Skip to content

Commit fc73212

Browse files
authored
Merge pull request #401 from valory-xyz/fix/is-transitioning-fast
Improve the healthcheck
2 parents b84f330 + d2e1c6f commit fc73212

File tree

9 files changed

+94
-55
lines changed

9 files changed

+94
-55
lines changed

packages/packages.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616
"contract/valory/staking_token/0.1.0": "bafybeiabkkhjpybqpzdfc4vcbiz4vefctfpvwetbmo7pqpiuxprmpvnti4",
1717
"contract/valory/relayer/0.1.0": "bafybeibvqc3lwxtcnu6dgfkf7mzefdgtfyosyq2dow7ogyxsl25vkxjwea",
1818
"skill/valory/market_manager_abci/0.1.0": "bafybeihmyqkzl3bm5zvjnc4auj32qjf3pk73scyq7mntmpsudqnisb4gey",
19-
"skill/valory/decision_maker_abci/0.1.0": "bafybeigehrtalp3ppnog25yuvfcdt3gmrgvxb2zm2zyngxxfcvps2s3tza",
20-
"skill/valory/trader_abci/0.1.0": "bafybeideek7oe3rbcnaymd4bnwsm2kull75wfdvljv5prvcsok5sgti7bq",
21-
"skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeih2s2dwnyxm7xhd3knc3wlaejzyvfulxkipwnidmzxgx7t3ofqbpq",
19+
"skill/valory/decision_maker_abci/0.1.0": "bafybeigddrgyys4rqu3x6gwig7cpylesbpy6ioocmngremad373w54nlky",
20+
"skill/valory/trader_abci/0.1.0": "bafybeidvi2fa26sbs3ig56rzfsewzcr2htgwkpxcdxzauyoys27byynoze",
21+
"skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeicffb2hc2efvr33tvbbd5dp5sbj25fkar4fhgmqfbpy4fzxnzolsy",
2222
"skill/valory/staking_abci/0.1.0": "bafybeial5xtgzf37e2khvdrc2q2wa2xhirjwioi2szwvcgtupidjxhg7tq",
2323
"skill/valory/check_stop_trading_abci/0.1.0": "bafybeid7l74lmjnkeerkbvwhoo2l4cawb7c545rhcx3mjpsjux4zwy5wpm",
24-
"agent/valory/trader/0.1.0": "bafybeicy63hsvgcui5p6vwjdgfwrm7ldvjxui4nyy7zykm675xjfnmdbza",
25-
"service/valory/trader/0.1.0": "bafybeiawu46p7whmf6aiywqyechsolmhb56ew7c7pjphmrhzen7umk6lc4",
26-
"service/valory/trader_pearl/0.1.0": "bafybeia3eztsz325jy2sbtilulfnl6pngz3bltkvogowx6xym3kr5re4ei"
24+
"agent/valory/trader/0.1.0": "bafybeif4vgpi37dspburfa4nltd6rzi7muqgqx3ojliutibwpahln3wxbe",
25+
"service/valory/trader/0.1.0": "bafybeigzal6ikcehpsitpi7g3qgv6vhigcp2uqwlqgs3askdzaknk5bcy4",
26+
"service/valory/trader_pearl/0.1.0": "bafybeihgmbbjtkrlu62bkm3e4j2ehqipv5huqpifjiyttvjrk4sikwsfzu"
2727
},
2828
"third_party": {
2929
"protocol/valory/acn_data_share/0.1.0": "bafybeih5ydonnvrwvy2ygfqgfabkr47s4yw3uqxztmwyfprulwfsoe7ipq",

packages/valory/agents/trader/aea-config.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ skills:
5050
- valory/reset_pause_abci:0.1.0:bafybeigebq46oqz2mx2iajupr6p5pgm6z5pvfye5w6zypsseuqtvta7b4a
5151
- valory/termination_abci:0.1.0:bafybeieurwmfernodqyczj5ertsgfbjtjnrlgvte7sli4sajnbopty7inu
5252
- valory/transaction_settlement_abci:0.1.0:bafybeifkftgkyzrxwxjdyqixpp7vk6aqmufikalmwx3kydtlg74tonu47u
53-
- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeih2s2dwnyxm7xhd3knc3wlaejzyvfulxkipwnidmzxgx7t3ofqbpq
53+
- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeicffb2hc2efvr33tvbbd5dp5sbj25fkar4fhgmqfbpy4fzxnzolsy
5454
- valory/market_manager_abci:0.1.0:bafybeihmyqkzl3bm5zvjnc4auj32qjf3pk73scyq7mntmpsudqnisb4gey
55-
- valory/decision_maker_abci:0.1.0:bafybeigehrtalp3ppnog25yuvfcdt3gmrgvxb2zm2zyngxxfcvps2s3tza
56-
- valory/trader_abci:0.1.0:bafybeideek7oe3rbcnaymd4bnwsm2kull75wfdvljv5prvcsok5sgti7bq
55+
- valory/decision_maker_abci:0.1.0:bafybeigddrgyys4rqu3x6gwig7cpylesbpy6ioocmngremad373w54nlky
56+
- valory/trader_abci:0.1.0:bafybeidvi2fa26sbs3ig56rzfsewzcr2htgwkpxcdxzauyoys27byynoze
5757
- valory/staking_abci:0.1.0:bafybeial5xtgzf37e2khvdrc2q2wa2xhirjwioi2szwvcgtupidjxhg7tq
5858
- valory/check_stop_trading_abci:0.1.0:bafybeid7l74lmjnkeerkbvwhoo2l4cawb7c545rhcx3mjpsjux4zwy5wpm
5959
- valory/mech_interact_abci:0.1.0:bafybeif2tpz2zet6p4z4vi3b254oxzyyzoe5tehj3me3znzt7h7otkpd54

packages/valory/services/trader/service.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ license: Apache-2.0
77
fingerprint:
88
README.md: bafybeigtuothskwyvrhfosps2bu6suauycolj67dpuxqvnicdrdu7yhtvq
99
fingerprint_ignore_patterns: []
10-
agent: valory/trader:0.1.0:bafybeicy63hsvgcui5p6vwjdgfwrm7ldvjxui4nyy7zykm675xjfnmdbza
10+
agent: valory/trader:0.1.0:bafybeif4vgpi37dspburfa4nltd6rzi7muqgqx3ojliutibwpahln3wxbe
1111
number_of_agents: 4
1212
deployment:
1313
agent:

packages/valory/services/trader_pearl/service.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ license: Apache-2.0
88
fingerprint:
99
README.md: bafybeibg7bdqpioh4lmvknw3ygnllfku32oca4eq5pqtvdrdsgw6buko7e
1010
fingerprint_ignore_patterns: []
11-
agent: valory/trader:0.1.0:bafybeicy63hsvgcui5p6vwjdgfwrm7ldvjxui4nyy7zykm675xjfnmdbza
11+
agent: valory/trader:0.1.0:bafybeif4vgpi37dspburfa4nltd6rzi7muqgqx3ojliutibwpahln3wxbe
1212
number_of_agents: 1
1313
deployment:
1414
agent:

packages/valory/skills/decision_maker_abci/handlers.py

+73-34
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
import json
2323
import re
24-
from datetime import datetime
24+
from datetime import datetime, timezone
2525
from enum import Enum
2626
from typing import Any, Callable, Dict, Optional, Tuple, cast
2727
from urllib.parse import urlparse
@@ -33,6 +33,7 @@
3333
)
3434
from packages.valory.protocols.http.message import HttpMessage
3535
from packages.valory.protocols.ipfs import IpfsMessage
36+
from packages.valory.skills.abstract_round_abci.base import RoundSequence
3637
from packages.valory.skills.abstract_round_abci.handlers import (
3738
ABCIRoundHandler as BaseABCIRoundHandler,
3839
)
@@ -70,6 +71,9 @@
7071
TendermintHandler = BaseTendermintHandler
7172

