Skip to content

Commit 7c5bbce

Browse files
authored
Add starkware (#15)
1 parent 8ca789e commit 7c5bbce

5 files changed

Lines changed: 103 additions & 17 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Exporter currently supports all EVM-compatible chains. In addition, there is lim
77
- Solana
88
- Bitcoin
99
- Dogecoin
10+
- Filecoin
11+
- Starkware
1012

1113
# Disclaimer
1214
Please note that this tool is in the early development stage and should not be used to influence critical business decisions.

src/collectors/dogecoin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def probe(self, metrics):
4040
logger.error("Health check failed for {}: {}".format(
4141
strip_url(self.https_url), exc))
4242
metrics['ws_rpc_health'].add_metric(self.labels_values, False)
43-
except Exception as e:
43+
except Exception as exc:
4444
logger.error("Health check failed for {}: {}".format(
4545
strip_url(self.https_url), exc))
4646
metrics['ws_rpc_health'].add_metric(self.labels_values, False)

src/collectors/starkware.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from settings import cfg, logger
2+
from helpers import strip_url
3+
from time import perf_counter
4+
import requests
5+
6+
7+
class starkware_collector():
8+
9+
def __init__(self, https_url, provider):
10+
self.labels = [
11+
'websocket_url', 'https_url', 'provider', 'blockchain',
12+
'network_name', 'network_type'
13+
]
14+
self.labels_values = [
15+
https_url, provider, cfg.blockchain, cfg.network_name,
16+
cfg.network_type
17+
]
18+
self.https_url = https_url
19+
20+
def probe(self, metrics):
21+
try:
22+
payload = {
23+
"method": "starknet_blockNumber",
24+
"jsonrpc": "2.0",
25+
"id": 1
26+
}
27+
start = perf_counter()
28+
29+
response = requests.post(self.https_url, json=payload).json()
30+
latency = (perf_counter() - start) * 1000
31+
32+
if response:
33+
metrics['ws_rpc_health'].add_metric(self.labels_values, True)
34+
metrics['ws_rpc_latency'].add_metric(self.labels_values,
35+
latency)
36+
metrics['ws_rpc_block_height'].add_metric(
37+
self.labels_values, response['result'])
38+
else:
39+
logger.error("Bad response from client {}: {}".format(
40+
strip_url(self.https_url), exc))
41+
metrics['ws_rpc_health'].add_metric(self.labels_values, False)
42+
except requests.RequestException as exc:
43+
logger.error("Health check failed for {}: {}".format(
44+
strip_url(self.https_url), exc))
45+
metrics['ws_rpc_health'].add_metric(self.labels_values, False)
46+
except Exception as exc:
47+
logger.error("Health check failed for {}: {}".format(
48+
strip_url(self.https_url), exc))
49+
metrics['ws_rpc_health'].add_metric(self.labels_values, False)

src/exporter.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from collectors.bitcoin import bitcoin_collector
1111
from collectors.dogecoin import doge_collector
1212
from collectors.filecoin import filecoin_collector
13+
from collectors.starkware import starkware_collector
1314
from settings import logger, cfg
1415

1516

@@ -33,6 +34,8 @@ def __init__(self):
3334
self._instantiate_doge()
3435
if cfg.isFilecoin():
3536
self._instantiate_filecoin()
37+
if cfg.isStarkware():
38+
self._instantiate_starkware()
3639

3740
def _instantiate_evm(self):
3841
for item in cfg.endpoints:
@@ -93,6 +96,14 @@ def _instantiate_filecoin(self):
9396
filecoin_collector(item['https_url'], item['provider']))
9497
self.labels = self.collectors[0].labels
9598

