def test_two_trees_with_clear(): db = RefcountDB(EphemDB()) NODES = 60 t1 = pruning_trie.Trie(db) t2 = pruning_trie.Trie(db) db.ttl = NODES // 4 for i in range(NODES): t1.update(to_string(i), to_string(i)) if i < NODES // 2: t2.update(to_string(i), to_string(i)) db.commit_refcount_changes(i) db.cleanup(i) t1.clear_all() db.cleanup(NODES) assert t2.to_dict() == { to_string(i): to_string(i) for i in range(NODES // 2) } for i in range(NODES // 2): t2.delete(to_string(i)) db.commit_refcount_changes(NODES + i) db.cleanup(NODES + i) for i in range(NODES // 4): db.cleanup(NODES + NODES // 2 + i) assert len(db.kv) == 0
def test_two_trees(): db = RefcountDB(EphemDB()) NODES = 60 t1 = pruning_trie.Trie(db) t2 = pruning_trie.Trie(db) db.ttl = 0 for i in range(NODES): t1.update(to_string(i), to_string(i)) if i < NODES // 2: t2.update(to_string(i), to_string(i)) db.commit_refcount_changes(i) db.cleanup(i) check_db_tightness([t1, t2], db) for i in range(NODES): sys.stderr.write('clearing: %d\n' % i) t1.delete(to_string(NODES - 1 - i)) db.commit_refcount_changes(NODES + i) db.cleanup(NODES + i) check_db_tightness([t1, t2], db) assert t2.to_dict() == { to_string(i): to_string(i) for i in range(NODES // 2) } for i in range(NODES // 2): t2.delete(to_string(i)) db.commit_refcount_changes(NODES * 2 + i) db.cleanup(NODES * 2 + i) check_db_tightness([t1, t2], db) assert len(db.kv) == 0
def test_basic_pruning(): db = RefcountDB(EphemDB()) NODES = 60 t = pruning_trie.Trie(db) db.ttl = 0 db.logging = True for i in range(NODES): t.update(to_string(i), to_string(i)) db.commit_refcount_changes(0) db.cleanup(0) check_db_tightness([t], db) for i in range(NODES): t.update(to_string(i), to_string(i**3)) db.commit_refcount_changes(0) db.cleanup(0) check_db_tightness([t], db) for i in range(NODES): t.delete(to_string(i)) db.commit_refcount_changes(0) db.cleanup(0) check_db_tightness([t], db) assert len(t.to_dict()) == 0 assert len(db.kv) == 0
def test_deep_inner_branch_deletion(): db = RefcountDB(EphemDB()) db.logging = True db.ttl = 1 t1 = pruning_trie.Trie(db) t1.update(b'etherdogecoin', b'\x33' * 50) t1.update(b'etherdogelot', b'\x44' * 50) t1.delete(b'etherhouse') t1.delete(b'etherhouse') t1.delete(b'etherhouse') t1.delete(b'etherhouse')
def test_clear(): db = RefcountDB(EphemDB()) NODES = 60 t = pruning_trie.Trie(db) db.ttl = 0 for i in range(NODES): t.update(to_string(i), to_string(i)) db.commit_refcount_changes(i) db.cleanup(i) t.clear_all() db.commit_refcount_changes(NODES) db.cleanup(NODES) assert len(db.kv) == 0
def run_test(name): logger.debug('testing %s' % name) t = trie.Trie(EphemDB()) data = load_tests()[name] for k in data['in']: logger.debug('updating with (%s, %s)' % (k, k)) k = to_string(k) t.update(k, k) for point, prev, nxt in data['tests']: assert to_string(nxt) == (t.next(point) or b'') assert to_string(prev) == (t.prev(point) or b'')
def test_block_18315_changes(): pre = {} toadd = [ [ '0x0000000000000000000000000000000000000000000000000000000000000000', '0xf9e88bc2b3203e764fe67b4d0f4171b7756117c8' ], [ '0x0000000000000000000000000000000000000000000000000000000000000001', '0x' ], [ '0x0000000000000000000000000000000000000000000000000000000000000002', '0x' ], ] db = RefcountDB(EphemDB()) db.logging = True NODES = 60 t1 = pruning_trie.Trie(db) t2 = pruning_trie.Trie(db) db.ttl = NODES * 2 c = 0 for k, v in pre.items(): triekey = utils.sha3(utils.zpad(k[2:].decode('hex'), 32)) t1.update(triekey, rlp.encode(v[2:].decode('hex'))) t2.update(triekey, rlp.encode(v[2:].decode('hex'))) db.commit_refcount_changes(c) db.cleanup(c) c += 1 sys.stderr.write('##############################\n') print(utils.encode_hex(t1.root_hash)) print(t1.to_dict()) for k, v in toadd: sys.stderr.write('kv: %s %s\n' % (k, v)) triekey = utils.sha3(utils.zpad(utils.decode_hex(k[2:]), 32)) if v == '0x': t1.delete(triekey) else: t1.update(triekey, rlp.encode(utils.decode_hex(v[2:]))) db.commit_refcount_changes(c) db.cleanup(c) c += 1 t1.clear_all() db.commit_refcount_changes(c) for i in range(db.ttl + 1): db.cleanup(c) c += 1 t3 = pruning_trie.Trie(db) t3.root_hash = t2.root_hash print(t3.to_dict())
def __init__(self, genesis): env = Env(EphemDB(), konfig) if not genesis: genesis = mk_genesis_data(env) if 'config' in genesis: if 'homesteadBlock' in genesis['config']: env.config['HOMESTEAD_FORK_BLKNUM'] = int(genesis['config']['homesteadBlock']) env.config['DAO_FORK_BLKNUM'] = int(genesis['config']['homesteadBlock']) env.config['ANTI_DOS_FORK_BLKNUM'] = int(genesis['config']['homesteadBlock']) env.config['SPURIOUS_DRAGON_FORK_BLKNUM'] = int(genesis['config']['homesteadBlock']) self.state = state_from_genesis_declaration(genesis, env) initialize_genesis_keys(self.state, Block(self.state.prev_headers[0], [], []))
def test_two_tries_with_small_root_node(): db = RefcountDB(EphemDB()) db.logging = True db.ttl = 1 t1 = pruning_trie.Trie(db) t2 = pruning_trie.Trie(db) t1.update(b'3', b'5') t2.update(b'3', b'5') t1.delete(b'3') db.commit_refcount_changes(0) db.cleanup(0) db.cleanup(1) db.cleanup(2) print(db.kv) print(t2.to_dict())
def test_insert_delete(): for a in (5, 15, 60): db = RefcountDB(EphemDB()) NODES = a t1 = pruning_trie.Trie(db) db.ttl = 0 db.logging = True for i in range(NODES): t1.update(to_string(i), to_string(i)) db.commit_refcount_changes(i) db.cleanup(i) check_db_tightness([t1], db) for i in range(NODES): t1.delete(to_string(NODES - 1 - i)) db.commit_refcount_changes(NODES + i) db.cleanup(NODES + i) check_db_tightness([t1], db) assert len(db.kv) == 0
def test_trie_transfer(): db = RefcountDB(EphemDB()) NODES = 60 t1 = pruning_trie.Trie(db) db.ttl = NODES * 2 for i in range(NODES): t1.update(to_string(i), to_string(i)) db.commit_refcount_changes(i) db.cleanup(i) t2 = pruning_trie.Trie(db) t2.root_hash = t1.root_hash assert t2.to_dict() == {to_string(i): to_string(i) for i in range(NODES)} for i in range(NODES): t2.delete(to_string(i)) db.commit_refcount_changes(NODES + i) db.cleanup(NODES + i) for i in range(NODES * 2): db.cleanup(2 * NODES + i) assert len(db.kv) == 0
def test_shared_prefix(): db = RefcountDB(EphemDB()) db.logging = True db.ttl = 1 t1 = pruning_trie.Trie(db) t2 = pruning_trie.Trie(db) t1.update(b'dogecoin', b'\x33' * 50) t1.update(b'dogelot', b'\x44' * 50) t2.update(b'dogecoin', b'\x33' * 50) t2.update(b'dogelot', b'\x44' * 50) print(db.kv) t1.delete(b'dogecoin') t1.delete(b'dogelot') print(db.kv) db.commit_refcount_changes(0) db.cleanup(0) db.cleanup(1) db.cleanup(2) print(db.kv) print(t2.to_dict())
def test_delayed_pruning(): NODES = 60 db = RefcountDB(EphemDB()) t = pruning_trie.Trie(db) db.ttl = NODES // 4 for i in range(NODES): t.update(to_string(i), to_string(i)) db.commit_refcount_changes(i) db.cleanup(i) for i in range(NODES): t.update(to_string(i), to_string(i**3)) db.commit_refcount_changes(i + NODES) db.cleanup(i + NODES) for i in range(NODES): t.delete(to_string(i)) db.commit_refcount_changes(i + NODES * 2) db.cleanup(i + NODES * 2) for i in range(NODES // 4): db.cleanup(i + NODES * 3) assert len(t.to_dict()) == 0 assert len(db.kv) == 0
def test_revert_deletes(): db = RefcountDB(EphemDB()) NODES = 60 t1 = pruning_trie.Trie(db) db.ttl = NODES * 2 for i in range(NODES): t1.update(to_string(i), to_string(i)) db.commit_refcount_changes(i) db.cleanup(i) x = t1.root_hash for i in range(NODES): t1.delete(to_string(i)) db.commit_refcount_changes(NODES + i) db.cleanup(NODES + i) for i in range(NODES * 2 - 1, NODES - 1, -1): db.revert_refcount_changes(i) for i in range(NODES * 2): db.cleanup(NODES + i) db.revert_refcount_changes(i) t1.root_hash = x assert t1.to_dict() == {to_string(i): to_string(i) for i in range(NODES)}
def test_block_18503_changes(): pre = {'0x0c': '0x29d33c02a200937995e632c4597b4dca8e503978'} toadd = [ ['0x', '0x09'], ] db = RefcountDB(EphemDB()) db.logging = True NODES = 60 t1 = pruning_trie.Trie(db) t2 = pruning_trie.Trie(db) db.ttl = NODES * 2 c = 0 for k, v in pre.items(): triekey = utils.sha3(utils.zpad(utils.decode_hex(k[2:]), 32)) t1.update(triekey, rlp.encode(utils.decode_hex(v[2:]))) t2.update(triekey, rlp.encode(utils.decode_hex(v[2:]))) db.commit_refcount_changes(c) db.cleanup(c) c += 1 print(utils.encode_hex(t1.root_hash)) for k, v in toadd: sys.stderr.write('kv: %s %s\n' % (k, v)) triekey = utils.sha3(utils.zpad(utils.decode_hex(k[2:]), 32)) if v == '0x': t1.delete(triekey) else: t1.update(triekey, rlp.encode(utils.decode_hex(v[2:]))) db.commit_refcount_changes(c) db.cleanup(c) c += 1 t1.clear_all() db.commit_refcount_changes(c) for i in range(db.ttl + 1): db.cleanup(c) c += 1 t3 = pruning_trie.Trie(db) t3.root_hash = t2.root_hash print(t3.to_dict())
def test_revert_adds(): db = RefcountDB(EphemDB()) NODES = 60 t1 = pruning_trie.Trie(db) t2 = pruning_trie.Trie(db) db.ttl = NODES * 2 for i in range(NODES): t1.update(to_string(i), to_string(i)) db.commit_refcount_changes(i) db.cleanup(i) for i in range(NODES): t2.update(to_string(i), to_string(i)) db.commit_refcount_changes(NODES + i) db.cleanup(NODES + i) for i in range(NODES * 2 - 1, NODES - 1, -1): db.revert_refcount_changes(i) for i in range(NODES): t1.delete(to_string(i)) db.commit_refcount_changes(NODES + i) db.cleanup(NODES + i) for i in range(NODES * 2): db.cleanup(NODES * 2 + i) assert len(db.kv) == 0
def run_test(name): pairs = load_tests()[name] def _dec(x): if utils.is_string(x) and x.startswith(b'0x'): return utils.decode_hex(x[2:]) return x pairs['in'] = [(_dec(k), _dec(v)) for k, v in pairs['in']] deletes = [(k, v) for k, v in pairs['in'] if v is None] N_PERMUTATIONS = 100 for i, permut in enumerate(itertools.permutations(pairs['in'])): if i > N_PERMUTATIONS: break db = RefcountDB(EphemDB()) db.ttl = 0 t = pruning_trie.Trie(db) for k, v in permut: # logger.debug('updating with (%s, %s)' %(k, v)) if v is not None: t.update(k, v) else: t.delete(k) db.commit_refcount_changes(0) db.cleanup(0) # make sure we have deletes at the end for k, v in deletes: t.delete(k) t.clear_all() db.commit_refcount_changes(1) db.cleanup(1) assert len(db.kv) == 0 assert pairs['root'] == b'0x' + \ utils.encode_hex(t.root_hash), (i, list(permut) + deletes)
def db(): return EphemDB()
def __init__(self, db=None, config=None, global_config=None): self.db = EphemDB() if db is None else db assert isinstance(self.db, BaseDB) self.config = config or dict(default_config) self.global_config = global_config or dict()