7273

74+
FSM_REPR_MAX_DEPTH = 25
75+
76+
7377
class IpfsHandler(AbstractResponseHandler):
7478
"""IPFS message handler."""
7579

@@ -104,6 +108,7 @@ def handle(self, message: IpfsMessage) -> None:
104108
OK_CODE = 200
105109
NOT_FOUND_CODE = 404
106110
BAD_REQUEST_CODE = 400
111+
TOO_EARLY_CODE = 425
107112
AVERAGE_PERIOD_SECONDS = 10
108113

109114

@@ -156,12 +161,15 @@ def setup(self) -> None:
156161

157162
self.rounds_info = load_rounds_info_with_transitions()
158163

164+
@property
165+
def round_sequence(self) -> RoundSequence:
166+
"""Return the round sequence."""
167+
return self.context.state.round_sequence
168+
159169
@property
160170
def synchronized_data(self) -> SynchronizedData:
161171
"""Return the synchronized data."""
162-
return SynchronizedData(
163-
db=self.context.state.round_sequence.latest_synchronized_data.db
164-
)
172+
return SynchronizedData(db=self.round_sequence.latest_synchronized_data.db)
165173

166174
def _get_handler(self, url: str, method: str) -> Tuple[Optional[Callable], Dict]:
167175
"""Check if an url is meant to be handled in this handler
@@ -176,7 +184,7 @@ def _get_handler(self, url: str, method: str) -> Tuple[Optional[Callable], Dict]
176184
# Check base url
177185
if not re.match(self.handler_url_regex, url):
178186
self.context.logger.info(
179-
f"The url {url} does not match the DynamicNFT HttpHandler's pattern"
187+
f"The url {url} does not match the HttpHandler's pattern"
180188
)
181189
return None, {}
182190

@@ -193,7 +201,7 @@ def _get_handler(self, url: str, method: str) -> Tuple[Optional[Callable], Dict]
193201

194202
# No route found
195203
self.context.logger.info(
196-
f"The message [{method}] {url} is intended for the DynamicNFT HttpHandler but did not match any valid pattern"
204+
f"The message [{method}] {url} is intended for the HttpHandler but did not match any valid pattern"
197205
)
198206
return self._handle_bad_request, {}
199207

@@ -265,6 +273,36 @@ def _handle_bad_request(
265273
self.context.logger.info("Responding with: {}".format(http_response))
266274
self.context.outbox.put_message(message=http_response)
267275

276+
def _has_transitioned(self) -> bool:
277+
"""Check if the agent has transitioned."""
278+
try:
279+
return bool(self.round_sequence.last_round_transition_height)
280+
except ValueError:
281+
return False
282+
283+
def _handle_too_early(
284+
self, http_msg: HttpMessage, http_dialogue: HttpDialogue
285+
) -> None:
286+
"""
287+
Handle a request when the FSM's loop has not started yet.
288+
289+
:param http_msg: the http message
290+
:param http_dialogue: the http dialogue
291+
"""
292+
http_response = http_dialogue.reply(
293+
performative=HttpMessage.Performative.RESPONSE,
294+
target_message=http_msg,
295+
version=http_msg.version,
296+
status_code=TOO_EARLY_CODE,
297+
status_text="The state machine has not started yet! Please try again later...",
298+
headers=http_msg.headers,
299+
body=b"",
300+
)
301+
302+
# Send response
303+
self.context.logger.info("Responding with: {}".format(http_response))
304+
self.context.outbox.put_message(message=http_response)
305+
268306
def _handle_get_health(
269307
self, http_msg: HttpMessage, http_dialogue: HttpDialogue
270308
) -> None:
@@ -274,40 +312,41 @@ def _handle_get_health(
274312
:param http_msg: the http message
275313
:param http_dialogue: the http dialogue
276314
"""
277-
seconds_since_last_transition = None
278-
is_tm_unhealthy = None
279-
is_transitioning_fast = None
280-
current_round = None
281-
rounds = None
315+
if not self._has_transitioned():
316+
self._handle_too_early(http_msg, http_dialogue)
317+
return
318+
282319
has_required_funds = self._check_required_funds()
283320
is_receiving_mech_responses = self._check_is_receiving_mech_responses()
284321
is_staking_kpi_met = self.synchronized_data.is_staking_kpi_met
285322
staking_status = self.synchronized_data.service_staking_state.name.lower()
286323

