From 6a05293f51c934595dc8e09868566a583c3a06e2 Mon Sep 17 00:00:00 2001 From: cpp-priyanshu Date: Sun, 1 Dec 2024 04:05:40 +0530 Subject: [PATCH 1/4] Add new round and behavior with API integration --- packages/packages.json | 8 +-- .../agents/learning_agent/aea-config.yaml | 17 +++++- .../services/learning_service/service.yaml | 54 ++++++++++++++++- .../valory/skills/learning_abci/behaviours.py | 60 ++++++++++++++++++- .../learning_abci/fsm_specification.yaml | 9 ++- .../valory/skills/learning_abci/models.py | 3 + .../valory/skills/learning_abci/payloads.py | 6 ++ .../valory/skills/learning_abci/rounds.py | 37 +++++++++++- .../valory/skills/learning_abci/skill.yaml | 24 ++++++-- .../fsm_specification.yaml | 7 ++- .../skills/learning_chained_abci/models.py | 6 +- .../skills/learning_chained_abci/skill.yaml | 20 ++++++- sample.env | 14 ++--- 13 files changed, 237 insertions(+), 28 deletions(-) diff --git a/packages/packages.json b/packages/packages.json index 702826f..ae0db8e 100644 --- a/packages/packages.json +++ b/packages/packages.json @@ -1,10 +1,10 @@ { "dev": { "contract/valory/erc20/0.1.0": "bafybeibyhuxozkkvsymqz45vxixr3w3bs4vsvxg2nsx5jlyi3f3hhn7ezi", - "skill/valory/learning_abci/0.1.0": "bafybeih5m372dqrdfy7w6iah4m5qfgf3j5t7ihsgorzyzhax5srm32wmim", - "skill/valory/learning_chained_abci/0.1.0": "bafybeihu6uvvdnfntgluhrbxqus5malsit36xqsyxv46wjqsmuodadarpm", - "agent/valory/learning_agent/0.1.0": "bafybeiatizepnj42umexk3p5rnop67cdshbgrflvnysaagm3t4xqo74kem", - "service/valory/learning_service/0.1.0": "bafybeig34lg3wztyj7ecsbyb6qj7ryf34gnpr2cuoz3akjvgdsh3pejboq" + "skill/valory/learning_abci/0.1.0": "bafybeieamdxwyp4khtzefhs6kuhebirxm6y4mnyotiha24f7dndj6tvdwe", + "skill/valory/learning_chained_abci/0.1.0": "bafybeiffws345wmtqwyyf7eoyhxkhfco72bwqshq4amxa2rweywaenjuqy", + "agent/valory/learning_agent/0.1.0": "bafybeibiu4oa7qt6nlzhcresl2la6ziphs3vhe7j77vkh5ov5vcwd46qia", + "service/valory/learning_service/0.1.0": "bafybeicae367qvvbe5ghztatfgbiyjxpky5onkbzgaoor3dt7xunkd5p6q" }, "third_party": { "protocol/open_aea/signing/1.0.0": "bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi", diff --git a/packages/valory/agents/learning_agent/aea-config.yaml b/packages/valory/agents/learning_agent/aea-config.yaml index dd0bbfc..c08fa23 100644 --- a/packages/valory/agents/learning_agent/aea-config.yaml +++ b/packages/valory/agents/learning_agent/aea-config.yaml @@ -32,8 +32,8 @@ protocols: skills: - valory/abstract_abci:0.1.0:bafybeidz54kvxhbdmpruzguuzzq7bjg4pekjb5amqobkxoy4oqknnobopu - valory/abstract_round_abci:0.1.0:bafybeiajjzuh6vf23crp55humonknirvv2f4s3dmdlfzch6tc5ow52pcgm -- valory/learning_abci:0.1.0:bafybeih5m372dqrdfy7w6iah4m5qfgf3j5t7ihsgorzyzhax5srm32wmim -- valory/learning_chained_abci:0.1.0:bafybeihu6uvvdnfntgluhrbxqus5malsit36xqsyxv46wjqsmuodadarpm +- valory/learning_abci:0.1.0:bafybeieamdxwyp4khtzefhs6kuhebirxm6y4mnyotiha24f7dndj6tvdwe +- valory/learning_chained_abci:0.1.0:bafybeiffws345wmtqwyyf7eoyhxkhfco72bwqshq4amxa2rweywaenjuqy - valory/registration_abci:0.1.0:bafybeiffipsowrqrkhjoexem7ern5ob4fabgif7wa6gtlszcoaop2e3oey - valory/reset_pause_abci:0.1.0:bafybeif4lgvbzsmzljesxbphycdv52ka7qnihyjrjpfaseclxadcmm6yiq - valory/termination_abci:0.1.0:bafybeiekkpo5qef5zaeagm3si6v45qxcojvtjqe4a5ceccvk4q7k3xi3bi @@ -219,3 +219,16 @@ models: response_type: dict retries: 5 url: https://api.coingecko.com/api/v3/simple/price + coingecko_pricehistorydata_specs: + args: + api_id: coingecko + headers: + Accept: application/json + method: GET + parameters: + vs_currency: usd + days: 1 + response_key: prices + response_type: list + retries: 5 + url: https://api.coingecko.com/api/v3/coins/autonolas/market_chart diff --git a/packages/valory/services/learning_service/service.yaml b/packages/valory/services/learning_service/service.yaml index c7d8bca..5c0fc4d 100644 --- a/packages/valory/services/learning_service/service.yaml +++ b/packages/valory/services/learning_service/service.yaml @@ -7,7 +7,7 @@ license: Apache-2.0 fingerprint: README.md: bafybeid42pdrf6qrohedylj4ijrss236ai6geqgf3he44huowiuf7pl464 fingerprint_ignore_patterns: [] -agent: valory/learning_agent:0.1.0:bafybeiatizepnj42umexk3p5rnop67cdshbgrflvnysaagm3t4xqo74kem +agent: valory/learning_agent:0.1.0:bafybeibiu4oa7qt6nlzhcresl2la6ziphs3vhe7j77vkh5ov5vcwd46qia number_of_agents: 4 deployment: agent: @@ -108,6 +108,19 @@ extra: response_type: dict retries: 5 url: https://api.coingecko.com/api/v3/simple/price + coingecko_pricehistorydata_specs: + args: + api_id: coingecko + headers: + Accept: application/json + method: GET + parameters: + vs_currency: usd + days: 1 + response_key: prices + response_type: list + retries: 5 + url: https://api.coingecko.com/api/v3/coins/autonolas/market_chart 1: models: benchmark_tool: @@ -169,6 +182,19 @@ extra: response_type: dict retries: 5 url: https://api.coingecko.com/api/v3/simple/price + coingecko_pricehistorydata_specs: + args: + api_id: coingecko + headers: + Accept: application/json + method: GET + parameters: + vs_currency: usd + days: 1 + response_key: prices + response_type: list + retries: 5 + url: https://api.coingecko.com/api/v3/coins/autonolas/market_chart 2: models: benchmark_tool: @@ -230,6 +256,19 @@ extra: response_type: dict retries: 5 url: https://api.coingecko.com/api/v3/simple/price + coingecko_pricehistorydata_specs: + args: + api_id: coingecko + headers: + Accept: application/json + method: GET + parameters: + vs_currency: usd + days: 1 + response_key: prices + response_type: list + retries: 5 + url: https://api.coingecko.com/api/v3/coins/autonolas/market_chart 3: models: benchmark_tool: @@ -291,6 +330,19 @@ extra: response_type: dict retries: 5 url: https://api.coingecko.com/api/v3/simple/price + coingecko_pricehistorydata_specs: + args: + api_id: coingecko + headers: + Accept: application/json + method: GET + parameters: + vs_currency: usd + days: 1 + response_key: prices + response_type: list + retries: 5 + url: https://api.coingecko.com/api/v3/coins/autonolas/market_chart --- public_id: valory/ledger:0.19.0 type: connection diff --git a/packages/valory/skills/learning_abci/behaviours.py b/packages/valory/skills/learning_abci/behaviours.py index e5fb9c7..eb8dbbb 100644 --- a/packages/valory/skills/learning_abci/behaviours.py +++ b/packages/valory/skills/learning_abci/behaviours.py @@ -46,15 +46,18 @@ CoingeckoSpecs, Params, SharedState, + Coingeckopricehistorydataspecs, ) from packages.valory.skills.learning_abci.payloads import ( DataPullPayload, DecisionMakingPayload, + EvaluationPayload, TxPreparationPayload, ) from packages.valory.skills.learning_abci.rounds import ( DataPullRound, DecisionMakingRound, + EvaluationRound, Event, LearningAbciApp, SynchronizedData, @@ -99,6 +102,11 @@ def local_state(self) -> SharedState: def coingecko_specs(self) -> CoingeckoSpecs: """Get the Coingecko api specs.""" return self.context.coingecko_specs + + @property + def coingecko_pricehistorydata_specs(self) -> Coingeckopricehistorydataspecs: + """Get the Coingecko api specs.""" + return self.context.coingecko_pricehistorydata_specs @property def metadata_filepath(self) -> str: @@ -278,7 +286,6 @@ def get_native_balance(self) -> Generator[None, None, Optional[float]]: return balance - class DecisionMakingBehaviour( LearningBaseBehaviour ): # pylint: disable=too-many-ancestors @@ -384,6 +391,56 @@ def get_price_from_ipfs(self) -> Generator[None, None, Optional[dict]]: self.context.logger.error(f"Got price from IPFS: {price}") return price +class EvaluationBehaviour(DataPullBehaviour,LearningBaseBehaviour): + """Behaviour to handle the evaluation of current vs historical prices.""" + + matching_round: Type[AbstractRound] = EvaluationRound + + def async_act(self) -> Generator: + """Perform the evaluation logic.""" + with self.context.benchmark_tool.measure(self.behaviour_id).local(): + # Fetch the current token price using the specified method + current_price = yield from self.get_token_price_specs() + + # Continue with existing logic + historical_data = yield from self.get_historical_price_data() + self.context.logger.error(f"Got data from ApiSpecs method: {historical_data}") + + if not historical_data: + return self.synchronized_data, Event.ERROR + + average_historical_price = sum(historical_data) / len(historical_data) + + if current_price > average_historical_price: + self.context.logger.info("Current price is higher than the average of last day.") + elif current_price < average_historical_price: + self.context.logger.info("Current price is lower than the average of last day.") + else: + self.context.logger.info("Current price is the same as the average of last day.") + + payload = EvaluationPayload( + sender=self.context.agent_address, + historical_prices=historical_data + ) + + # Send the payload to all agents and mark the behaviour as done + 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_historical_price_data(self) -> Generator[None, None, list[float]]: + """Fetch historical price data from the Coingecko API.""" + specs = self.coingecko_pricehistorydata_specs.get_spec() + response = yield from self.get_http_response(**specs) + historical_data = self.coingecko_pricehistorydata_specs.process_response(response) + + prices = [price[1] for price in historical_data] + + return prices # Assuming prices is a list of floats + + class TxPreparationBehaviour( LearningBaseBehaviour @@ -659,5 +716,6 @@ class LearningRoundBehaviour(AbstractRoundBehaviour): behaviours: Set[Type[BaseBehaviour]] = [ # type: ignore DataPullBehaviour, DecisionMakingBehaviour, + EvaluationBehaviour, TxPreparationBehaviour, ] diff --git a/packages/valory/skills/learning_abci/fsm_specification.yaml b/packages/valory/skills/learning_abci/fsm_specification.yaml index 3538353..00a95de 100644 --- a/packages/valory/skills/learning_abci/fsm_specification.yaml +++ b/packages/valory/skills/learning_abci/fsm_specification.yaml @@ -14,6 +14,7 @@ start_states: states: - DataPullRound - DecisionMakingRound +- EvaluationRound - FinishedDecisionMakingRound - FinishedTxPreparationRound - TxPreparationRound @@ -25,7 +26,11 @@ transition_func: (DecisionMakingRound, ERROR): FinishedDecisionMakingRound (DecisionMakingRound, NO_MAJORITY): DecisionMakingRound (DecisionMakingRound, ROUND_TIMEOUT): DecisionMakingRound - (DecisionMakingRound, TRANSACT): TxPreparationRound + (DecisionMakingRound, TRANSACT): EvaluationRound + (EvaluationRound, DONE): TxPreparationRound + (EvaluationRound, ERROR): FinishedDecisionMakingRound + (EvaluationRound, NO_MAJORITY): EvaluationRound + (EvaluationRound, ROUND_TIMEOUT): EvaluationRound (TxPreparationRound, DONE): FinishedTxPreparationRound (TxPreparationRound, NO_MAJORITY): TxPreparationRound - (TxPreparationRound, ROUND_TIMEOUT): TxPreparationRound + (TxPreparationRound, ROUND_TIMEOUT): TxPreparationRound \ No newline at end of file diff --git a/packages/valory/skills/learning_abci/models.py b/packages/valory/skills/learning_abci/models.py index c9e1aa5..dff0343 100644 --- a/packages/valory/skills/learning_abci/models.py +++ b/packages/valory/skills/learning_abci/models.py @@ -64,3 +64,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class CoingeckoSpecs(ApiSpecs): """A model that wraps ApiSpecs for Coingecko API.""" + +class Coingeckopricehistorydataspecs(ApiSpecs): + """A model that wraps ApiSpecs for Coingecko API.""" diff --git a/packages/valory/skills/learning_abci/payloads.py b/packages/valory/skills/learning_abci/payloads.py index 68787e6..c22093a 100644 --- a/packages/valory/skills/learning_abci/payloads.py +++ b/packages/valory/skills/learning_abci/payloads.py @@ -41,6 +41,12 @@ class DecisionMakingPayload(BaseTxPayload): event: str +@dataclass(frozen=True) +class EvaluationPayload(BaseTxPayload): + """Payload for the EvaluationRound.""" + + historical_prices: list[float] + @dataclass(frozen=True) class TxPreparationPayload(BaseTxPayload): diff --git a/packages/valory/skills/learning_abci/rounds.py b/packages/valory/skills/learning_abci/rounds.py index 9a9c626..4f97e9f 100644 --- a/packages/valory/skills/learning_abci/rounds.py +++ b/packages/valory/skills/learning_abci/rounds.py @@ -37,6 +37,7 @@ from packages.valory.skills.learning_abci.payloads import ( DataPullPayload, DecisionMakingPayload, + EvaluationPayload, TxPreparationPayload, ) @@ -152,6 +153,34 @@ def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: # Event.DONE, Event.ERROR, Event.TRANSACT, Event.ROUND_TIMEOUT # this needs to be referenced for static checkers +class EvaluationRound(CollectSameUntilThresholdRound): + """ + EvaluationRound is designed to compare current and historical prices, an essential step in scenarios + where decisions are based on market trends. This round involves agents reaching a consensus on the + current price and comparing it to previously synchronized historical prices to assess market conditions. + """ + + payload_class = EvaluationPayload + synchronized_data_class = SynchronizedData + done_event = Event.DONE + error_event = Event.ERROR + no_majority_event = Event.NO_MAJORITY + + def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: + """ + This method is called at the end of the round to finalize the operations based on the data collected. + Since this is a simplified example, it automatically concludes the round by returning the synchronized + data along with a 'DONE' event indicating the round has completed successfully without errors or + the inability to reach a majority. + + Returns: + Optional[Tuple[BaseSynchronizedData, Event]]: Returns a tuple containing the current state of + synchronized data along with the 'DONE' event to signal the successful end of the round. + """ + + return self.synchronized_data, Event.DONE + + class TxPreparationRound(CollectSameUntilThresholdRound): """TxPreparationRound""" @@ -195,7 +224,13 @@ class LearningAbciApp(AbciApp[Event]): Event.ROUND_TIMEOUT: DecisionMakingRound, Event.DONE: FinishedDecisionMakingRound, Event.ERROR: FinishedDecisionMakingRound, - Event.TRANSACT: TxPreparationRound, + Event.TRANSACT: EvaluationRound, + }, + EvaluationRound: { + Event.NO_MAJORITY: EvaluationRound, + Event.ROUND_TIMEOUT: EvaluationRound, + Event.DONE: TxPreparationRound, + Event.ERROR: FinishedDecisionMakingRound, }, TxPreparationRound: { Event.NO_MAJORITY: TxPreparationRound, diff --git a/packages/valory/skills/learning_abci/skill.yaml b/packages/valory/skills/learning_abci/skill.yaml index b34eadf..a087e97 100644 --- a/packages/valory/skills/learning_abci/skill.yaml +++ b/packages/valory/skills/learning_abci/skill.yaml @@ -7,13 +7,13 @@ license: Apache-2.0 aea_version: '>=1.0.0, <2.0.0' fingerprint: __init__.py: bafybeiho3lkochqpmes4f235chq26oggmwnol3vjuvhosleoubbjirbwaq - behaviours.py: bafybeiaiy6sh7aqo4zzghnejv55vs43vqtpaipj5cpabx32qdjrqleeeie + behaviours.py: bafybeicfmrd52md2xjyrrgzisv2nqm5fzwo3jggqupopam4epskmvzgouq dialogues.py: bafybeifqjbumctlffx2xvpga2kcenezhe47qhksvgmaylyp5ypwqgfar5u - fsm_specification.yaml: bafybeigbbydxuqephdpatb3fp3sxnvr77bfvvo5hwjimxfpgyl32wupe64 + fsm_specification.yaml: bafybeibjeq2tku4bwsh64tm6ud4pz2yt32doffsrt23fxrt6j3bgtz6axm handlers.py: bafybeigjadr4thz6hfpfx5abezbwnqhbxmachf4efasrn4z2vqhsqgnyvi - models.py: bafybeicreffhurci7jzpwvxnlo5z3a2j3vcfgkopg2gtwwxfrncbzk77ra - payloads.py: bafybeidc6qqnfvd7qovjatt2i2kbga7pj6epdghlzqxdhzx6b6j6p7ubvm - rounds.py: bafybeibcxdou2opzsof4fcnaijfdgzpaaggmucyolhegns3k4zpzvuom2i + models.py: bafybeic762skwe2zv4awqxhl5rnlnv2vxsw5vefwg5neq6xvbkzv5ethwi + payloads.py: bafybeihpjgvwhyf6nzi2orijnqihxlmqcbfnnce7o5cm3sh7gwvd6iaeuu + rounds.py: bafybeiabtsjl26sucwsn5k3z6pxhob42qataxj5hj7o3tiqbeznm2hzxxu fingerprint_ignore_patterns: [] connections: [] contracts: @@ -147,6 +147,20 @@ models: retries: 5 url: https://api.coingecko.com/api/v3/simple/price class_name: CoingeckoSpecs + coingecko_pricehistorydata_specs: + args: + api_id: coingecko + headers: + Accept: application/json + method: GET + parameters: + vs_currency: usd + days: 1 + response_key: prices + response_type: list + retries: 5 + url: https://api.coingecko.com/api/v3/coins/autonolas/market_chart + class_name: Coingeckopricehistorydataspecs requests: args: {} class_name: Requests diff --git a/packages/valory/skills/learning_chained_abci/fsm_specification.yaml b/packages/valory/skills/learning_chained_abci/fsm_specification.yaml index 6f464f9..25edbe5 100644 --- a/packages/valory/skills/learning_chained_abci/fsm_specification.yaml +++ b/packages/valory/skills/learning_chained_abci/fsm_specification.yaml @@ -29,6 +29,7 @@ states: - CheckTransactionHistoryRound - CollectSignatureRound - DecisionMakingRound +- EvaluationRound - FinalizationRound - RandomnessTransactionSubmissionRound - RegistrationRound @@ -64,7 +65,11 @@ transition_func: (DecisionMakingRound, ERROR): ResetAndPauseRound (DecisionMakingRound, NO_MAJORITY): DecisionMakingRound (DecisionMakingRound, ROUND_TIMEOUT): DecisionMakingRound - (DecisionMakingRound, TRANSACT): TxPreparationRound + (DecisionMakingRound, TRANSACT): EvaluationRound + (EvaluationRound, DONE): TxPreparationRound + (EvaluationRound, ERROR): EvaluationRound + (EvaluationRound, NO_MAJORITY): EvaluationRound + (EvaluationRound, ROUND_TIMEOUT): EvaluationRound (FinalizationRound, CHECK_HISTORY): CheckTransactionHistoryRound (FinalizationRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound (FinalizationRound, DONE): ValidateTransactionRound diff --git a/packages/valory/skills/learning_chained_abci/models.py b/packages/valory/skills/learning_chained_abci/models.py index 6adbd80..adffcd6 100644 --- a/packages/valory/skills/learning_chained_abci/models.py +++ b/packages/valory/skills/learning_chained_abci/models.py @@ -27,7 +27,7 @@ RandomnessApi as BaseRandomnessApi, ) from packages.valory.skills.learning_abci.models import ( - CoingeckoSpecs as BaseCoingeckoSpecs, + CoingeckoSpecs,Coingeckopricehistorydataspecs as BaseCoingeckoSpecs, ) from packages.valory.skills.learning_abci.models import Params as LearningParams from packages.valory.skills.learning_abci.models import SharedState as BaseSharedState @@ -79,3 +79,7 @@ class Params( # pylint: disable=too-many-ancestors class CoingeckoSpecs(BaseCoingeckoSpecs): """A model that wraps ApiSpecs for Coingecko API.""" + +class Coingeckopricehistorydataspecs(BaseCoingeckoSpecs): + """A model that wraps ApiSpecs for Coingecko API.""" + diff --git a/packages/valory/skills/learning_chained_abci/skill.yaml b/packages/valory/skills/learning_chained_abci/skill.yaml index cdda1f4..7885c6d 100644 --- a/packages/valory/skills/learning_chained_abci/skill.yaml +++ b/packages/valory/skills/learning_chained_abci/skill.yaml @@ -10,9 +10,9 @@ fingerprint: behaviours.py: bafybeiagipms5gfebqysx5sl4dhydppceqv4aga64ibqgygqczbh4imyxu composition.py: bafybeib64i3h7vmimsjflc37j4s5feipiar7hib5ixdwbadphjezq5z4cu dialogues.py: bafybeiakqfqcpg7yrxt4bsyernhy5p77tci4qhmgqqjqi3ttx7zk6sklca - fsm_specification.yaml: bafybeibhguliurgppqgues6zhy3e3pioacgapilid7j26u4pmfsump5ape + fsm_specification.yaml: bafybeiftkgmrw774gc63wake2px5htcidlpuj47m36i6mnqekcwi2ncv44 handlers.py: bafybeicru4lanvektcppxpecul4zwjfuaxseopxtsxrfzmbfaz5qk4m67q - models.py: bafybeico4qysu652lznxwxfamsu43d7llstplca5eqcwnmwg66fxmzt4qe + models.py: bafybeigeccljqc7bmrrdiodi4zxehigb4tnpjuzlxavsqnlutwsmv25wvq fingerprint_ignore_patterns: [] connections: [] contracts: [] @@ -22,7 +22,7 @@ skills: - valory/registration_abci:0.1.0:bafybeiffipsowrqrkhjoexem7ern5ob4fabgif7wa6gtlszcoaop2e3oey - valory/reset_pause_abci:0.1.0:bafybeif4lgvbzsmzljesxbphycdv52ka7qnihyjrjpfaseclxadcmm6yiq - valory/termination_abci:0.1.0:bafybeiekkpo5qef5zaeagm3si6v45qxcojvtjqe4a5ceccvk4q7k3xi3bi -- valory/learning_abci:0.1.0:bafybeih5m372dqrdfy7w6iah4m5qfgf3j5t7ihsgorzyzhax5srm32wmim +- valory/learning_abci:0.1.0:bafybeieamdxwyp4khtzefhs6kuhebirxm6y4mnyotiha24f7dndj6tvdwe - valory/transaction_settlement_abci:0.1.0:bafybeielv6eivt2z6nforq43xewl2vmpfwpdu2s2vfogobziljnwsclmlm behaviours: main: @@ -155,6 +155,20 @@ models: retries: 5 url: https://api.coingecko.com/api/v3/simple/price class_name: CoingeckoSpecs + coingecko_pricehistorydata_specs: + args: + api_id: coingecko + headers: + Accept: application/json + method: GET + parameters: + vs_currency: usd + days: 1 + response_key: prices + response_type: list + retries: 5 + url: https://api.coingecko.com/api/v3/coins/autonolas/market_chart + class_name: Coingeckopricehistorydataspecs randomness_api: args: api_id: cloudflare diff --git a/sample.env b/sample.env index 8527f56..a9b0101 100644 --- a/sample.env +++ b/sample.env @@ -1,10 +1,10 @@ -ALL_PARTICIPANTS='["","address_1","address_2","address_3"]' -SAFE_CONTRACT_ADDRESS= -SAFE_CONTRACT_ADDRESS_SINGLE= -GNOSIS_LEDGER_RPC= -COINGECKO_API_KEY= -TRANSFER_TARGET_ADDRESS= +ALL_PARTICIPANTS='["0x8B0f9b4b40cc2E9685FCf88957Ca39104c8cd721"]' +SAFE_CONTRACT_ADDRESS=0xFCE595554cB55c7FAbc5Ab359F398B37DE59f542 +SAFE_CONTRACT_ADDRESS_SINGLE=0x11B9506EBCc04EDbdeb42d01b9e3A0CBA0107ffd +GNOSIS_LEDGER_RPC=https://virtual.gnosis.rpc.tenderly.co/204ddd51-1d70-44a7-bb79-63d7e72f9342 +COINGECKO_API_KEY=CG-5Nn7yAS9qAvHZxKtGqfjQHri +TRANSFER_TARGET_ADDRESS=0xEE93B2F35C8Ef5Bf0395286Ea887181970916243 ON_CHAIN_SERVICE_ID=1 RESET_PAUSE_DURATION=10 -RESET_TENDERMINT_AFTER=10 +RESET_TENDERMINT_AFTER=10 \ No newline at end of file From a35a99405e2ce80d3ad4a71ce30028981a595418 Mon Sep 17 00:00:00 2001 From: cpp-priyanshu Date: Sun, 1 Dec 2024 07:39:11 +0530 Subject: [PATCH 2/4] Add functionality to store and retrieve data on IPFS --- packages/packages.json | 8 +- .../agents/learning_agent/aea-config.yaml | 4 +- .../services/learning_service/service.yaml | 2 +- .../valory/skills/learning_abci/behaviours.py | 129 ++++++++++++------ .../valory/skills/learning_abci/payloads.py | 6 +- .../valory/skills/learning_abci/rounds.py | 27 +++- .../valory/skills/learning_abci/skill.yaml | 6 +- .../skills/learning_chained_abci/skill.yaml | 2 +- 8 files changed, 131 insertions(+), 53 deletions(-) diff --git a/packages/packages.json b/packages/packages.json index ae0db8e..4ac60b7 100644 --- a/packages/packages.json +++ b/packages/packages.json @@ -1,10 +1,10 @@ { "dev": { "contract/valory/erc20/0.1.0": "bafybeibyhuxozkkvsymqz45vxixr3w3bs4vsvxg2nsx5jlyi3f3hhn7ezi", - "skill/valory/learning_abci/0.1.0": "bafybeieamdxwyp4khtzefhs6kuhebirxm6y4mnyotiha24f7dndj6tvdwe", - "skill/valory/learning_chained_abci/0.1.0": "bafybeiffws345wmtqwyyf7eoyhxkhfco72bwqshq4amxa2rweywaenjuqy", - "agent/valory/learning_agent/0.1.0": "bafybeibiu4oa7qt6nlzhcresl2la6ziphs3vhe7j77vkh5ov5vcwd46qia", - "service/valory/learning_service/0.1.0": "bafybeicae367qvvbe5ghztatfgbiyjxpky5onkbzgaoor3dt7xunkd5p6q" + "skill/valory/learning_abci/0.1.0": "bafybeicq3jpctj6w5v4rfstjrb7lslynla5jox75gg5rpe4rjpxmnqmw2i", + "skill/valory/learning_chained_abci/0.1.0": "bafybeigke7r5duhzk4lsetgrbnt6clqfe43b4utrzzluyhdvqzfmhnnwb4", + "agent/valory/learning_agent/0.1.0": "bafybeifyolb7xpq44hosv7n3u2h5yih236san6qtakspihsmu4ig4jbsbm", + "service/valory/learning_service/0.1.0": "bafybeiarfnfu2tsl2bsatrpg3z7v7actqm2uvxgu65ix3ab4nstbmfumlq" }, "third_party": { "protocol/open_aea/signing/1.0.0": "bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi", diff --git a/packages/valory/agents/learning_agent/aea-config.yaml b/packages/valory/agents/learning_agent/aea-config.yaml index c08fa23..0b3ff69 100644 --- a/packages/valory/agents/learning_agent/aea-config.yaml +++ b/packages/valory/agents/learning_agent/aea-config.yaml @@ -32,8 +32,8 @@ protocols: skills: - valory/abstract_abci:0.1.0:bafybeidz54kvxhbdmpruzguuzzq7bjg4pekjb5amqobkxoy4oqknnobopu - valory/abstract_round_abci:0.1.0:bafybeiajjzuh6vf23crp55humonknirvv2f4s3dmdlfzch6tc5ow52pcgm -- valory/learning_abci:0.1.0:bafybeieamdxwyp4khtzefhs6kuhebirxm6y4mnyotiha24f7dndj6tvdwe -- valory/learning_chained_abci:0.1.0:bafybeiffws345wmtqwyyf7eoyhxkhfco72bwqshq4amxa2rweywaenjuqy +- valory/learning_abci:0.1.0:bafybeicq3jpctj6w5v4rfstjrb7lslynla5jox75gg5rpe4rjpxmnqmw2i +- valory/learning_chained_abci:0.1.0:bafybeigke7r5duhzk4lsetgrbnt6clqfe43b4utrzzluyhdvqzfmhnnwb4 - valory/registration_abci:0.1.0:bafybeiffipsowrqrkhjoexem7ern5ob4fabgif7wa6gtlszcoaop2e3oey - valory/reset_pause_abci:0.1.0:bafybeif4lgvbzsmzljesxbphycdv52ka7qnihyjrjpfaseclxadcmm6yiq - valory/termination_abci:0.1.0:bafybeiekkpo5qef5zaeagm3si6v45qxcojvtjqe4a5ceccvk4q7k3xi3bi diff --git a/packages/valory/services/learning_service/service.yaml b/packages/valory/services/learning_service/service.yaml index 5c0fc4d..eacc669 100644 --- a/packages/valory/services/learning_service/service.yaml +++ b/packages/valory/services/learning_service/service.yaml @@ -7,7 +7,7 @@ license: Apache-2.0 fingerprint: README.md: bafybeid42pdrf6qrohedylj4ijrss236ai6geqgf3he44huowiuf7pl464 fingerprint_ignore_patterns: [] -agent: valory/learning_agent:0.1.0:bafybeibiu4oa7qt6nlzhcresl2la6ziphs3vhe7j77vkh5ov5vcwd46qia +agent: valory/learning_agent:0.1.0:bafybeifyolb7xpq44hosv7n3u2h5yih236san6qtakspihsmu4ig4jbsbm number_of_agents: 4 deployment: agent: diff --git a/packages/valory/skills/learning_abci/behaviours.py b/packages/valory/skills/learning_abci/behaviours.py index eb8dbbb..e9f6ca8 100644 --- a/packages/valory/skills/learning_abci/behaviours.py +++ b/packages/valory/skills/learning_abci/behaviours.py @@ -393,52 +393,96 @@ def get_price_from_ipfs(self) -> Generator[None, None, Optional[dict]]: class EvaluationBehaviour(DataPullBehaviour,LearningBaseBehaviour): """Behaviour to handle the evaluation of current vs historical prices.""" - + matching_round: Type[AbstractRound] = EvaluationRound - + def async_act(self) -> Generator: """Perform the evaluation logic.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - # Fetch the current token price using the specified method - current_price = yield from self.get_token_price_specs() - - # Continue with existing logic - historical_data = yield from self.get_historical_price_data() - self.context.logger.error(f"Got data from ApiSpecs method: {historical_data}") - - if not historical_data: - return self.synchronized_data, Event.ERROR + try: + with self.context.benchmark_tool.measure(self.behaviour_id).local(): + self.context.logger.debug("Starting EvaluationBehaviour logic") + + current_price = yield from self.get_token_price_specs() + self.context.logger.info(f"Current price fetched: {current_price}") + + historical_data = yield from self.get_historical_price_data() + self.context.logger.info(f"Historical data fetched: {historical_data}") + + if not historical_data: + self.context.logger.error("No historical data available.") + return self.synchronized_data, Event.ERROR + + average_historical_price = sum(historical_data) / len(historical_data) + self.context.logger.info(f"Average historical price computed: {average_historical_price}") + + comparison_result = self.compare_prices(current_price, average_historical_price) + self.context.logger.info(f"Price comparison result: {comparison_result}") + + historical_data_ipfs_hash = yield from self.send_historical_data_to_ipfs(historical_data) + self.context.logger.info(f"Historical data IPFS hash: {type(historical_data_ipfs_hash)}") + + payload = EvaluationPayload( + sender=self.context.agent_address, + historical_data_ipfshash=historical_data_ipfs_hash, + comparison_data=comparison_result, + ) + self.context.logger.info("EvaluationPayload prepared and being sent.") + + 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.context.logger.info("EvaluationBehaviour completed.") + + self.set_done() + + except Exception as e: + self.context.logger.error(f"Error in EvaluationBehaviour: {str(e)}") + raise - average_historical_price = sum(historical_data) / len(historical_data) - - if current_price > average_historical_price: - self.context.logger.info("Current price is higher than the average of last day.") - elif current_price < average_historical_price: - self.context.logger.info("Current price is lower than the average of last day.") - else: - self.context.logger.info("Current price is the same as the average of last day.") - - payload = EvaluationPayload( - sender=self.context.agent_address, - historical_prices=historical_data - ) - - # Send the payload to all agents and mark the behaviour as done - 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 compare_prices(self, current, historical_average): + """Log comparison of current price to historical average.""" + if current > historical_average: + self.context.logger.info("Current price is higher than the average of last day.") + elif current < historical_average: + self.context.logger.info("Current price is lower than the average of last day.") + else: + self.context.logger.info("Current price is the same as the average of last day.") + return current > historical_average def get_historical_price_data(self) -> Generator[None, None, list[float]]: """Fetch historical price data from the Coingecko API.""" - specs = self.coingecko_pricehistorydata_specs.get_spec() - response = yield from self.get_http_response(**specs) - historical_data = self.coingecko_pricehistorydata_specs.process_response(response) + try: + self.context.logger.debug("Fetching historical price data.") + specs = self.coingecko_pricehistorydata_specs.get_spec() + response = yield from self.get_http_response(**specs) + if response.status_code != HTTP_OK: + self.context.logger.error(f"Failed to fetch historical data: {response.body}") + return [] + + historical_data = self.coingecko_pricehistorydata_specs.process_response(response) + if historical_data is None: + self.context.logger.error("No historical data returned from processing.") + return [] + + prices = [price[1] for price in historical_data] + self.context.logger.info(f"Historical prices fetched: {prices}") + return prices # Assuming prices is a list of floats + except Exception as e: + self.context.logger.error(f"Exception in fetching historical data: {str(e)}") + return [] + + + def send_historical_data_to_ipfs(self, historical_data) -> Generator[None, None, Optional[str]]: + """Store the historical price data in IPFS.""" + data = {"historical_prices": historical_data} + historical_data_ipfs_hash = yield from self.send_to_ipfs( + filename=self.metadata_filepath, obj=data, filetype=SupportedFiletype.JSON + ) + self.context.logger.info( + f"Historical price data stored in IPFS: https://gateway.autonolas.tech/ipfs/{historical_data_ipfs_hash}" + ) + return historical_data_ipfs_hash - prices = [price[1] for price in historical_data] - - return prices # Assuming prices is a list of floats @@ -467,6 +511,15 @@ def async_act(self) -> Generator: yield from self.wait_until_round_end() self.set_done() + + def get_historical_data_from_ipfs(self) -> Generator[None, None, Optional[dict]]: + """Load the historical data from IPFS""" + ipfs_hash = self.synchronized_data.historical_data_ipfshash + data = yield from self.get_from_ipfs( + ipfs_hash=ipfs_hash, filetype=SupportedFiletype.JSON + ) + self.context.logger.error(f"Got historical data from IPFS: {data}") + return data def get_tx_hash(self) -> Generator[None, None, Optional[str]]: """Get the transaction hash""" diff --git a/packages/valory/skills/learning_abci/payloads.py b/packages/valory/skills/learning_abci/payloads.py index c22093a..a5bda13 100644 --- a/packages/valory/skills/learning_abci/payloads.py +++ b/packages/valory/skills/learning_abci/payloads.py @@ -41,12 +41,12 @@ class DecisionMakingPayload(BaseTxPayload): event: str -@dataclass(frozen=True) + class EvaluationPayload(BaseTxPayload): """Payload for the EvaluationRound.""" - - historical_prices: list[float] + historical_data_ipfshash:Optional[str] + comparison_data:Optional[bool] @dataclass(frozen=True) class TxPreparationPayload(BaseTxPayload): diff --git a/packages/valory/skills/learning_abci/rounds.py b/packages/valory/skills/learning_abci/rounds.py index 4f97e9f..b402324 100644 --- a/packages/valory/skills/learning_abci/rounds.py +++ b/packages/valory/skills/learning_abci/rounds.py @@ -88,6 +88,22 @@ def erc20_balance(self) -> Optional[float]: def participant_to_data_round(self) -> DeserializedCollection: """Agent to payload mapping for the DataPullRound.""" return self._get_deserialized("participant_to_data_round") + + @property + def historical_data_ipfshash(self) -> Optional[str]: + """Get the IPFS hash of historical data.""" + return self.db.get("historical_data_ipfshash", None) + + @property + def comparison_data(self) -> Optional[bool]: + """Get the comparison result of current vs. historical prices.""" + return self.db.get("comparison_data", None) + + @property + def participant_to_evaluation_round(self) -> DeserializedCollection: + """Agent to payload mapping for the DataPullRound.""" + return self._get_deserialized("participant_to_evaluation_round") + @property def most_voted_tx_hash(self) -> Optional[float]: @@ -166,6 +182,15 @@ class EvaluationRound(CollectSameUntilThresholdRound): error_event = Event.ERROR no_majority_event = Event.NO_MAJORITY + # Adjust the collection key to use the appropriate collection for this round + collection_key = get_name(SynchronizedData.participant_to_evaluation_round) # Adjusted + + # Selection key should map directly to the payload data correctly + selection_key = ( + get_name(SynchronizedData.historical_data_ipfshash), + get_name(SynchronizedData.comparison_data), + ) + def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: """ This method is called at the end of the round to finalize the operations based on the data collected. @@ -177,7 +202,7 @@ def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: Optional[Tuple[BaseSynchronizedData, Event]]: Returns a tuple containing the current state of synchronized data along with the 'DONE' event to signal the successful end of the round. """ - + print("self.synchronized_data",self.synchronized_data) return self.synchronized_data, Event.DONE diff --git a/packages/valory/skills/learning_abci/skill.yaml b/packages/valory/skills/learning_abci/skill.yaml index a087e97..f1c9696 100644 --- a/packages/valory/skills/learning_abci/skill.yaml +++ b/packages/valory/skills/learning_abci/skill.yaml @@ -7,13 +7,13 @@ license: Apache-2.0 aea_version: '>=1.0.0, <2.0.0' fingerprint: __init__.py: bafybeiho3lkochqpmes4f235chq26oggmwnol3vjuvhosleoubbjirbwaq - behaviours.py: bafybeicfmrd52md2xjyrrgzisv2nqm5fzwo3jggqupopam4epskmvzgouq + behaviours.py: bafybeiawutvwbbp6i6nezl7455plvvikc522a6oezd4voe7cjcxq5osuty dialogues.py: bafybeifqjbumctlffx2xvpga2kcenezhe47qhksvgmaylyp5ypwqgfar5u fsm_specification.yaml: bafybeibjeq2tku4bwsh64tm6ud4pz2yt32doffsrt23fxrt6j3bgtz6axm handlers.py: bafybeigjadr4thz6hfpfx5abezbwnqhbxmachf4efasrn4z2vqhsqgnyvi models.py: bafybeic762skwe2zv4awqxhl5rnlnv2vxsw5vefwg5neq6xvbkzv5ethwi - payloads.py: bafybeihpjgvwhyf6nzi2orijnqihxlmqcbfnnce7o5cm3sh7gwvd6iaeuu - rounds.py: bafybeiabtsjl26sucwsn5k3z6pxhob42qataxj5hj7o3tiqbeznm2hzxxu + payloads.py: bafybeighb7a6ye35t64ufuwu6k5zjamgbxbvqla2myvkngcuofid4y43cu + rounds.py: bafybeihl2ignqtmcg2ppyw6pjxtms52zryjaz2uprzxy42dzamuhmocesm fingerprint_ignore_patterns: [] connections: [] contracts: diff --git a/packages/valory/skills/learning_chained_abci/skill.yaml b/packages/valory/skills/learning_chained_abci/skill.yaml index 7885c6d..103c66c 100644 --- a/packages/valory/skills/learning_chained_abci/skill.yaml +++ b/packages/valory/skills/learning_chained_abci/skill.yaml @@ -22,7 +22,7 @@ skills: - valory/registration_abci:0.1.0:bafybeiffipsowrqrkhjoexem7ern5ob4fabgif7wa6gtlszcoaop2e3oey - valory/reset_pause_abci:0.1.0:bafybeif4lgvbzsmzljesxbphycdv52ka7qnihyjrjpfaseclxadcmm6yiq - valory/termination_abci:0.1.0:bafybeiekkpo5qef5zaeagm3si6v45qxcojvtjqe4a5ceccvk4q7k3xi3bi -- valory/learning_abci:0.1.0:bafybeieamdxwyp4khtzefhs6kuhebirxm6y4mnyotiha24f7dndj6tvdwe +- valory/learning_abci:0.1.0:bafybeicq3jpctj6w5v4rfstjrb7lslynla5jox75gg5rpe4rjpxmnqmw2i - valory/transaction_settlement_abci:0.1.0:bafybeielv6eivt2z6nforq43xewl2vmpfwpdu2s2vfogobziljnwsclmlm behaviours: main: From b55cdcef9bbec622ecc1fcec324b5e7464b4c4fa Mon Sep 17 00:00:00 2001 From: cpp-priyanshu Date: Sun, 1 Dec 2024 15:11:23 +0530 Subject: [PATCH 3/4] Update IPFS data retrieval to ensure proper data retrieval --- packages/packages.json | 8 +++---- .../agents/learning_agent/aea-config.yaml | 4 ++-- .../services/learning_service/service.yaml | 2 +- .../valory/skills/learning_abci/behaviours.py | 14 ++++------- .../valory/skills/learning_abci/payloads.py | 11 +++++---- .../valory/skills/learning_abci/rounds.py | 23 ++++--------------- .../valory/skills/learning_abci/skill.yaml | 6 ++--- .../skills/learning_chained_abci/skill.yaml | 2 +- 8 files changed, 26 insertions(+), 44 deletions(-) diff --git a/packages/packages.json b/packages/packages.json index 4ac60b7..4e85789 100644 --- a/packages/packages.json +++ b/packages/packages.json @@ -1,10 +1,10 @@ { "dev": { "contract/valory/erc20/0.1.0": "bafybeibyhuxozkkvsymqz45vxixr3w3bs4vsvxg2nsx5jlyi3f3hhn7ezi", - "skill/valory/learning_abci/0.1.0": "bafybeicq3jpctj6w5v4rfstjrb7lslynla5jox75gg5rpe4rjpxmnqmw2i", - "skill/valory/learning_chained_abci/0.1.0": "bafybeigke7r5duhzk4lsetgrbnt6clqfe43b4utrzzluyhdvqzfmhnnwb4", - "agent/valory/learning_agent/0.1.0": "bafybeifyolb7xpq44hosv7n3u2h5yih236san6qtakspihsmu4ig4jbsbm", - "service/valory/learning_service/0.1.0": "bafybeiarfnfu2tsl2bsatrpg3z7v7actqm2uvxgu65ix3ab4nstbmfumlq" + "skill/valory/learning_abci/0.1.0": "bafybeia6d5djkyb33iptxbb43mijhgndeyu2jhdbfekzm36y24pyel456y", + "skill/valory/learning_chained_abci/0.1.0": "bafybeibkwi3desmzj3do7czphgrwyckon56j7t243kvplo2kazuyg3bbyu", + "agent/valory/learning_agent/0.1.0": "bafybeigns24jm6jc6637f56jdppshdqoiawm6ua3seuuzx5cfgchtbfl4q", + "service/valory/learning_service/0.1.0": "bafybeiaw5ydomwrtf4e5uohptikuj5xvu37c26tmhslghov4cvlxao65fu" }, "third_party": { "protocol/open_aea/signing/1.0.0": "bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi", diff --git a/packages/valory/agents/learning_agent/aea-config.yaml b/packages/valory/agents/learning_agent/aea-config.yaml index 0b3ff69..adc48b6 100644 --- a/packages/valory/agents/learning_agent/aea-config.yaml +++ b/packages/valory/agents/learning_agent/aea-config.yaml @@ -32,8 +32,8 @@ protocols: skills: - valory/abstract_abci:0.1.0:bafybeidz54kvxhbdmpruzguuzzq7bjg4pekjb5amqobkxoy4oqknnobopu - valory/abstract_round_abci:0.1.0:bafybeiajjzuh6vf23crp55humonknirvv2f4s3dmdlfzch6tc5ow52pcgm -- valory/learning_abci:0.1.0:bafybeicq3jpctj6w5v4rfstjrb7lslynla5jox75gg5rpe4rjpxmnqmw2i -- valory/learning_chained_abci:0.1.0:bafybeigke7r5duhzk4lsetgrbnt6clqfe43b4utrzzluyhdvqzfmhnnwb4 +- valory/learning_abci:0.1.0:bafybeia6d5djkyb33iptxbb43mijhgndeyu2jhdbfekzm36y24pyel456y +- valory/learning_chained_abci:0.1.0:bafybeibkwi3desmzj3do7czphgrwyckon56j7t243kvplo2kazuyg3bbyu - valory/registration_abci:0.1.0:bafybeiffipsowrqrkhjoexem7ern5ob4fabgif7wa6gtlszcoaop2e3oey - valory/reset_pause_abci:0.1.0:bafybeif4lgvbzsmzljesxbphycdv52ka7qnihyjrjpfaseclxadcmm6yiq - valory/termination_abci:0.1.0:bafybeiekkpo5qef5zaeagm3si6v45qxcojvtjqe4a5ceccvk4q7k3xi3bi diff --git a/packages/valory/services/learning_service/service.yaml b/packages/valory/services/learning_service/service.yaml index eacc669..ef8c458 100644 --- a/packages/valory/services/learning_service/service.yaml +++ b/packages/valory/services/learning_service/service.yaml @@ -7,7 +7,7 @@ license: Apache-2.0 fingerprint: README.md: bafybeid42pdrf6qrohedylj4ijrss236ai6geqgf3he44huowiuf7pl464 fingerprint_ignore_patterns: [] -agent: valory/learning_agent:0.1.0:bafybeifyolb7xpq44hosv7n3u2h5yih236san6qtakspihsmu4ig4jbsbm +agent: valory/learning_agent:0.1.0:bafybeigns24jm6jc6637f56jdppshdqoiawm6ua3seuuzx5cfgchtbfl4q number_of_agents: 4 deployment: agent: diff --git a/packages/valory/skills/learning_abci/behaviours.py b/packages/valory/skills/learning_abci/behaviours.py index e9f6ca8..bcef9eb 100644 --- a/packages/valory/skills/learning_abci/behaviours.py +++ b/packages/valory/skills/learning_abci/behaviours.py @@ -419,11 +419,11 @@ def async_act(self) -> Generator: self.context.logger.info(f"Price comparison result: {comparison_result}") historical_data_ipfs_hash = yield from self.send_historical_data_to_ipfs(historical_data) - self.context.logger.info(f"Historical data IPFS hash: {type(historical_data_ipfs_hash)}") + self.context.logger.info(f"Historical data IPFS hash: {historical_data_ipfs_hash}") payload = EvaluationPayload( sender=self.context.agent_address, - historical_data_ipfshash=historical_data_ipfs_hash, + historical_data_ipfs_hash=historical_data_ipfs_hash, comparison_data=comparison_result, ) self.context.logger.info("EvaluationPayload prepared and being sent.") @@ -439,7 +439,7 @@ def async_act(self) -> Generator: self.context.logger.error(f"Error in EvaluationBehaviour: {str(e)}") raise - def compare_prices(self, current, historical_average): + def compare_prices(self, current, historical_average) -> str: """Log comparison of current price to historical average.""" if current > historical_average: self.context.logger.info("Current price is higher than the average of last day.") @@ -471,7 +471,6 @@ def get_historical_price_data(self) -> Generator[None, None, list[float]]: self.context.logger.error(f"Exception in fetching historical data: {str(e)}") return [] - def send_historical_data_to_ipfs(self, historical_data) -> Generator[None, None, Optional[str]]: """Store the historical price data in IPFS.""" data = {"historical_prices": historical_data} @@ -483,9 +482,6 @@ def send_historical_data_to_ipfs(self, historical_data) -> Generator[None, None, ) return historical_data_ipfs_hash - - - class TxPreparationBehaviour( LearningBaseBehaviour ): # pylint: disable=too-many-ancestors @@ -501,6 +497,7 @@ def async_act(self) -> Generator: # Get the transaction hash tx_hash = yield from self.get_tx_hash() + yield from self.get_historical_data_from_ipfs() payload = TxPreparationPayload( sender=sender, tx_submitter=self.auto_behaviour_id(), tx_hash=tx_hash @@ -514,12 +511,11 @@ def async_act(self) -> Generator: def get_historical_data_from_ipfs(self) -> Generator[None, None, Optional[dict]]: """Load the historical data from IPFS""" - ipfs_hash = self.synchronized_data.historical_data_ipfshash + ipfs_hash = self.synchronized_data.historical_data_ipfs_hash data = yield from self.get_from_ipfs( ipfs_hash=ipfs_hash, filetype=SupportedFiletype.JSON ) self.context.logger.error(f"Got historical data from IPFS: {data}") - return data def get_tx_hash(self) -> Generator[None, None, Optional[str]]: """Get the transaction hash""" diff --git a/packages/valory/skills/learning_abci/payloads.py b/packages/valory/skills/learning_abci/payloads.py index a5bda13..2b9a1e6 100644 --- a/packages/valory/skills/learning_abci/payloads.py +++ b/packages/valory/skills/learning_abci/payloads.py @@ -19,7 +19,7 @@ """This module contains the transaction payloads of the LearningAbciApp.""" -from dataclasses import dataclass +from dataclasses import dataclass,field from typing import Optional from packages.valory.skills.abstract_round_abci.base import BaseTxPayload @@ -42,15 +42,16 @@ class DecisionMakingPayload(BaseTxPayload): event: str +@dataclass(frozen=True) class EvaluationPayload(BaseTxPayload): - """Payload for the EvaluationRound.""" + """Represent a transaction payload for the EvaluationRound.""" - historical_data_ipfshash:Optional[str] - comparison_data:Optional[bool] + historical_data_ipfs_hash: Optional[str] = field(default=None) + comparison_data: bool = field(default=False) @dataclass(frozen=True) class TxPreparationPayload(BaseTxPayload): """Represent a transaction payload for the TxPreparationRound.""" tx_submitter: Optional[str] = None - tx_hash: Optional[str] = None + tx_hash: Optional[str] = None \ No newline at end of file diff --git a/packages/valory/skills/learning_abci/rounds.py b/packages/valory/skills/learning_abci/rounds.py index b402324..264efc8 100644 --- a/packages/valory/skills/learning_abci/rounds.py +++ b/packages/valory/skills/learning_abci/rounds.py @@ -90,12 +90,12 @@ def participant_to_data_round(self) -> DeserializedCollection: return self._get_deserialized("participant_to_data_round") @property - def historical_data_ipfshash(self) -> Optional[str]: + def historical_data_ipfs_hash(self) -> Optional[str]: """Get the IPFS hash of historical data.""" - return self.db.get("historical_data_ipfshash", None) + return self.db.get("historical_data_ipfs_hash", None) @property - def comparison_data(self) -> Optional[bool]: + def comparison_data(self) -> bool: """Get the comparison result of current vs. historical prices.""" return self.db.get("comparison_data", None) @@ -187,25 +187,10 @@ class EvaluationRound(CollectSameUntilThresholdRound): # Selection key should map directly to the payload data correctly selection_key = ( - get_name(SynchronizedData.historical_data_ipfshash), + get_name(SynchronizedData.historical_data_ipfs_hash), get_name(SynchronizedData.comparison_data), ) - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: - """ - This method is called at the end of the round to finalize the operations based on the data collected. - Since this is a simplified example, it automatically concludes the round by returning the synchronized - data along with a 'DONE' event indicating the round has completed successfully without errors or - the inability to reach a majority. - - Returns: - Optional[Tuple[BaseSynchronizedData, Event]]: Returns a tuple containing the current state of - synchronized data along with the 'DONE' event to signal the successful end of the round. - """ - print("self.synchronized_data",self.synchronized_data) - return self.synchronized_data, Event.DONE - - class TxPreparationRound(CollectSameUntilThresholdRound): """TxPreparationRound""" diff --git a/packages/valory/skills/learning_abci/skill.yaml b/packages/valory/skills/learning_abci/skill.yaml index f1c9696..26139a4 100644 --- a/packages/valory/skills/learning_abci/skill.yaml +++ b/packages/valory/skills/learning_abci/skill.yaml @@ -7,13 +7,13 @@ license: Apache-2.0 aea_version: '>=1.0.0, <2.0.0' fingerprint: __init__.py: bafybeiho3lkochqpmes4f235chq26oggmwnol3vjuvhosleoubbjirbwaq - behaviours.py: bafybeiawutvwbbp6i6nezl7455plvvikc522a6oezd4voe7cjcxq5osuty + behaviours.py: bafybeiab6cxmzl3gixgxr6x32qeclwzad2u7dqhshhsa5gomslrsxkuo3a dialogues.py: bafybeifqjbumctlffx2xvpga2kcenezhe47qhksvgmaylyp5ypwqgfar5u fsm_specification.yaml: bafybeibjeq2tku4bwsh64tm6ud4pz2yt32doffsrt23fxrt6j3bgtz6axm handlers.py: bafybeigjadr4thz6hfpfx5abezbwnqhbxmachf4efasrn4z2vqhsqgnyvi models.py: bafybeic762skwe2zv4awqxhl5rnlnv2vxsw5vefwg5neq6xvbkzv5ethwi - payloads.py: bafybeighb7a6ye35t64ufuwu6k5zjamgbxbvqla2myvkngcuofid4y43cu - rounds.py: bafybeihl2ignqtmcg2ppyw6pjxtms52zryjaz2uprzxy42dzamuhmocesm + payloads.py: bafybeifzwc5ywzowin5bempi3ngu3zdiewpv3zj547shhh63f42qoaf5g4 + rounds.py: bafybeida3pjv2rnj6jckrp6cmc2anfu5ru6umwh5atkbycq7vwnmjibrky fingerprint_ignore_patterns: [] connections: [] contracts: diff --git a/packages/valory/skills/learning_chained_abci/skill.yaml b/packages/valory/skills/learning_chained_abci/skill.yaml index 103c66c..265dc80 100644 --- a/packages/valory/skills/learning_chained_abci/skill.yaml +++ b/packages/valory/skills/learning_chained_abci/skill.yaml @@ -22,7 +22,7 @@ skills: - valory/registration_abci:0.1.0:bafybeiffipsowrqrkhjoexem7ern5ob4fabgif7wa6gtlszcoaop2e3oey - valory/reset_pause_abci:0.1.0:bafybeif4lgvbzsmzljesxbphycdv52ka7qnihyjrjpfaseclxadcmm6yiq - valory/termination_abci:0.1.0:bafybeiekkpo5qef5zaeagm3si6v45qxcojvtjqe4a5ceccvk4q7k3xi3bi -- valory/learning_abci:0.1.0:bafybeicq3jpctj6w5v4rfstjrb7lslynla5jox75gg5rpe4rjpxmnqmw2i +- valory/learning_abci:0.1.0:bafybeia6d5djkyb33iptxbb43mijhgndeyu2jhdbfekzm36y24pyel456y - valory/transaction_settlement_abci:0.1.0:bafybeielv6eivt2z6nforq43xewl2vmpfwpdu2s2vfogobziljnwsclmlm behaviours: main: From e3aefd9f4a2770613d971566a31d029403d3cf7e Mon Sep 17 00:00:00 2001 From: cpp-priyanshu Date: Wed, 4 Dec 2024 17:55:37 +0530 Subject: [PATCH 4/4] resolve the fsm-specification round calling --- .../valory/skills/learning_chained_abci/fsm_specification.yaml | 2 +- sample.env | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/valory/skills/learning_chained_abci/fsm_specification.yaml b/packages/valory/skills/learning_chained_abci/fsm_specification.yaml index 25edbe5..194d76c 100644 --- a/packages/valory/skills/learning_chained_abci/fsm_specification.yaml +++ b/packages/valory/skills/learning_chained_abci/fsm_specification.yaml @@ -67,7 +67,7 @@ transition_func: (DecisionMakingRound, ROUND_TIMEOUT): DecisionMakingRound (DecisionMakingRound, TRANSACT): EvaluationRound (EvaluationRound, DONE): TxPreparationRound - (EvaluationRound, ERROR): EvaluationRound + (EvaluationRound, ERROR): ResetAndPauseRound (EvaluationRound, NO_MAJORITY): EvaluationRound (EvaluationRound, ROUND_TIMEOUT): EvaluationRound (FinalizationRound, CHECK_HISTORY): CheckTransactionHistoryRound diff --git a/sample.env b/sample.env index a9b0101..adafe4f 100644 --- a/sample.env +++ b/sample.env @@ -1,7 +1,7 @@ ALL_PARTICIPANTS='["0x8B0f9b4b40cc2E9685FCf88957Ca39104c8cd721"]' SAFE_CONTRACT_ADDRESS=0xFCE595554cB55c7FAbc5Ab359F398B37DE59f542 SAFE_CONTRACT_ADDRESS_SINGLE=0x11B9506EBCc04EDbdeb42d01b9e3A0CBA0107ffd -GNOSIS_LEDGER_RPC=https://virtual.gnosis.rpc.tenderly.co/204ddd51-1d70-44a7-bb79-63d7e72f9342 +GNOSIS_LEDGER_RPC=https://virtual.gnosis.rpc.tenderly.co/ea862018-a938-4350-a09b-e97ec4c1fb8e COINGECKO_API_KEY=CG-5Nn7yAS9qAvHZxKtGqfjQHri TRANSFER_TARGET_ADDRESS=0xEE93B2F35C8Ef5Bf0395286Ea887181970916243