Skip to content
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

Support monitoring of blockchain forks #302

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5510d0d
Tests: Add block found tests (#278)
kanasite Aug 15, 2021
8c0a419
Parsers: Fix block parser (#293)
kanasite Oct 4, 2021
5ef400b
Initial support for blockchain forks.
guydavis Oct 12, 2021
276c271
Correct coin symbol in daily summary.
guydavis Oct 13, 2021
604884d
Merge branch 'forks' into dev
guydavis Oct 13, 2021
5323fa5
Merge pull request #1 from guydavis/dev
guydavis Oct 13, 2021
35a04a6
Correct coin symbol in daily summary.
guydavis Oct 14, 2021
7d6d296
Merge pull request #2 from guydavis/forks
guydavis Oct 14, 2021
6acf6da
Fix formatting of symbol.
guydavis Oct 16, 2021
3c7c8af
Merge pull request #3 from guydavis/forks
guydavis Oct 16, 2021
84b69c0
Bugfix: Check for non MacOS operating systems before running apt-get
Connor-Knabe Oct 18, 2021
301ccd1
Refactoring.
guydavis Oct 22, 2021
6377133
Merge pull request #4 from guydavis/forks
guydavis Oct 22, 2021
0f3b07a
Add Pushcut notifier as an alternative to Pushover (#304)
Connor-Knabe Oct 27, 2021
aa1308d
Add IFTTT notifying functionality (#305)
Connor-Knabe Oct 27, 2021
972797f
Config: Toggle notifications for plot increases and decreases (#307)
Connor-Knabe Oct 30, 2021
b613633
Merge branch 'martomi:dev' into dev
guydavis Nov 6, 2021
a480c8c
Merge pull request #5 from guydavis/dev
guydavis Nov 6, 2021
599dc69
Staicoin is 1000x for mojos.
guydavis Nov 6, 2021
45a564e
Cryptodoge mojos factor.
guydavis Nov 15, 2021
a3179aa
SHIBgreen
guydavis Dec 7, 2021
d3ee7c3
Staicoin renamed their blockchain to 'Stai'.
guydavis Jan 20, 2022
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
22 changes: 22 additions & 0 deletions INTEGRATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ Test with:
PUSHOVER_API_TOKEN=<api_token> PUSHOVER_USER_KEY=<user_key> python3 -m unittest tests.notifier.test_pushover_notifier
```

## Pushcut

[Pushcut](https://pushcut.io/) is available for both Android and iOS. High priority notifications can be configured
from the Pushcut app to overwrite any Silence or Do-Not-Disturb modes on your phone and sound a loud alarm at any time
of the day to make you aware of any issues in a timely manner.

Test with:

```
PUSHCUT_API_TOKEN=<api_token> PUSHCUT_NOTIFICATION_NAME=<notification_name> python3 -m unittest tests.notifier.test_pushcut_notifier
```

## SMTP / E-Mail

This integration uses SMTP to send an e-mail to a designated address. Alert information is sent in the subject line of
Expand Down Expand Up @@ -135,6 +147,16 @@ Test with:
GRAFANA_BASE_URL=<webhook_url> GRAFANA_API_TOKEN=<api_token> python3 -m unittest tests.notifier.test_grafana_notifier
```

## Ifttt

[Ifttt](https://ifttt.com/) is available for both Android and iOS. Can be used to send push notifications and to integrate with various other APIs. For example if you wanted to flash a Philips hue lightbulb when you have a Chiadog notification.

Test with:

```
IFTTT_API_TOKEN=<api_token> IFTTT_WEBHOOK_NAME=<user_key> python3 -m unittest tests.notifier.test_ifttt_notifier
```

## Unit Testing on Windows

When running unit tests on Windows, you will want to use PowerShell to set environment variables like this:
Expand Down
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ helps with automated monitoring and sends you a mobile notification in case some
| ------------- | ------------- | ------|
| Harvester | Your harvester appears to be offline! No events for the past 400 seconds. | HIGH |
| Harvester | Disconnected HDD? The total plot count decreased from 100 to 40. | HIGH |
| Harvester | Connected HDD? The total plot count increased from 0 to 42. | LOW |
| Harvester | Experiencing networking issues? Harvester did not participate in any challenge for 120 seconds. It's now working again. | NORMAL |
| Harvester | Seeking plots took too long: 21.42 seconds! | NORMAL |
| Full Node | Experiencing networking issues? Skipped 42 signage points! | NORMAL |
Expand Down Expand Up @@ -49,13 +50,16 @@ You may use one (or more) of the following integrations to receive notifications
| Integration | Advantages | Cost |
| ------------- | ------------- | ------|
| [Pushover](https://pushover.net/) | High priority notifications that can override your phone's silent mode. | $5 one time purchase after 30 day trial. |
| [Pushcut](https://pushcut.io/) | Alternative to Pushover |
| E-mail | You probably already have an email. No additional apps. | Free |
| Slack | Quick & easy setup. | Free |
| Discord | Quick & easy setup. | Free |
| Telegram | Quick & easy setup. | Free |
| Shell script (beta) | Execute anything in your own script. | Free |
| MQTT | Well-suited for Home Automation. | Free |
| Grafana | For hardware monitoring. | Free |
| [Ifttt](https://ifttt.com/) | Can be used to send push notifications or to do other API integrations depending on incoming data. | Free |


For detailed guide on how to test and configure, please refer to [INTEGRATIONS.md](INTEGRATIONS.md).

Expand Down Expand Up @@ -202,6 +206,26 @@ for [chiadog-docker](https://github.com/ajacobson/chiadog-docker).
Alternatively, [as suggested here](https://github.com/martomi/chiadog/issues/24) you can run `chiadog` from a unix user
with limited permissions.

## Running `chiadog` against a blockchain fork

Despite the name, it's possible to monitor [blockchain forks](https://xchforks.com/), such as Flax, N-Chain, Chives, HDDCoin, Flora, and others. In the [config.yml](config.yml), change the following:
* coin_name: 'chia' --> A lower-cased string of the coin's name.
* coin_symbol: 'xch' --> A lower-cased string of the coin's symbol, often 3-letters long.

Then in the next section, set the log line prefix used for matching into the blockchain's debug.log:
```
chia_logs:
file_log_consumer:
...
prefix: 'chia'
...
```
While the Chia blockchain's logline prefix is 'chia', Flax's is 'flax', etc, some chains are different:
* N-Chain: 'chia' -> They never bothered to change it.
* Flora: prefix: 'flora_proxy: chia' -> They added 'flora_proxy: ' instead.

*DISCLAIMER*: As every blockchain fork is different from the main Chia blockchain, often to differing amounts, there is no guarantee every single fork can be monitored by Chiadog. Raise an [issue](https://github.com/martomi/chiadog/issues) for problems with a particular fork.

# Contributing

Contributions are always welcome! Please refer to [CONTRIBUTING](CONTRIBUTING.md) documentation.
35 changes: 35 additions & 0 deletions config-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
# instances monitoring multiple harvesters
notification_title_prefix: 'Chia'
log_level: INFO
coin_name: 'chia'
coin_symbol: 'xch'

# Only one consumer can be enabled at a time, you can
# delete the section for the consumer which you aren't using
# For Windows file path needs to be absolute.
chia_logs:
file_log_consumer:
enable: true
prefix: 'chia'
file_path: '~/.chia/mainnet/log/debug.log'
network_log_consumer:
enable: false
Expand Down Expand Up @@ -44,20 +47,35 @@ notifier:
enable: false
daily_stats: true
wallet_events: true
decreasing_plot_events: true
increasing_plot_events: false
credentials:
api_token: 'dummy_token'
user_key: 'dummy_key'
pushcut:
enable: false
daily_stats: true
wallet_events: true
decreasing_plot_events: true
increasing_plot_events: false
credentials:
api_token: 'dummy_token'
user_key: 'dummy_key'
telegram:
enable: false
daily_stats: true
wallet_events: true
decreasing_plot_events: true
increasing_plot_events: false
credentials:
bot_token: 'dummy_bot_token'
chat_id: 'dummy_chat_id'
smtp:
enable: false
daily_stats: true
wallet_events: true
decreasing_plot_events: true
increasing_plot_events: false
credentials:
sender: 'chia@example.com'
sender_name: 'chiadog'
Expand All @@ -70,23 +88,31 @@ notifier:
enable: false
daily_stats: true
wallet_events: true
decreasing_plot_events: true
increasing_plot_events: false
script_path: 'tests/test_script.sh'
discord:
enable: false
daily_stats: true
wallet_events: true
decreasing_plot_events: true
increasing_plot_events: false
credentials:
webhook_url: 'https://discord.com/api/webhooks/...'
slack:
enable: false
daily_stats: true
wallet_events: true
decreasing_plot_events: true
increasing_plot_events: false
credentials:
webhook_url: 'https://hooks.slack.com/services/...'
mqtt:
enable: false
daily_stats: true
wallet_events: true
decreasing_plot_events: true
increasing_plot_events: false
topic: chia/chiadog/alert
qos: 1
retain: false
Expand All @@ -102,3 +128,12 @@ notifier:
api_token: ''
dashboard_id: -1
panel_id: -1
ifttt:
enable: false
daily_stats: false
wallet_events: false
decreasing_plot_events: true
increasing_plot_events: false
credentials:
api_token: 'dummy_token'
webhook_name: 'dummy_key'
11 changes: 6 additions & 5 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ then
exit 1
fi

# Check existence of required python build packages
if ! package_installed libpython3-dev || ! package_installed build-essential; then
sudo apt-get update
sudo apt-get install libpython3-dev build-essential -y
# Check existence of required python build packages for non-MacOS
if [[ "$OSTYPE" != "darwin"* ]]; then
if ! package_installed libpython3-dev || ! package_installed build-essential; then
sudo apt-get update
sudo apt-get install libpython3-dev build-essential -y
fi
fi

# Create virtual environment
python3 -m venv venv

Expand Down
5 changes: 3 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def init(config:Config):

# Create log consumer based on provided configuration
chia_logs_config = config.get_chia_logs_config()
log_consumer = create_log_consumer_from_config(chia_logs_config)
log_consumer = create_log_consumer_from_config(chia_logs_config, config.get_coin_name(), config.get_coin_symbol())
if log_consumer is None:
exit(0)

Expand All @@ -73,7 +73,8 @@ def init(config:Config):
notify_manager = NotifyManager(config=config, keep_alive_monitor=keep_alive_monitor)

# Stats manager accumulates stats over 24 hours and sends a summary each day
stats_manager = StatsManager(config=config.get_daily_stats_config(), notify_manager=notify_manager)
stats_manager = StatsManager(config=config.get_daily_stats_config(), notify_manager=notify_manager,
symbol=config.get_coin_symbol())

# Link stuff up in the log handler
# Pipeline: Consume -> Handle -> Notify
Expand Down
4 changes: 2 additions & 2 deletions src/chia_log/handlers/block_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class BlockHandler(LogHandler):
that are evaluated for each event.
"""

def __init__(self):
self._parser = BlockParser()
def __init__(self, prefix):
self._parser = BlockParser(prefix)
self._cond_checkers: List[BlockConditionChecker] = [FoundBlocks()]

def handle(self, logs: str, stats_manager: Optional[StatsManager] = None) -> List[Event]:
Expand Down
22 changes: 20 additions & 2 deletions src/chia_log/handlers/condition_checkers/non_decreasing_plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,28 @@ def __init__(self):
# When copying plots it's common that plots decrease by 1 temporarily
# by setting the default threshold to 2, we can avoid false alarms
self._decrease_warn_threshold = 2
self._increase_info_threshold = 2

def check(self, obj: HarvesterActivityMessage) -> Optional[Event]:
event = None
if obj.total_plots_count > self._max_farmed_plots:
logging.info(f"Detected new plots. Farming with {obj.total_plots_count} plots.")
message = (
f"Connected HDD? The total plot count increased from "
f"{self._max_farmed_plots} to {obj.total_plots_count}."
)
logging.info(message)

if obj.total_plots_count - self._max_farmed_plots > self._increase_info_threshold:
event = Event(
type=EventType.PLOTINCREASE,
priority=EventPriority.LOW,
service=EventService.HARVESTER,
message=message,
)

self._max_farmed_plots = obj.total_plots_count

event = None
if obj.total_plots_count < self._max_farmed_plots:
if self._max_farmed_plots - obj.total_plots_count < self._decrease_warn_threshold:
logging.info(
Expand All @@ -40,7 +55,10 @@ def check(self, obj: HarvesterActivityMessage) -> Optional[Event]:
)
logging.warning(message)
event = Event(
type=EventType.USER, priority=EventPriority.HIGH, service=EventService.HARVESTER, message=message
type=EventType.PLOTDECREASE,
priority=EventPriority.HIGH,
service=EventService.HARVESTER,
message=message,
)

# Update max plots to prevent repeated alarms
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@


class WalletAddedCoinStats(WalletAddedCoinConsumer, StatAccumulator):
def __init__(self):
def __init__(self, symbol):
self._last_reset_time = datetime.now()
self._total_added_mojos = 0
self.symbol = symbol

def reset(self):
self._last_reset_time = datetime.now()
Expand All @@ -20,4 +21,4 @@ def consume(self, obj: WalletAddedCoinMessage):
def get_summary(self) -> str:
chia_coins = self._total_added_mojos / 1e12
xch_string = f"{chia_coins:.12f}".rstrip("0").rstrip(".")
return f"Received ☘️: {xch_string} XCH"
return f"Received ☘️: {xch_string} {self.symbol.upper()}"
4 changes: 2 additions & 2 deletions src/chia_log/handlers/daily_stats/stats_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class StatsManager:
with a summary from all stats that have been collected for the past 24 hours.
"""

def __init__(self, config: dict, notify_manager: NotifyManager):
def __init__(self, config: dict, notify_manager: NotifyManager, symbol: str):
self._enable = config.get("enable", False)
self._notify_time = self._parse_notify_time(config.get("time_of_day", "21:00"))
self._frequency_hours = config.get("frequency_hours", 24)
Expand All @@ -48,7 +48,7 @@ def __init__(self, config: dict, notify_manager: NotifyManager):
logging.info("Enabled stats for daily notifications")
self._notify_manager = notify_manager
self._stat_accumulators = [
WalletAddedCoinStats(),
WalletAddedCoinStats(symbol=symbol),
FoundProofStats(),
FoundPartialStats(),
FoundBlockStats(),
Expand Down
4 changes: 2 additions & 2 deletions src/chia_log/handlers/finished_signage_point_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class FinishedSignagePointHandler(LogHandler):
that are evaluated for each event.
"""

def __init__(self):
self._parser = FinishedSignagePointParser()
def __init__(self, prefix):
self._parser = FinishedSignagePointParser(prefix)
self._cond_checkers: List[FinishedSignageConditionChecker] = [NonSkippedSignagePoints()]

def handle(self, logs: str, stats_manager: Optional[StatsManager] = None) -> List[Event]:
Expand Down
4 changes: 2 additions & 2 deletions src/chia_log/handlers/harvester_activity_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ class HarvesterActivityHandler(LogHandler):
ensure that farming is going smoothly.
"""

def __init__(self):
self._parser = HarvesterActivityParser()
def __init__(self, prefix):
self._parser = HarvesterActivityParser(prefix)
self._cond_checkers: List[HarvesterConditionChecker] = [
TimeSinceLastFarmEvent(),
NonDecreasingPlots(),
Expand Down
7 changes: 4 additions & 3 deletions src/chia_log/handlers/wallet_added_coin_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ class WalletAddedCoinHandler(LogHandler):
receiving XCH and creates user notifications.
"""

def __init__(self):
self._parser = WalletAddedCoinParser()
def __init__(self, prefix, symbol):
self._parser = WalletAddedCoinParser(prefix)
self.symbol = symbol

def handle(self, logs: str, stats_manager: Optional[StatsManager] = None) -> List[Event]:
events = []
Expand All @@ -36,7 +37,7 @@ def handle(self, logs: str, stats_manager: Optional[StatsManager] = None) -> Lis
type=EventType.USER,
priority=EventPriority.LOW,
service=EventService.WALLET,
message=f"Cha-ching! Just received {xch_string} XCH ☘️",
message=f"Cha-ching! Just received {xch_string} {self.symbol.upper()} ☘️",
)
)

Expand Down
Loading