287-
round_sequence = cast(SharedState, self.context.state).round_sequence
324+
round_sequence = self.round_sequence
325+
is_tm_unhealthy = round_sequence.block_stall_deadline_expired
288326

289-
if round_sequence._last_round_transition_timestamp:
290-
is_tm_unhealthy = cast(
291-
SharedState, self.context.state
292-
).round_sequence.block_stall_deadline_expired
293-
294-
current_time = datetime.now().timestamp()
295-
seconds_since_last_transition = current_time - datetime.timestamp(
296-
round_sequence._last_round_transition_timestamp
297-
)
327+
current_time = datetime.now().timestamp()
328+
seconds_since_last_transition = current_time - datetime.timestamp(
329+
round_sequence.last_round_transition_timestamp
330+
)
298331

299-
is_transitioning_fast = (
300-
not is_tm_unhealthy
301-
and seconds_since_last_transition
302-
< 2 * self.context.params.reset_pause_duration
303-
)
332+
abci_app = self.round_sequence.abci_app
333+
previous_rounds = abci_app._previous_rounds
334+
previous_round_cls = type(previous_rounds[-1])
335+
previous_round_events = abci_app.transition_function.get(
336+
previous_round_cls, {}
337+
).keys()
338+
previous_round_timeouts = {
339+
abci_app.event_to_timeout.get(event, -1) for event in previous_round_events
340+
}
341+
last_round_timeout = max(previous_round_timeouts)
342+
is_transitioning_fast = (
343+
not is_tm_unhealthy
344+
and seconds_since_last_transition < 2 * last_round_timeout
345+
)
304346

