Skip to content

Commit

Permalink
Merge pull request #370 from lidofinance/fix/oracle-v3-fixes-6
Browse files Browse the repository at this point in the history
Fix/oracle v3 fixes 6
  • Loading branch information
F4ever committed May 2, 2023
2 parents 73a655c + 9402d8f commit e50088b
Show file tree
Hide file tree
Showing 13 changed files with 47 additions and 68 deletions.
1 change: 0 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends -qq \
gcc=4:10.2.1-1 \
libffi-dev=3.3-6 \
g++=4:10.2.1-1 \
git=1:2.30.2-1 \
curl=7.74.0-1.3+deb11u7 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ In manual mode all sleeps are disabled and `ALLOW_REPORTING_IN_BUNKER_MODE` is T
| `TX_GAS_ADDITION` | Used to modify gas parameter that used in transaction. (gas = estimated_gas + TX_GAS_ADDITION) | False | `100000` |
| `CYCLE_SLEEP_IN_SECONDS` | The time between cycles of the oracle's activity | False | `12` |
| `SUBMIT_DATA_DELAY_IN_SLOTS` | The difference in slots between submit data transactions from Oracles. It is used to prevent simultaneous sending of transactions and, as a result, transactions revert. | False | `6` |
| `HTTP_REQUEST_TIMEOUT_EXECUTION` | Timeout for HTTP execution layer requests | False | `120` |
| `HTTP_REQUEST_TIMEOUT_CONSENSUS` | Timeout for HTTP consensus layer requests | False | `300` |
| `HTTP_REQUEST_RETRY_COUNT_CONSENSUS` | Total number of retries to fetch data from endpoint for consensus layer requests | False | `5` |
| `HTTP_REQUEST_SLEEP_BEFORE_RETRY_IN_SECONDS_CONSENSUS` | The delay http provider sleeps if API is stuck for consensus layer | False | `12` |
Expand Down

This file was deleted.

This file was deleted.

5 changes: 4 additions & 1 deletion src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ def main(module_name: OracleModule):
start_http_server(variables.PROMETHEUS_PORT)

logger.info({'msg': 'Initialize multi web3 provider.'})
web3 = Web3(FallbackProviderModule(variables.EXECUTION_CLIENT_URI))
web3 = Web3(FallbackProviderModule(
variables.EXECUTION_CLIENT_URI,
request_kwargs={'timeout': variables.HTTP_REQUEST_TIMEOUT_EXECUTION}
))

logger.info({'msg': 'Modify web3 with custom contract function call.'})
tweak_w3_contracts(web3)
Expand Down
12 changes: 9 additions & 3 deletions src/modules/checks/suites/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import pytest
from _pytest._io import TerminalWriter
from web3_multi_provider import MultiProvider
from xdist import is_xdist_controller # type: ignore[import]
from xdist.dsession import TerminalDistReporter # type: ignore[import]

Expand All @@ -10,8 +9,12 @@
from src.utils.slot import get_reference_blockstamp
from src.web3py.contract_tweak import tweak_w3_contracts
from src.web3py.extensions import (
ConsensusClientModule, KeysAPIClientModule, LidoValidatorsProvider, TransactionUtils,
ConsensusClientModule,
KeysAPIClientModule,
LidoValidatorsProvider,
TransactionUtils,
LidoContracts,
FallbackProviderModule,
)
from src.web3py.typings import Web3

Expand All @@ -21,7 +24,10 @@

@pytest.fixture()
def web3():
web3 = Web3(MultiProvider(variables.EXECUTION_CLIENT_URI))
web3 = Web3(FallbackProviderModule(
variables.EXECUTION_CLIENT_URI,
request_kwargs={'timeout': variables.HTTP_REQUEST_TIMEOUT_EXECUTION}
))
tweak_w3_contracts(web3)
cc = ConsensusClientModule(variables.CONSENSUS_CLIENT_URI, web3)
kac = KeysAPIClientModule(variables.KEYS_API_URI, web3)
Expand Down
28 changes: 17 additions & 11 deletions src/modules/submodules/consensus.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,29 +270,35 @@ def process_report(self, blockstamp: ReferenceBlockStamp) -> None:
if not self.is_reporting_allowed(blockstamp):
logger.warning({'msg': 'Reporting checks are not passed. Report will not be sent.'})
return

self._process_report_hash(blockstamp, report_hash)
# Even if report hash transaction was failed we have to check if we can report data for current frame
self._process_report_data(blockstamp, report_data, report_hash)

def _process_report_hash(self, blockstamp: ReferenceBlockStamp, report_hash: HexBytes) -> None:
latest_blockstamp, member_info = self._get_latest_data()

# Check if current slot is newer than (member slot + slots_delay)
if not member_info.is_fast_lane:
if latest_blockstamp.slot_number < member_info.current_frame_ref_slot + member_info.fast_lane_length_slot:
logger.info({'msg': f'Member is not in fast lane, so report will be postponed for [{member_info.fast_lane_length_slot}] slots.'})
return None

if not member_info.is_report_member:
logger.info({'msg': 'Account can`t submit report hash.'})
return None

if HexBytes(member_info.current_frame_member_report) != report_hash:
logger.info({'msg': f'Send report hash. Consensus version: [{self.CONSENSUS_VERSION}]'})
self._send_report_hash(blockstamp, report_hash, self.CONSENSUS_VERSION)
else:
logger.info({'msg': 'Provided hash already submitted.'})
if HexBytes(member_info.current_frame_member_report) == report_hash:
logger.info({'msg': 'Account already submitted provided hash.'})
return None

