taint

Crypto forensics for private use
git clone git://git.defalsify.org/taint.git
Log | Files | Refs | LICENSE

commit eb2c5f7af7abd94f35c126a8511aba4f96c51239
parent 335f62adfc1e00b38c73141ed89dfaa40580f36e
Author: nolash <dev@holbrook.no>
Date:   Fri, 16 Apr 2021 21:12:44 +0200

Add data log, cache state save and load

Diffstat:
Mtaint/cache.py | 6+++---
Mtaint/crypto.py | 3+++
Mtaint/store/file.py | 2+-
Mtaint/taint.py | 36+++++++++++++++++++++++++++++++++---
Mtests/test_interface.py | 19++++++++++++++-----
5 files changed, 54 insertions(+), 12 deletions(-)

diff --git a/taint/cache.py b/taint/cache.py @@ -156,11 +156,11 @@ class Cache(Salter): return bb + b - @staticmethod - def from_serialized(chain_spec, b): + @classmethod + def from_serialized(cls, chain_spec, b): cursor = len(b)-32 bloom = CacheBloom.from_serialized(b[:cursor]) - c = Cache(chain_spec, bloom.bits_size, cache_bloom=bloom) + c = cls(chain_spec, bloom.bits_size, cache_bloom=bloom) (c.first_block_height, c.first_tx_index) = from_index(b[cursor:cursor+16]) cursor += 16 diff --git a/taint/crypto.py b/taint/crypto.py @@ -22,3 +22,6 @@ class Salter: h.update(self.ionized_salt) return h.digest() + + def root_key(self): + return self.ionized_salt diff --git a/taint/store/file.py b/taint/store/file.py @@ -37,7 +37,7 @@ class FileStore: b = b'' c = -1 while c != 0: - d = f.read(1024) + d = f.read(4096) c = len(d) b += d diff --git a/taint/taint.py b/taint/taint.py @@ -4,6 +4,7 @@ from hexathon import strip_0x # local imports from .cache import Cache from .account import Account +from .crypto import Salter class Tainter(Cache): @@ -48,10 +49,39 @@ class Tainter(Cache): def save(self): for account in self.subjects.values(): self.store.put(account.account, account.serialize()) + self.store.put(self.root_key(), self.serialize()) + + + def load_account(self, k, label=None): + try: + b = self.store.get(k) + except FileNotFoundError: + return None + return Account.from_serialized(b, self.chain_spec, label) def load_subject(self, k, label=None): - b = self.store.get(k) - a = Account.from_serialized(b, self.chain_spec, label) - self.subjects[k] = a + a = self.load_account(k, label) + if a == None: + return False + self.add_subject(a) + return True + + + def load_object(self, k, label=None): + a = self.load_account(k, label) + if a == None: + return False + self.add_object(a) return True + + + @staticmethod + def load(store, chain_spec, result_handler=None): + a = Salter(chain_spec) + b = store.get(a.root_key()) + c = Tainter.from_serialized(chain_spec, b) + c.store = store + c.result_handler = result_handler + return c + diff --git a/tests/test_interface.py b/tests/test_interface.py @@ -16,20 +16,29 @@ class TestInterface(TestBase): c = Tainter(self.chain_spec, self.bits_size, store=self.store) c.add_subject(self.alice) c.add_subject(self.bob) + block_height = 42 + tx_index = 13 + c.add_tx(self.alice.account, self.bob.account, block_height, tx_index) c.save() - for k in os.listdir(self.session_data_dir): - self.assertIn(bytes.fromhex(k), c.subjects) - + stored = os.listdir(self.session_data_dir) + self.assertEqual(len(stored), 3) + self.assertIn(self.alice.account.hex(), stored) + self.assertIn(self.bob.account.hex(), stored) + self.assertIn(c.root_key().hex(), stored) c = Tainter(self.chain_spec, self.bits_size, store=self.store) r = c.load_subject(self.alice.account) self.assertTrue(r) - r = c.load_subject(self.bob.account) + r = c.load_object(self.bob.account) self.assertTrue(r) self.assertTrue(self.alice.is_same(c.subjects[self.alice.account])) - self.assertTrue(self.bob.is_same(c.subjects[self.bob.account])) + self.assertTrue(self.bob.is_same(c.objects[self.bob.account])) + self.assertFalse(c.have(block_height, tx_index)) + + c = Tainter.load(self.store, self.chain_spec) + self.assertTrue(c.have(block_height, tx_index)) if __name__ == '__main__':