Skip to content

Commit

Permalink
Merge branch 'main' into fix/coverage-gap
Browse files Browse the repository at this point in the history
  • Loading branch information
angrybayblade committed Jan 27, 2022
2 parents ad4a457 + d44d7e1 commit 6c262f1
Show file tree
Hide file tree
Showing 14 changed files with 231 additions and 150 deletions.
44 changes: 44 additions & 0 deletions docs/api/skills/abstract_round_abci/base.md
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,17 @@ Return true if a Byzantine majority is achievable, false otherwise.

True if the majority is still possible, false otherwise.

<a id="packages.valory.skills.abstract_round_abci.base.AbstractRound.consensus_threshold"></a>

#### consensus`_`threshold

```python
@property
def consensus_threshold() -> int
```

Consensus threshold

<a id="packages.valory.skills.abstract_round_abci.base.AbstractRound.check_payload"></a>

#### check`_`payload
Expand Down Expand Up @@ -1127,6 +1138,28 @@ def __init__(*args: Any, **kwargs: Any)

Initialize the collection round.

<a id="packages.valory.skills.abstract_round_abci.base.CollectionRound.payloads"></a>

#### payloads

```python
@property
def payloads() -> List[BaseTxPayload]
```

Get all agent payloads

<a id="packages.valory.skills.abstract_round_abci.base.CollectionRound.payloads_count"></a>

#### payloads`_`count

```python
@property
def payloads_count() -> Counter
```

Get count of payload attributes

<a id="packages.valory.skills.abstract_round_abci.base.CollectionRound.process_payload"></a>

#### process`_`payload
Expand Down Expand Up @@ -1323,6 +1356,17 @@ VotingRound
This class represents logic for rounds where a round needs votes from
agents, pass if k same votes of n agents

<a id="packages.valory.skills.abstract_round_abci.base.VotingRound.vote_count"></a>

#### vote`_`count

```python
@property
def vote_count() -> Counter
```

Get agent payload vote count

<a id="packages.valory.skills.abstract_round_abci.base.VotingRound.positive_vote_threshold_reached"></a>

#### positive`_`vote`_`threshold`_`reached
Expand Down
17 changes: 9 additions & 8 deletions docs/api/skills/abstract_round_abci/utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,26 +136,27 @@ def __init__() -> None

Benchmark tool for rounds behaviours.

<a id="packages.valory.skills.abstract_round_abci.utils.BenchmarkTool.data"></a>
<a id="packages.valory.skills.abstract_round_abci.utils.BenchmarkTool.context"></a>

#### data
#### context

```python
@property
def data() -> Dict
def context() -> SkillContext
```

Returns formatted data.
Get skill context

<a id="packages.valory.skills.abstract_round_abci.utils.BenchmarkTool.log"></a>
<a id="packages.valory.skills.abstract_round_abci.utils.BenchmarkTool.data"></a>

#### log
#### data

```python
def log() -> None
@property
def data() -> List
```

Output log.
Returns formatted data.

<a id="packages.valory.skills.abstract_round_abci.utils.BenchmarkTool.save"></a>

Expand Down
9 changes: 9 additions & 0 deletions docs/price_estimation.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,15 @@ and subsequently stripped from unnecessary data structures and behaviours.

### The `PriceAggregationAbciApp`

This `AbciApp` implements off-chain aggregation of observations by the agents.
Once the majority of agents has submitted their observation these are shared
with all agents as they move to the price estimation round. In this next round
each of the agents performs off-chain a computation on the data set, which could
be a simple summary statistic or an estimate derived from a complex model -
either way this is something that cannot be done on-chain. Once consensus is
reached on this estimate, the aggregate value is submitted and recorded
on-chain in the next block that is mined.

