Xandaaah
Xandaaah

Reputation: 73

Python Kademlia not uploading data fully

I wrote a basic file sharing app in Python, but it seems to cut out much of the end of a file, which could be problematic to say the least. It uses the "kademlia" library, and it stores the data directly on the DHT. It's about ~4000 characters left out. Am I doing something wrong or is this a bug with the library?

import asyncio, io, hashlib, json, os
from kademlia.network import Server

CHUNKSIZE = 6000

BOOTSTRAP = False
PORT = 8103

nodes = [("127.0.0.1", 8103)]

def hash_(file: io.BytesIO):
    hash = hashlib.sha256()
    while True:
        val = file.read(1024*16)
        if not val:
            break
        hash.update(val)
    file.seek(0)
    return hash.hexdigest()

def size(file: io.BytesIO) -> int:
    file.seek(0, io.SEEK_END)
    val = file.tell()
    file.seek(0)
    return val

async def host(node: Server, file: io.BytesIO):
    size_ = size(file)
    chunks = size_ // CHUNKSIZE
    fhash = hash_(file)
    await node.set(fhash, json.dumps(
        {'chunks': chunks, 'size': size_, 'name': os.path.basename(file.name)}
    ))
    for i in range(0,chunks):
        await node.set(f"{fhash}/{i}", file.read(CHUNKSIZE))
    return fhash

async def download(node: Server, file: io.BytesIO, hash: str):
    meta = await node.get(hash)
    assert meta
    meta = json.loads(meta)
    for i in range(0,meta['chunks']):
        file.write(await node.get(f"{hash}/{i}"))
        file.flush()
    

async def run():
    # Create a node and start listening on port provided.
    node = Server()
    await node.listen(PORT)

    if BOOTSTRAP: await node.bootstrap(nodes)

    while True:
        inp = (await asyncio.to_thread(input, ">")).split(' ') 
        if inp[0] == 'host':
            with open(inp[1], 'rb') as f:
                print(await host(node, f))
        if inp[0] == 'download':
            with open('downloaded', 'wb') as f:
                await download(node, f, inp[1])
        if inp[0] == 'exit':
            exit()
if __name__ == '__main__':
    asyncio.run(run())

What I expected

What I got (in git diff format)

Upvotes: 0

Views: 20

Answers (0)

Related Questions