305-
if round_sequence._abci_app:
306-
current_round = round_sequence._abci_app.current_round.round_id
307-
rounds = [
308-
r.round_id for r in round_sequence._abci_app._previous_rounds[-25:]
309-
]
310-
rounds.append(current_round)
347+
rounds = [r.round_id for r in previous_rounds[-FSM_REPR_MAX_DEPTH:]] + [
348+
round_sequence.current_round_id
349+
]
311350

312351
data = {
313352
"seconds_since_last_transition": seconds_since_last_transition,
@@ -348,7 +387,7 @@ def _send_ok_response(
348387
def _send_not_found_response(
349388
self, http_msg: HttpMessage, http_dialogue: HttpDialogue
350389
) -> None:
351-
"""Send an not found response"""
390+
"""Send a not found response"""
352391
http_response = http_dialogue.reply(
353392
performative=HttpMessage.Performative.RESPONSE,
354393
target_message=http_msg,
@@ -375,6 +414,6 @@ def _check_is_receiving_mech_responses(self) -> bool:
375414
# (an on chain transaction)
376415
return (
377416
self.synchronized_data.decision_receive_timestamp
378-
< int(datetime.utcnow().timestamp())
417+
< int(datetime.now(timezone.utc).timestamp())
379418
- self.context.params.expected_mech_response_time
380419
)

packages/valory/skills/decision_maker_abci/skill.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ fingerprint:
2929
behaviours/tool_selection.py: bafybeienlxcgjs3ogyofli3d7q3p5rst3mcxxcnwqf7qolqjeefjtixeke
3030
dialogues.py: bafybeigpwuzku3we7axmxeamg7vn656maww6emuztau5pg3ebsoquyfdqm
3131
fsm_specification.yaml: bafybeifvu7n6sjmrerogkzsftjrw2l6w5ppuq3f43ouj2rwbomdr5glp2e
32-
handlers.py: bafybeieggvt2rh654s2jt2ablqtyzaycb7wlgrrdbsccf5652nptv45hie
32+
handlers.py: bafybeiherm5a2kjmf46ffjoyvhh3tsja5au5i677oasiutdxdojwdtwqla
3333
io_/__init__.py: bafybeifxgmmwjqzezzn3e6keh2bfo4cyo7y5dq2ept3stfmgglbrzfl5rq
3434
io_/loader.py: bafybeih3sdsx5dhe4kzhtoafexjgkutsujwqy3zcdrlrkhtdks45bc7exa
3535
models.py: bafybeiasqxrhudkisjohjdgbkmmj6esyw52sh66xflwkatd5dyradxb37q

packages/valory/skills/trader_abci/skill.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ skills:
2727
- valory/transaction_settlement_abci:0.1.0:bafybeifkftgkyzrxwxjdyqixpp7vk6aqmufikalmwx3kydtlg74tonu47u
2828
- valory/termination_abci:0.1.0:bafybeieurwmfernodqyczj5ertsgfbjtjnrlgvte7sli4sajnbopty7inu
2929
- valory/market_manager_abci:0.1.0:bafybeihmyqkzl3bm5zvjnc4auj32qjf3pk73scyq7mntmpsudqnisb4gey
30-
- valory/decision_maker_abci:0.1.0:bafybeigehrtalp3ppnog25yuvfcdt3gmrgvxb2zm2zyngxxfcvps2s3tza
31-
- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeih2s2dwnyxm7xhd3knc3wlaejzyvfulxkipwnidmzxgx7t3ofqbpq
30+
- valory/decision_maker_abci:0.1.0:bafybeigddrgyys4rqu3x6gwig7cpylesbpy6ioocmngremad373w54nlky
31+
- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeicffb2hc2efvr33tvbbd5dp5sbj25fkar4fhgmqfbpy4fzxnzolsy
3232
- valory/staking_abci:0.1.0:bafybeial5xtgzf37e2khvdrc2q2wa2xhirjwioi2szwvcgtupidjxhg7tq
3333
- valory/check_stop_trading_abci:0.1.0:bafybeid7l74lmjnkeerkbvwhoo2l4cawb7c545rhcx3mjpsjux4zwy5wpm
3434
- valory/mech_interact_abci:0.1.0:bafybeif2tpz2zet6p4z4vi3b254oxzyyzoe5tehj3me3znzt7h7otkpd54

packages/valory/skills/tx_settlement_multiplexer_abci/skill.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ protocols:
2323
- valory/ledger_api:1.0.0:bafybeihmqzcbj6t7vxz2aehd5726ofnzsfjs5cwlf42ro4tn6i34cbfrc4
2424
skills:
2525
- valory/abstract_round_abci:0.1.0:bafybeia27qmw6w5ds5fcrpj2475brnz742aampe3sgochloijs2l7jovai
26-
- valory/decision_maker_abci:0.1.0:bafybeigehrtalp3ppnog25yuvfcdt3gmrgvxb2zm2zyngxxfcvps2s3tza
26+
- valory/decision_maker_abci:0.1.0:bafybeigddrgyys4rqu3x6gwig7cpylesbpy6ioocmngremad373w54nlky
2727
- valory/staking_abci:0.1.0:bafybeial5xtgzf37e2khvdrc2q2wa2xhirjwioi2szwvcgtupidjxhg7tq
2828
- valory/mech_interact_abci:0.1.0:bafybeif2tpz2zet6p4z4vi3b254oxzyyzoe5tehj3me3znzt7h7otkpd54
2929
behaviours:

poetry.lock

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)