add data filter

This commit is contained in:
lash 2022-04-05 11:44:15 +00:00
parent 4dfe6be170
commit c4e2dc37f3
Signed by: lash
GPG Key ID: 21D2E7BB88C2A746
5 changed files with 85 additions and 13 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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