diff --git a/README.md b/README.md index 9440ca9..0438f8f 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,10 @@ Specify validating nodes' master or ephemeral validation keys in the appropriate As this tool is used to monitor the live network, it is not really useful for monitoring reporting mode/Clio servers. ## Warning -This is an early stage project, so expect problems. For example, asyncio does not clean up neatly when exiting using a keyboard interrupt. -This monitoring tool is not intended for solo use in a production environment - please use redundant monitoring for mission-critical infrastructure. +This is an early stage project, so expect problems. +This monitoring tool is not intended for solo use in a production environment - please use redundant monitoring for mission-critical infrastructure. No one who contributed to this code is responsible for your servers. + +By running this code, you agree the code author(s) are not liable for missed notifications or other issues, including, but not limited to, those arising from errors in the code. Be cautious when using webhooks, as messages may be lost due to rate limiting or other factors. @@ -26,6 +28,7 @@ Be cautious when using webhooks, as messages may be lost due to rate limiting or 5. Support Slack & email notifications. 6. Notify validator subscribers if their ephemeral key changes. 7. Write a function to scrub sensitive notification data from logging. +8. Account for rippled errors, like tooBusy. ## Notifications If enabled in `settings.py`, notifications will be sent at the following times: @@ -34,16 +37,17 @@ If enabled in `settings.py`, notifications will be sent at the following times: 3. When a subscribed server or a monitored validator is more than n ledgers (specified in `settings.py`) ahead of or behind the rest of the network 4. (coming later) When latency is dangerously high between monitoring bot and the remote server 5. Administrators can receive heartbeat messages as specified in `settings.py` +6. (coming later) When a validator changes their amendment votes At this time, notifications will not be retried if the monitoring server is unable to reach the API. This functionality can be easily integrated in the future by passing the messages back into the notification_queue. ## Running the bot As written, this code will produce errors with asyncio in Python 3.9. The code is tested and works with 3.10 and 3.11. -1. `git clone https://github.com/crypticrabbit/rippled_monitor.git` -2. `cd rippled_monitor` +1. `git clone https://github.com/jscottbranson/rippled-livenet-monitor.git` +2. `cd rippled-livenet-monitor` 3. `pip install -r requirements.txt` 4. `cp settings_ex.py settings.py` -5. Adjust `settings.py` as needed +5. Adjust `settings.py` 6. (optional) Save Twilio notification credentials as env variables. 7. `python3 main.py` diff --git a/amendments.py b/amendments.py new file mode 100644 index 0000000..a70afef --- /dev/null +++ b/amendments.py @@ -0,0 +1,42 @@ +AMENDMENTS = [ + { + 'id': '0285B7E5E08E1A8E4C15636F0591D87F73CB6A7B6452A932AD72BBC8E5D1CBE3', + 'name': 'fixNFTokenDirV1 (dep)', + }, + { + 'id': '3C43D9A973AA4443EF3FC38E42DD306160FBFFDAB901CD8BAA15D09F2597EB87', + 'name': 'NonFungibleTokensV1 (dep)', + }, + { + 'id': '36799EA497B1369B170805C078AEFE6188345F9B3E324C21E9CA3FF574E3C3D6', + 'name': 'fixNFTokenNegOffer (dep)', + }, + { + 'id': '93E516234E35E08CA689FA33A6D38E103881F8DCB53023F728C307AA89D515A7', + 'name': 'XRPFees', + }, + { + 'id': '75A7E01C505DD5A179DFE3E000A9B6F1EDDEB55A12F95579A23E15B15DC8BE5A', + 'name': 'ImmediateOfferKilled', + }, + { + 'id': '2E2FB9CF8A44EB80F4694D38AADAE9B8B7ADAFD2F092E10068E61C98C4F092B0', + 'name': 'fixUniversalNumber', + }, + { + 'id': 'F1ED6B4A411D8B872E65B9DCB4C8B100375B0DD3D62D07192E011D6D7F339013', + 'name': 'fixTrustLinesToSelf', + }, + { + 'id': '73761231F7F3D94EC3D8C63D91BDD0D89045C6F71B917D1925C01253515A6669', + 'name': 'fixNonFungibleTokensV1_2', + }, + { + 'id': '47C3002ABA31628447E8E9A8B315FAA935CE30183F9A9B86845E469CA2CDC3DF', + 'name': 'DisallowIncoming', + }, + { + 'id': '9178256A980A86CF3D70D0260A7DA6402AAFE43632FDBCB88037978404188871', + 'name': 'OwnerPaysFee', + }, +] diff --git a/process_responses/console_output.py b/process_responses/console_output.py index a205693..d5d1422 100644 --- a/process_responses/console_output.py +++ b/process_responses/console_output.py @@ -132,8 +132,10 @@ async def format_table_server(table): # Base load factor in green if isinstance(server['load_factor'], int) and isinstance(server['load_base'], int): if server['load_factor'] == server['load_base']: + server['load_factor'] = round(server['load_factor'] / server['load_base'], 1) server['load_factor'] = green + str(server['load_factor']) + color_reset else: + server['load_factor'] = round(server['load_factor'] / server['load_base'], 1) server['load_factor'] = red + str(server['load_factor']) + color_reset # Calculate Open Ledger Fee server['load_factor_fee_escalation'] = await fee_calc(server['load_factor_fee_escalation'], server['fee_base'], server['load_base']) @@ -150,7 +152,7 @@ async def print_table_server(table): logging.info("Preparing to print updated server table.") pretty_table = PrettyTable() pretty_table.field_names = [ - "Server Name", "State", "O.L. Fee", "Queue Fee", "Load Factor", + "Server Name", "State", "O.L. Fee", "Queue Fee", "Load Multiplier", "LL Hash", "History", "LL # Tx", "Forked?", "Last Updated", ] table_new = await format_table_server(await copy_stock(table)) @@ -213,7 +215,7 @@ async def print_table_amendments(table_validator, amendments): amendment['name'], len(amendment['supporters']), len(table_validator) - len(amendment['supporters']), - str(round(len(amendment['supporters']) / len(table_validator) * 100, 2)) + '%', + str(round(len(amendment['supporters']) / len(table_validator) * 100, 1)) + '%', supporters, ]) print(pretty_table)