0. `CollectObservationRound` <br/>
Observational data is collected by the AEAs on the target quantity to
estimate. Once the agents reach consensus over this data, that is to say at
Expand Down
6 changes: 3 additions & 3 deletions packages/hashes.csv
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ valory/contracts/gnosis_safe_proxy_factory,QmQC54GB8DQ21cSNL4tvXTxtgps3785vM6jx8
valory/contracts/multisend,QmTHULSBYd5fmhPuXskVN2dfPAFqXtgL6tnwoESU5xBJr7
valory/contracts/offchain_aggregator,QmQiiAXrx5r7p7qur2uXMv4QGJvou15A4yVNSz2HG61uLa
valory/contracts/uniswap_v2_erc20,QmSwm4fK1VUR97kiTwwHyxEQyYRZBxLYnVBdDk11D6jg6u
valory/contracts/uniswap_v2_router_02,QmV3syJHEMbhiwARfGcyUgSazUdnRTGrGmgZ1AWpn4GrxK
valory/contracts/uniswap_v2_router_02,QmNmShbPWSdpfdYhcZBV5TyXEbv5ZsfFKCYcttRdxDzFeh
valory/protocols/abci,QmQ9yWLMQkozpryqawEScB764VD6Z9aDNLccAsX1cuQp3Z
valory/protocols/contract_api,QmcM7FdjuyyRM3iYudLNnFdqJQUasi1Ba2Skf3xyuETRUp
valory/protocols/http,QmRKu1vs6w2iug8sgFiporMuo9QR1K2Gvwve7p6eLhRkmg
valory/protocols/ledger_api,QmcjQd5XckbTUUwc5nYCJCU6FvUKfhRNCG4M4EMGXt1jVG
valory/skills/abstract_abci,QmS2Ppvq8jCLWy8cyykUZ1EZ71BsPWeZBE7hBo18FLfST9
valory/skills/abstract_round_abci,QmQGH65ny16CZZcQux6iP3zNnmETViCk3tSrypsGFApMh9
valory/skills/abstract_round_abci,QmT91tjxXp7Q9grfgs23gbQT8am1kmwpwmh2KKQpToc9TW
valory/skills/apy_estimation_abci,QmWFUCFFPLV5NDbPWsVsMf5CNYR6VzVeHzeXPcPpEXm1u8
valory/skills/counter,QmTKi3jYQDZNXR9q65ZYcTb4ezkYiBBchC3cDLuvk2tg3p
valory/skills/counter_client,QmbLse9HQhHoWkxmwPkutUpecKRxQbwoJKoAoGHmdAkUZ2
valory/skills/liquidity_provision,QmbzUVrhGisyHVkL3G9Cp7eBPUfHAFEhvqswFLB8k4XcsD
valory/skills/oracle_deployment_abci,QmYyGWZ45Ant4g1N1hXhEwkvhVk8JZ5KeyWa5fUNuD6wA1
valory/skills/price_estimation_abci,QmbYGKDkH75z1vz36kRxCrYMjG6PR23DTUiPVc9zPwyRLj
valory/skills/price_estimation_abci,QmXPPbJJtye6o4PNH2jhLTvDxXMc4z1RR5R8fR38CmhpQe
valory/skills/registration_abci,QmfGsVvmwqMkjYX7WtrZud3kABYrQgisDKDtPgTwJ8MQYT
valory/skills/safe_deployment_abci,QmYZRp9kHLX2qzNTPJ3HjVhS8fwtDoKzg7Z4GbTetrVSbE
valory/skills/simple_abci,QmTEJiZBZ3WCTQgySHGp76cTNkSbCcaZZVwTwfTNEngcaQ
Expand Down
9 changes: 8 additions & 1 deletion packages/valory/contracts/uniswap_v2_router_02/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,14 @@ def get_method_data(
args = [kwargs[i] for i in input_names]
# Encode and return the contract call
data = instance.encodeABI(fn_name=method_name, args=args)
except KeyError: # pragma: nocover # TOFIX catch other exceptions which can occur
except KeyError as e: # pragma: nocover
_logger.warning(f"No such information in method ABI:\n{e}")
return None
except AttributeError as e: # pragma: nocover
_logger.warning(f"No such attribute:\n{e}")
return None
except TypeError as e: # pragma: nocover
_logger.warning(f"Method called with wrong arguments:\n{e}")
return None
return {"data": bytes.fromhex(data[2:])} # type: ignore

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ aea_version: '>=1.0.0, <2.0.0'
fingerprint:
__init__.py: QmevsUxqaoqkrvyQL4RJhaGBLagpGStUUBggwWbpHa2A5o
build/IUniswapV2Router02.json: QmZPa3Ua4UU8MrRmyDmRFFJuK6UPiGV2N75anRASzpiKMK
contract.py: QmTZjp6yV4ZB2aA4dR2Z1XWJY8i2znscdNo3TNhCtopjh4
contract.py: QmNiVHPd32hssXLQWHcZfa9GDKAUHwpucEk4UyheS3CtiG
fingerprint_ignore_patterns: []
contracts: []
class_name: UniswapV2Router02Contract
Expand Down
81 changes: 35 additions & 46 deletions packages/valory/skills/abstract_round_abci/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@
from dataclasses import dataclass, field
from enum import Enum
from math import ceil
from operator import itemgetter
from typing import Any
from typing import Counter as CounterType
from typing import (
Any,
Dict,
FrozenSet,
Generic,
Expand Down Expand Up @@ -837,6 +835,11 @@ def is_majority_possible(
return False
return True

@property
def consensus_threshold(self) -> int:
"""Consensus threshold"""
return self._consensus_params.consensus_threshold

@abstractmethod
def check_payload(self, payload: BaseTxPayload) -> None:
"""Check payload."""
Expand Down Expand Up @@ -890,6 +893,16 @@ def __init__(self, *args: Any, **kwargs: Any):
super().__init__(*args, **kwargs)
self.collection: Dict[str, BaseTxPayload] = {}

@property
def payloads(self) -> List[BaseTxPayload]:
"""Get all agent payloads"""
return list(self.collection.values())

@property
def payloads_count(self) -> Counter:
"""Get count of payload attributes"""
return Counter(map(lambda p: getattr(p, self.payload_attribute), self.payloads))

def process_payload(self, payload: BaseTxPayload) -> None:
"""Process payload."""

Expand Down Expand Up @@ -980,29 +993,17 @@ def threshold_reached(
self,
) -> bool:
"""Check if the threshold has been reached."""

counter: CounterType = Counter()
counter.update(
getattr(payload, self.payload_attribute)
for payload in self.collection.values()
)
return any(
count >= self._consensus_params.consensus_threshold
for count in counter.values()
)
counts = self.payloads_count.values()
return any(count >= self.consensus_threshold for count in counts)

@property
def most_voted_payload(
self,
) -> Any:
"""Get the most voted payload."""
counter = Counter() # type: ignore
counter.update(
getattr(payload, self.payload_attribute)
for payload in self.collection.values()
)
most_voted_payload, max_votes = max(counter.items(), key=itemgetter(1))
if max_votes < self._consensus_params.consensus_threshold:

most_voted_payload, max_votes = self.payloads_count.most_common()[0]
if max_votes < self.consensus_threshold:
raise ABCIAppInternalError("not enough votes")
return most_voted_payload

Expand Down Expand Up @@ -1117,32 +1118,25 @@ class VotingRound(CollectionRound):
collection_key: str
period_state_class = BasePeriodState

@property
def vote_count(self) -> Counter:
"""Get agent payload vote count"""
return Counter(payload.vote for payload in self.collection.values()) # type: ignore

@property
def positive_vote_threshold_reached(self) -> bool:
"""Check that the vote threshold has been reached."""
true_votes = sum(
[payload.vote is True for payload in self.collection.values()] # type: ignore
)
# check that "true" has at least the consensus # of votes
return true_votes >= self._consensus_params.consensus_threshold
return self.vote_count[True] >= self.consensus_threshold

@property
def negative_vote_threshold_reached(self) -> bool:
"""Check that the vote threshold has been reached."""
false_votes = sum(
[payload.vote is False for payload in self.collection.values()] # type: ignore
)
# check that "false" has at least the consensus # of votes
return false_votes >= self._consensus_params.consensus_threshold
return self.vote_count[False] >= self.consensus_threshold

@property
def none_vote_threshold_reached(self) -> bool:
"""Check that the vote threshold has been reached."""
none_votes = sum(
[payload.vote is None for payload in self.collection.values()] # type: ignore
)
# check that "None" has at least the consensus # of votes
return none_votes >= self._consensus_params.consensus_threshold
return self.vote_count[None] >= self.consensus_threshold

def end_block(self) -> Optional[Tuple[BasePeriodState, Enum]]:
"""Process the end of the block."""
Expand Down Expand Up @@ -1181,7 +1175,7 @@ def collection_threshold_reached(
self,
) -> bool:
"""Check if the threshold has been reached."""
return len(self.collection) >= self._consensus_params.consensus_threshold
return len(self.collection) >= self.consensus_threshold

def end_block(self) -> Optional[Tuple[BasePeriodState, Enum]]:
"""Process the end of the block."""
Expand Down Expand Up @@ -1311,14 +1305,10 @@ def _check_consistency(mcs, abci_app_cls: Type["AbciApp"]) -> None:
@classmethod
def _check_required_class_attributes(mcs, abci_app_cls: Type["AbciApp"]) -> None:
"""Check that required class attributes are set."""
try:
abci_app_cls.initial_round_cls
except AttributeError as exc:
raise ABCIAppInternalError("'initial_round_cls' field not set") from exc
try:
abci_app_cls.transition_function
except AttributeError as exc:
raise ABCIAppInternalError("'transition_function' field not set") from exc
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(
Expand Down Expand Up @@ -1783,7 +1773,7 @@ def syncing_up(
def abci_app(self) -> AbciApp:
"""Get the AbciApp."""
if self._abci_app is None:
raise ABCIAppInternalError("AbciApp not set")
raise ABCIAppInternalError("AbciApp not set") # pragma: nocover
return self._abci_app

@property
Expand Down Expand Up @@ -1863,7 +1853,6 @@ 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.
"""
Expand Down
4 changes: 2 additions & 2 deletions packages/valory/skills/abstract_round_abci/skill.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ fingerprint:
README.md: QmYNXPppPSnW61ipqKNH8pyMh8qzTERwQaducYYq1dnBJb
__init__.py: QmPuJK7gMKruSTcaYk9otrFncfD9h6vBZVoAtkwhTBgcxa
abci_app_chain.py: QmY4CAjgeM3GdPRT5NCTfeDdEfyUkCJc8FZNKsyW4vQ6oB
base.py: Qma39emgG2uXo6zrFN6VqquWeQNFJuJTDzCaxTz31ykJw9
base.py: QmPLVrvaudsmxwY9WmjLMPp1kzf1sdhDSPeLbHnMoRQPv5
behaviour_utils.py: QmXBfYhLwdhy5LT4NrBKXWoGQDXAGbWn9Z2osxeQm2ESHr
behaviours.py: QmNZiFSYdw7jes51c8Go4jykSSjoQWHtYt1DcLShrfHHCg
common.py: QmdoSkkkCRqoHX9T2rnPLpii5KVvEmibktKDik3pe2mNB7
dialogues.py: QmemiTJxfwp2PFxFQyAUHTx8FsthhWL3mYgonBhC3cTjWH
handlers.py: QmX82xDvh14N4LFLGMpA2FyKjh1KwNCSQqY1LSjZzgoWC9
models.py: Qme7SDyBwZzKqtdNXcun75H4gLDAkbMRPJDSuXa1enLWDj
serializer.py: QmV1rutPMEPbbMVwvM4My6s8fwT7S9KhgLTqrbjHLEfdJG
utils.py: QmThxHpnFD13vsDEx6P8F8K8QFLB4CQF7RrCBqYgNg6QWu
utils.py: Qmf3DtFoBfDEHCmaodLi3NxKWFck1xdsZsrScWfmDAsG6f
fingerprint_ignore_patterns: []
connections:
- valory/abci:0.1.0
Expand Down
Loading

0 comments on commit 6c262f1

Please sign in to comment.