99+
def _instantiate_starkware(self):
100+
for item in cfg.endpoints:
101+
logger.info("Initializing starkware node {}".format(
102+
strip_url(item['https_url'])))
103+
self.collectors.append(
104+
starkware_collector(item['https_url'], item['provider']))
105+
self.labels = self.collectors[0].labels
106+
96107
def collect(self):
97108
metrics = {
98109
"ws_rpc_health":

src/settings.py

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,43 +7,56 @@
77
logger = logging.getLogger('exporter')
88
LOGLEVEL = os.environ.get('LOGLEVEL', 'INFO').upper()
99

10-
logging.basicConfig(level=LOGLEVEL,
11-
format="{'thread': '%(threadName)s', 'level': '%(levelname)s', 'message': '%(message)s'}")
10+
logging.basicConfig(
11+
level=LOGLEVEL,
12+
format=
13+
"{'thread': '%(threadName)s', 'level': '%(levelname)s', 'message': '%(message)s'}"
14+
)
1215

1316

1417
class configuration():
1518

1619
def __init__(self, config_file_path: str, validation_file_path: str):
17-
self.allowed_providers = self._load_validation_file(validation_file_path)
20+
self.allowed_providers = self._load_validation_file(
21+
validation_file_path)
1822
self.configuration = self._load_configuration_file(config_file_path)
1923
self.blockchain = self.configuration['blockchain']
2024
# Load chain_id only if evm compatible collector
21-
if self.configuration['collector'] not in ['cardano', 'solana', 'bitcoin', 'doge' , 'filecoin']:
25+
if self.configuration['collector'] not in [
26+
'cardano', 'solana', 'bitcoin', 'doge', 'filecoin', 'starkware'
27+
]:
2228
try:
2329
self.chain_id = self.configuration['chain_id']
2430
except KeyError:
25-
logger.error("This chain requires chain_id configuration, but it is not provided.")
31+
logger.error(
32+
"This chain requires chain_id configuration, but it is not provided."
33+
)
2634
self.network_type = self.configuration['network_type']
2735
self.network_name = self.configuration['network_name']
2836
self.endpoints = self.configuration['endpoints']
2937
try:
30-
self.open_timeout = self.configuration['connection_parameters']['open_timeout']
38+
self.open_timeout = self.configuration['connection_parameters'][
39+
'open_timeout']
3140
except KeyError:
3241
self.open_timeout = 3
3342
try:
34-
self.close_timeout = self.configuration['connection_parameters']['close_timeout']
43+
self.close_timeout = self.configuration['connection_parameters'][
44+
'close_timeout']
3545
except KeyError:
3646
self.close_timeout = 1
3747
try:
38-
self.response_timeout = self.configuration['connection_parameters']['response_timeout']
48+
self.response_timeout = self.configuration[
49+
'connection_parameters']['response_timeout']
3950
except KeyError:
4051
self.response_timeout = 3
4152
try:
42-
self.ping_interval = self.configuration['connection_parameters']['ping_interval']
53+
self.ping_interval = self.configuration['connection_parameters'][
54+
'ping_interval']
4355
except KeyError:
4456
self.ping_interval = 6
4557
try:
46-
self.ping_timeout = self.configuration['connection_parameters']['ping_timeout']
58+
self.ping_timeout = self.configuration['connection_parameters'][
59+
'ping_timeout']
4760
except KeyError:
4861
self.ping_timeout = 2
4962

@@ -85,6 +98,9 @@ def isDoge(self) -> bool:
8598
def isFilecoin(self) -> bool:
8699
return self.configuration['collector'] == "filecoin"
87100

101+
def isStarkware(self) -> bool:
102+
return self.configuration['collector'] == "starkware"
103+
88104
def _load_configuration_file(self, path):
89105
logger.info('Loading {}'.format(path))
90106
configuration_file_schema = Schema({
@@ -97,7 +113,10 @@ def _load_configuration_file(self, path):
97113
'network_type':
98114
And(str, lambda s: s in ('Testnet', 'Mainnet')),
99115
'collector':
100-
And(str, lambda s: s in ('evm', 'cardano', 'conflux', 'solana', 'bitcoin', 'doge', 'filecoin')),
116+
And(
117+
str, lambda s: s in
118+
('evm', 'cardano', 'conflux', 'solana', 'bitcoin', 'doge',
119+
'filecoin', 'starkware')),
101120
Optional('connection_parameters'): {
102121
Optional('open_timeout'): And(int),
103122
Optional('close_timeout'): And(int),
@@ -106,9 +125,12 @@ def _load_configuration_file(self, path):
106125
Optional('ping_timeout'): And(int),
107126
},
108127
'endpoints': [{
109-
Optional('ws_url'): And(str),
110-
Optional('https_url'): And(str),
111-
'provider': And(str, lambda s: s in self.allowed_providers)
128+
Optional('ws_url'):
129+
And(str),
130+
Optional('https_url'):
131+
And(str),
132+
'provider':
133+
And(str, lambda s: s in self.allowed_providers)
112134
}]
113135
})
114136
try:
@@ -129,11 +151,13 @@ def _load_file(self, path):
129151
logger.info('Validating {}'.format(path))
130152
return file
131153
except IOError as e:
132-
logger.error('Problem with configuration file detected: {}'.format(e))
154+
logger.error(
155+
'Problem with configuration file detected: {}'.format(e))
133156
exit(1)
134157

135158

136159
cfg_file_path = os.getenv('CONFIG_FILE_PATH', default='/config/config.yml')
137-
valid_file_path = os.getenv('VALIDATION_FILE_PATH', default='/config/validation.yml')
160+
valid_file_path = os.getenv('VALIDATION_FILE_PATH',
161+
default='/config/validation.yml')
138162

139163
cfg = configuration(cfg_file_path, valid_file_path)

0 commit comments

Comments
 (0)