work on next and added a .gitignore

This commit is contained in:
Dominik Moritz Roth 2020-06-11 23:26:19 +02:00
parent 7aab26508d
commit c560414e36
2 changed files with 51 additions and 30 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.pyc
__pycache__

79
next.py
View File

@ -1,5 +1,4 @@
from typing import Mapping, MutableMapping, Sequence, Iterable, List, Set #import pyfuse3
import pyfuse3
from iota import Iota, ProposedTransaction, Address, TryteString, Tag from iota import Iota, ProposedTransaction, Address, TryteString, Tag
from iota.crypto.addresses import AddressGenerator from iota.crypto.addresses import AddressGenerator
@ -39,28 +38,31 @@ class Atom():
else: else:
if data[1]==True: if data[1]==True:
self.type = "dir" self.type = "dir"
self.milestoneIndex = data[4]
else: else:
self.type = "file" self.type = "file"
self.size = data[5] self.size = data[4]
self.name = data[2] self.name = data[2]
self.token = data[3] self.token = data[3]
self.milestoneIndex = data[4]
def dump(self) -> bytes: def dump(self) -> bytes:
# TODO: Delimiter? # TODO: Delimiter?
# TODO: compression? # TODO: compression?
return msgpack.dump(self._dumpAsArray()) return msgpack.dumps(self._dumpAsArray())
def _dumpAsArray(self): def _dumpAsArray(self):
if self.type=="milestone": if self.type=="milestone":
return [True]+self.milestone return [True]+self.milestone
else: else:
return [False, self.type, self.name, self.token, self.milestoneIndex, self.size] if self.type=="file":
return [False, self.type, self.name, self.token, self.size]
else:
return [False, self.type, self.name, self.token, self.milestoneIndex]
class BlobChunk(): class BlobChunk():
def __init__(self, data: bytes = b'', sealed: bool = False) -> None: def __init__(self, data: bytes = b'', sealed: bool = False) -> None:
self.data = data self.data = data
self.sealded = sealed self.sealed = sealed
def getData(self) -> bytes: def getData(self) -> bytes:
return self.data return self.data
@ -89,7 +91,8 @@ class TangleBlob():
self.chunks = [] self.chunks = []
m = hashlib.sha3_512() m = hashlib.sha3_512()
m.update(self.token) m.update(self.token)
self.adressGen = AddressGenerator(Seed(m.digest())) trSeed = TryteString.from_bytes(m.digest())[:81]
self.adressGen = AddressGenerator(Seed(trSeed))
self.fetched = False self.fetched = False
self.pushedNum = 0 self.pushedNum = 0
@ -117,12 +120,12 @@ class TangleBlob():
inputs = [addr] inputs = [addr]
)['trytes'] )['trytes']
def _dumpChunk(self, chunkNum: int, security_level=2) -> str: def _dumpChunk(self, chunkNum: int) -> str:
key = self._getKey(chunkNum + self.preChunks) key = self._getKey(chunkNum + self.preChunks)
data = self.chunks[chunkNum].getData() data = self.chunks[chunkNum].getData()
cipher = AES.new(key[16:][:16], AES.MODE_CBC, key[:16]) cipher = AES.new(key[16:][:16], AES.MODE_CBC, key[:16])
ct_bytes = cipher.encrypt(pad(data, AES.block_size)) ct_bytes = cipher.encrypt(pad(data, AES.block_size))
addr = self.adressGen.get_addresses(start=chunkNum + self.preChunks, count=1, security_level=security_level)['addresses'][0] addr = self.adressGen.get_addresses(start=chunkNum + self.preChunks, count=1)[0]
return self._genBundle(ct_bytes, addr) return self._genBundle(ct_bytes, addr)
def append(self, data: bytes, newBlock: bool = False) -> None: def append(self, data: bytes, newBlock: bool = False) -> None:
@ -157,15 +160,16 @@ class TangleBlob():
data = "" data = ""
for c in range(len(self.chunks)-self.pushedNum): for c in range(len(self.chunks)-self.pushedNum):
num = c + self.pushedNum num = c + self.pushedNum
data += self._dumpChunk(num, 2) data += self._dumpChunk(num) # num is without preChunks
self.pushedNum = self.getChunkLen()
return data return data
def fetch(self, security_level=2, skipChunks: int = 0) -> None: def fetch(self, skipChunks: int = 0) -> None:
chunkNum = self.getChunkLen() + skipChunks chunkNum = self.getChunkLen() + skipChunks
while True: while True:
key = self._getKey(chunkNum) key = self._getKey(chunkNum)
cipher = AES.new(key[16:][:16], AES.MODE_CBC, key[:16]) cipher = AES.new(key[16:][:16], AES.MODE_CBC, key[:16])
addr = self.adressGen.get_addresses(start=chunkNum, count=1, security_level=security_level)['addresses'][0] addr = self.adressGen.get_addresses(start=chunkNum, count=1)[0]
txHash = self.api.find_transactions(tags=[Tag("IOTAFS")], addresses=[addr])["hashes"] txHash = self.api.find_transactions(tags=[Tag("IOTAFS")], addresses=[addr])["hashes"]
if len(txHash)==0: if len(txHash)==0:
break break
@ -184,17 +188,26 @@ class TangleBlob():
self.fetched = True self.fetched = True
self._afterFetch() self._afterFetch()
def _afterFetch() -> None: def _afterFetch(self) -> None:
return return
def genToken(self) -> bytes:
return secrets.token_bytes(32)
class TangleFileTreeElement(TangleBlob): class TangleFileTreeElement(TangleBlob):
def __init__(self, token: bytes, iotaApi: Iota) -> None: def __init__(self, token: bytes, parent, iotaApi: Iota) -> None:
super(TangleFileTreeElement, self).__init__(token) super(TangleFileTreeElement, self).__init__(token, iotaApi)
self.inodes = {} self.inodes = {}
self.atomStack = -1 self.atomStack = -1
self.api = iotaApi
self.parent = parent
def _afterFetch(self) -> None: def _afterFetch(self) -> None:
data = msgpack.load(self.read()) raw = self.read()
if raw==b'':
self.atomStack = 0
return
data = msgpack.loads(raw, raw=True)
newAtoms = [] newAtoms = []
for i, elem in enumerate(reversed(data)): for i, elem in enumerate(reversed(data)):
atom = Atom() atom = Atom()
@ -216,20 +229,20 @@ class TangleFileTreeElement(TangleBlob):
self.inodes[atom.name] = atom self.inodes[atom.name] = atom
def _applyAtom(self, atom: Atom) -> None: def _applyAtom(self, atom: Atom) -> None:
if atom.name in self.inode: if atom.name in self.inodes:
self.atomStack += 1 self.atomStack += 1
self.inodes[atom.name] = atom self.inodes[atom.name] = atom
if atom.type=="dir": if atom.type=="dir":
self.inodes[atom.name].elem = TangleFileTreeElement(atom.token, self.iotaApi) self.inodes[atom.name].elem = TangleFileTreeElement(atom.token, self, self.iotaApi)
elif atom.type=="file": elif atom.type=="file":
self.inodes[atom.name].elem = TangleFile(atom.token, self.iotaApi) self.inodes[atom.name].elem = TangleFile(atom.name, self, self.api)
else: else:
raise Exception("How did such an atom get here?") raise Exception("How did such an atom get here?")
def _newAtom(self, atom: Atom) -> None: def _newAtom(self, atom: Atom) -> None:
self.append(atom.dump()) self.append(atom.dump())
def getNameList(self) -> List(str): def getNameList(self):
self._requireFetched() self._requireFetched()
return list(self.inodes.keys()) return list(self.inodes.keys())
@ -244,7 +257,7 @@ class TangleFileTreeElement(TangleBlob):
atom = Atom() atom = Atom()
atom.type="dir" atom.type="dir"
atom.name = name atom.name = name
atom.token = "GENTOKENHERE" # TODO: < atom.token = self.genToken()
atom.milestoneIndex = 0 atom.milestoneIndex = 0
self._newAtom(atom) self._newAtom(atom)
self._applyAtom(atom) self._applyAtom(atom)
@ -257,8 +270,8 @@ class TangleFileTreeElement(TangleBlob):
atom = Atom() atom = Atom()
atom.type="file" atom.type="file"
atom.name = name atom.name = name
atom.token = "GENTOKENHERE" # TODO: < atom.token = self.genToken()
atom.milestoneIndex = 0 atom.size = 0
self._newAtom(atom) self._newAtom(atom)
self._applyAtom(atom) self._applyAtom(atom)
return True return True
@ -276,22 +289,24 @@ class TangleFileTreeElement(TangleBlob):
def performMilestone(self): def performMilestone(self):
stones = [] stones = []
for atom in self.inodes: for a in self.inodes:
stones.append(atom._dumpAsArray()) stones.append(self.inodes[a]._dumpAsArray())
self.atomStack = 0 self.atomStack = 0
# TODO: Delimiter ? # TODO: Delimiter ?
# TODO: compression ? # TODO: compression ?
data = msgpack.dump(stones) data = msgpack.dumps(stones)
self.append(data) self.append(data)
# inform parent about milestone (when merged)
class TangleFile(): class TangleFile():
def __init__(self, name: str, parent: TangleFileTreeElement, iotaApi: Iota) -> None: def __init__(self, name: str, parent: TangleFileTreeElement, iotaApi: Iota) -> None:
self.api = iotaApi
self.name = name self.name = name
self.parent = parent self.parent = parent
self.reflexiveAtom = parent.inodes[name] self.reflexiveAtom = parent.inodes[name]
self.size = self.reflexiveAtom.size self.size = self.reflexiveAtom.size
self.token = self.reflexiveAtom.token self.token = self.reflexiveAtom.token
super(TangleFile, self).__init__(self.token, iotaApi) self.blob = TangleBlob(self.token, iotaApi)
def write(self, offset: int, data: bytes): def write(self, offset: int, data: bytes):
if offset == self.size: if offset == self.size:
@ -303,7 +318,7 @@ class TangleFile():
class IotaFs(): class IotaFs():
def __init__(self, token) -> None: def __init__(self, token) -> None:
self.api = Iota('https://nodes.thetangle.org:443', local_pow=True) self.api = Iota('https://nodes.thetangle.org:443', local_pow=True)
self.genesis = TangleFileTreeElement(token, self.api) self.genesis = TangleFileTreeElement(token, None, self.api)
log("Fetching Genesis...") log("Fetching Genesis...")
self.genesis.fetch() self.genesis.fetch()
log("Retrieving reference to root") log("Retrieving reference to root")
@ -321,3 +336,7 @@ class IotaFs():
def createNewFile(self, name) -> None: def createNewFile(self, name) -> None:
pass pass
api = Iota('https://nodes.thetangle.org:443', local_pow=True)
token = b'testToken'
genesis = TangleFileTreeElement(token, None, api)