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_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 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_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_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())