Skip to content

Add EVM HTTP generic collector #66

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
*.out
local*

.idea

# Python
venv
__pycache__
Expand Down
54 changes: 54 additions & 0 deletions src/collectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,3 +446,57 @@ def client_version(self):
def latency(self):
"""Returns connection latency."""
return self.interface.latest_query_latency


class EvmHttpCollector():
"""A collector to fetch information from EVM HTTPS endpoints."""

def __init__(self, url, labels, chain_id, **client_parameters):

self.labels = labels
self.chain_id = chain_id
self.interface = HttpsInterface(url, client_parameters.get('open_timeout'),
client_parameters.get('ping_timeout'))

self._logger_metadata = {
'component': 'EvmHttpCollector',
'url': strip_url(url)
}
self.client_version_payload = {
'jsonrpc': '2.0',
'method': "web3_clientVersion",
'id': 1
}
self.block_height_payload = {
'jsonrpc': '2.0',
'method': "eth_blockNumber",
'id': 1
}

def alive(self):
"""Returns true if endpoint is alive, false if not."""
# Run cached query because we can also fetch client version from this
# later on. This will save us an RPC call per run.
return self.interface.cached_json_rpc_post(
self.client_version_payload) is not None

def block_height(self):
"""Cached query and returns blockheight after converting hex string value to an int"""
result = self.interface.cached_json_rpc_post(self.block_height_payload)

if result and isinstance(result, str) and result.startswith('0x'):
return int(result, 16)
raise ValueError(f"Invalid block height result: {result}")

def client_version(self):
"""Runs a cached query to return client version."""
version = self.interface.cached_json_rpc_post(
self.client_version_payload)
if version is None:
return None
client_version = {"client_version": version}
return client_version

def latency(self):
"""Returns connection latency."""
return self.interface.latest_query_latency
2 changes: 1 addition & 1 deletion src/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def endpoints(self):

def _load_configuration(self):
allowed_providers = self._load_validation_file()
supported_collectors = ('evm', 'cardano', 'conflux', 'solana',
supported_collectors = ('evm', 'evmhttp', 'cardano', 'conflux', 'solana',
'bitcoin', 'doge', 'filecoin', 'starknet', 'aptos',
'tron')

Expand Down
2 changes: 2 additions & 0 deletions src/registries.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ def get_collector_registry(self) -> list:
collector = collectors.AptosCollector
case "tron", "tron":
collector = collectors.TronCollector
case "evmhttp", other: # pylint: disable=unused-variable
collector = collectors.EvmHttpCollector
case "evm", other: # pylint: disable=unused-variable
collector = collectors.EvmCollector
if collector is None:
Expand Down
9 changes: 9 additions & 0 deletions src/test_registries.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,15 @@ def test_get_collector_registry_for_tron(self):
with mock.patch('collectors.TronCollector', new=mock.Mock()) as collector:
helper_test_collector_registry(self, collector)

@mock.patch.dict(os.environ, {
"CONFIG_FILE_PATH": "tests/fixtures/configuration_evmhttp.yaml",
"VALIDATION_FILE_PATH": "tests/fixtures/validation.yaml"
})
def test_get_collector_registry_for_evmhttp(self):
"""Tests that the EVM HTTP collector is called with the correct args"""
self.collector_registry = CollectorRegistry()
with mock.patch('collectors.EvmHttpCollector', new=mock.Mock()) as collector:
helper_test_collector_registry(self, collector)

@mock.patch.dict(os.environ, {
"CONFIG_FILE_PATH": "tests/fixtures/configuration_evm.yaml",
Expand Down
15 changes: 15 additions & 0 deletions src/tests/fixtures/configuration_evmhttp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
blockchain: "Evm"
chain_id: 1234
network_name: "TestNetwork"
network_type: "Testnet"
integration_maturity: "development"
canonical_name: "test-network-testnet"
chain_selector: 121212
collector: "evmhttp"
endpoints:
- url: https://test1.com
provider: TestProvider1
- url: https://test2.com
provider: TestProvider2
- url: https://test3.com
provider: TestProvider3
Loading