if not member_info.is_fast_lane:
# Check if current slot is newer than (member slot + slots_delay)
if latest_blockstamp.slot_number < member_info.current_frame_ref_slot + member_info.fast_lane_length_slot:
logger.info({'msg': f'Member is not in fast lane, so report will be postponed '
f'for [{member_info.fast_lane_length_slot}] slots.'})
return None

if HexBytes(member_info.current_frame_consensus_report) == report_hash:
logger.info({'msg': 'Consensus reached with provided hash.'})
return None

logger.info({'msg': f'Send report hash. Consensus version: [{self.CONSENSUS_VERSION}]'})
self._send_report_hash(blockstamp, report_hash, self.CONSENSUS_VERSION)
return None

def _process_report_data(self, blockstamp: ReferenceBlockStamp, report_data: tuple, report_hash: HexBytes):
Expand Down
File renamed without changes.
7 changes: 3 additions & 4 deletions src/providers/http_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@
from prometheus_client import Histogram
from requests import Session, JSONDecodeError
from requests.adapters import HTTPAdapter
from requests.exceptions import ConnectionError as RequestsConnectionError
from urllib3 import Retry

from src.web3py.extensions.consistency import ProviderConsistencyModule
from src.providers.consistency import ProviderConsistencyModule


logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -126,8 +125,8 @@ def _get_without_fallbacks(
params=query_params,
timeout=self.request_timeout,
)
except RequestsConnectionError as error:
logger.debug({'msg': str(error)})
except Exception as error:
logger.error({'msg': str(error)})
t.labels(
endpoint=endpoint,
code=0,
Expand Down
2 changes: 2 additions & 0 deletions src/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
CYCLE_SLEEP_IN_SECONDS = 0

# HTTP variables
HTTP_REQUEST_TIMEOUT_EXECUTION = int(os.getenv('HTTP_REQUEST_TIMEOUT_EXECUTION', 2 * 60))

HTTP_REQUEST_TIMEOUT_CONSENSUS = int(os.getenv('HTTP_REQUEST_TIMEOUT_CONSENSUS', 5 * 60))
HTTP_REQUEST_RETRY_COUNT_CONSENSUS = int(os.getenv('HTTP_REQUEST_RETRY_COUNT_CONSENSUS', 5))
HTTP_REQUEST_SLEEP_BEFORE_RETRY_IN_SECONDS_CONSENSUS = int(
Expand Down
1 change: 0 additions & 1 deletion src/web3py/extensions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@
from src.web3py.extensions.contracts import LidoContracts
from src.web3py.extensions.lido_validators import LidoValidatorsProvider
from src.web3py.extensions.fallback import FallbackProviderModule
from src.web3py.extensions.consistency import ProviderConsistencyModule
2 changes: 1 addition & 1 deletion src/web3py/extensions/fallback.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Any

from web3_multi_provider import FallbackProvider
from src.web3py.extensions.consistency import ProviderConsistencyModule
from src.providers.consistency import ProviderConsistencyModule
from web3 import Web3


Expand Down
12 changes: 10 additions & 2 deletions tests/modules/submodules/consensus/test_reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,11 @@ def test_report_hash(web3, consensus, tx_utils, set_report_account):
def test_report_hash_member_not_in_fast_lane(web3, consensus, caplog):
blockstamp = ReferenceBlockStampFactory.build()
consensus._get_latest_blockstamp = Mock(return_value=blockstamp)
member_info = MemberInfoFactory.build(is_fast_lane=False, current_frame_ref_slot=blockstamp.slot_number - 1)
member_info = MemberInfoFactory.build(
is_fast_lane=False,
current_frame_ref_slot=blockstamp.slot_number - 1,
is_report_member=True,
)
consensus.get_member_info = Mock(return_value=member_info)

consensus._process_report_hash(blockstamp, HexBytes(int.to_bytes(1, 32)))
Expand Down Expand Up @@ -102,7 +106,7 @@ def test_do_not_report_same_hash(consensus, caplog, mock_latest_data):
consensus.get_member_info = Mock(return_value=member_info)

consensus._process_report_hash(blockstamp, HexBytes(int.to_bytes(1, 32)))
assert "Provided hash already submitted" in caplog.messages[-1]
assert "Account already submitted provided hash." in caplog.messages[-1]


# -------- Process report data ---------
Expand Down Expand Up @@ -140,6 +144,7 @@ def test_process_report_data_main_data_submitted(consensus, caplog, mock_latest_
blockstamp = ReferenceBlockStampFactory.build()
report_data = tuple()
report_hash = int.to_bytes(1, 32)
consensus._get_slot_delay_before_data_submit = Mock(return_value=0)

consensus.is_main_data_submitted = Mock(side_effect=[False, True])

Expand All @@ -164,6 +169,7 @@ def test_process_report_data_main_sleep_until_data_submitted(consensus, caplog,

consensus.is_main_data_submitted = Mock(return_value=False)
consensus._get_slot_delay_before_data_submit = Mock(return_value=100)
consensus._submit_report = Mock()

consensus._process_report_data(blockstamp, report_data, report_hash)
assert "Sleep for 100 slots before sending data." in caplog.text
Expand Down Expand Up @@ -203,6 +209,8 @@ def test_process_report_submit_report(consensus, tx_utils, caplog, mock_latest_d
consensus.is_main_data_submitted = Mock(side_effect=main_data_submitted_base)
consensus._get_slot_delay_before_data_submit = Mock(return_value=0)

consensus._submit_report = Mock()

consensus._process_report_data(blockstamp, report_data, report_hash)
assert "Send report data. Contract version: [1]" in caplog.text

Expand Down

0 comments on commit e50088b

Please sign in to comment.