commit c4e2dc37f36c99de0da3d985d3251162aa8d1b76
parent 4dfe6be170daf805459b5e72ce08b11516786adb
Author: lash <dev@holbrook.no>
Date: Tue, 5 Apr 2022 11:44:15 +0000
add data filter
Diffstat:
5 files changed, 85 insertions(+), 13 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
@@ -1,3 +1,7 @@
+- 0.3.1
+ * Add data filter
+- 0.3.0
+ * Reimplement on shep/chainsyncer 0.3.0
- 0.2.1
* Implement --keep-alive flag
- 0.2.0
diff --git a/eth_monitor/filters/out.py b/eth_monitor/filters/out.py
@@ -1,6 +1,12 @@
# standard imports
import sys
import logging
+import datetime
+
+# external imports
+from hexathon import (
+ strip_0x,
+ )
# local imports
from .base import RuledFilter
@@ -61,7 +67,18 @@ class OutFilter(RuledFilter):
data = data[:8] + '...'
if len(data) > 0:
data = 'data {}'.format(data)
- s = '{} {} {} {}'.format(self.c, block, tx, data)
+ #s = '{} {} {} {}'.format(self.c, block, tx, data)
+ tx_count = len(block.txs)
+ s = '{} {} block {} {} tx {}/{} {} {}'.format(
+ self.c,
+ datetime.datetime.fromtimestamp(block.timestamp),
+ block.number,
+ strip_0x(block.hash),
+ tx.index,
+ tx_count,
+ strip_0x(tx.hash),
+ data,
+ )
self.w.write(s + '\n')
self.c += 1
diff --git a/eth_monitor/rules.py b/eth_monitor/rules.py
@@ -8,6 +8,36 @@ from chainlib.eth.address import is_same_address
logg = logging.getLogger()
+class RuleMethod:
+
+ def __init__(self, methods, description=None):
+ self.methods = methods
+ self.description = description
+ if self.description == None:
+ self.description = str(uuid.uuid4())
+
+
+ def check(self, sender, recipient, data, tx_hash):
+ if len(self.methods) == 0:
+ return False
+
+ for method in self.methods:
+ l = len(method)
+ if len(method) > len(data):
+ continue
+ if data[:l] == method:
+ logg.debug('tx {} rule {} match in DATA {}'.format(tx_hash, self.description, method))
+ return True
+
+ return False
+
+
+ def __str__(self):
+ return 'Method ' + self.description + ' {}'.format(
+ self.methods,
+ )
+
+
class RuleSimple:
def __init__(self, outputs, inputs, executables, description=None):
@@ -19,18 +49,18 @@ class RuleSimple:
self.executables = executables
- def check(self, sender, recipient, tx_hash):
+ def check(self, sender, recipient, data, tx_hash):
for rule in self.outputs:
if rule != None and is_same_address(sender, rule):
- logg.debug('tx {} rule INCLUDE match in SENDER {}'.format(tx_hash, sender))
+ logg.debug('tx {} rule {} match in SENDER {}'.format(tx_hash, self.description, sender))
return True
for rule in self.inputs:
if rule != None and is_same_address(recipient, rule):
- logg.debug('tx {} rule INCLUDE match in RECIPIENT {}'.format(tx_hash, recipient))
+ logg.debug('tx {} rule {} match in RECIPIENT {}'.format(tx_hash, self.description, recipient))
return True
for rule in self.executables:
if rule != None and is_same_address(recipient, rule):
- logg.debug('tx {} rule INCLUDE match in ExECUTABLE {}'.format(tx_hash, recipient))
+ logg.debug('tx {} rule {} match in EXECUTABLE {}'.format(tx_hash, self.description, recipient))
return True
@@ -57,24 +87,25 @@ class AddressRules:
def include(self, rule):
self.includes.append(rule)
- logg.info('cache filter added EXCLUDE rule {}'.format(rule))
+ logg.info('cache filter added INCLUDE rule {}'.format(rule))
def apply_rules(self, tx):
- return self.apply_rules_addresses(tx.outputs[0], tx.inputs[0], tx.hash)
+ return self.apply_rules_addresses(tx.outputs[0], tx.inputs[0], tx.payload, tx.hash)
- def apply_rules_addresses(self, sender, recipient, tx_hash):
+ # TODO: rename
+ def apply_rules_addresses(self, sender, recipient, data, tx_hash):
v = self.include_by_default
for rule in self.includes:
- if rule.check(sender, recipient, tx_hash):
+ if rule.check(sender, recipient, data, tx_hash):
v = True
logg.info('match in includes rule: {}'.format(rule))
break
for rule in self.excludes:
- if rule.check(sender, recipient, tx_hash):
+ if rule.check(sender, recipient, data, tx_hash):
v = False
logg.info('match in excludes rule: {}'.format(rule))
break
diff --git a/eth_monitor/runnable/sync.py b/eth_monitor/runnable/sync.py
@@ -30,6 +30,7 @@ from eth_monitor.filters.cache import Filter as CacheFilter
from eth_monitor.rules import (
AddressRules,
RuleSimple,
+ RuleMethod,
)
from eth_monitor.filters import RuledFilter
from eth_monitor.filters.out import OutFilter
@@ -61,6 +62,8 @@ argparser.add_argument('--keep-alive', action='store_true', dest='keep_alive', h
argparser.add_argument('--input', default=[], action='append', type=str, help='Add input (recipient) addresses to includes list')
argparser.add_argument('--output', default=[], action='append', type=str, help='Add output (sender) addresses to includes list')
argparser.add_argument('--exec', default=[], action='append', type=str, help='Add exec (contract) addresses to includes list')
+argparser.add_argument('--data', default=[], action='append', type=str, help='Add data strings to include list')
+argparser.add_argument('--x-data', default=[], action='append', dest='xdata', type=str, help='Add data strings to exclude list')
argparser.add_argument('--address', default=[], action='append', type=str, help='Add addresses as input, output and exec to includes list')
argparser.add_argument('--x-input', default=[], action='append', type=str, dest='xinput', help='Add input (recipient) addresses to excludes list')
argparser.add_argument('--x-output', default=[], action='append', type=str, dest='xoutput', help='Add output (sender) addresses to excludes list')
@@ -155,10 +158,23 @@ def setup_address_arg_rules(rules, args):
exclude_outputs.append(address)
exclude_exec.append(address)
- includes = RuleSimple(include_outputs, include_inputs, include_exec)
+ includes = RuleSimple(include_outputs, include_inputs, include_exec, description='INCLUDE')
rules.include(includes)
- excludes = RuleSimple(exclude_outputs, exclude_inputs, exclude_exec)
+ excludes = RuleSimple(exclude_outputs, exclude_inputs, exclude_exec, description='EXCLUDE')
+ rules.exclude(excludes)
+
+ return rules
+
+
+def setup_data_arg_rules(rules, args):
+ include_data = args.data
+ exclude_data = args.xdata
+
+ includes = RuleMethod(include_data, description='INCLUDE')
+ rules.include(includes)
+
+ excludes = RuleMethod(exclude_data, description='EXCLUDE')
rules.exclude(excludes)
return rules
@@ -301,6 +317,10 @@ def main():
block_limit = block_offset
address_rules = AddressRules(include_by_default=args.include_default)
+ address_rules = setup_data_arg_rules(
+ address_rules,
+ args,
+ )
address_rules = setup_address_file_rules(
address_rules,
includes_file=args.includes_file,
diff --git a/setup.cfg b/setup.cfg
@@ -1,6 +1,6 @@
[metadata]
name = eth-monitor
-version = 0.3.0
+version = 0.3.1
description = Monitor and cache transactions using match filters
author = Louis Holbrook
author_email = dev@holbrook.no