Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 29 additions & 16 deletions simplechat/simplepub/replica.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,42 +253,55 @@ def write48(self, content, sign_fct): # publish event, returns seq or None

def write(self, content, sign_fct): # publish event, returns seq or None
assert os.path.getsize(self.log_fname) == self.state['max_pos']
chunks = []
seq = self.state['max_seq'] + 1
sz = bipf.varint_encode_to_bytes(len(content))
payload = sz + content[:28-len(sz)]
if len(payload) != 28:
payload += bytes(28 - len(payload))
content = content[28-len(sz):]
i = len(content) % 100

root_content_length = 28 - len(sz)
root_content = content[:root_content_length] # the first bytes fit on root

# prep the chunks
content = content[root_content_length:] # skip over root_content
chunk_content_length = 100
# pad so all chunk content is size 100
i = len(content) % chunk_content_length
if i > 0:
content += bytes(100-i)
ptr = bytes(20)
pad = bytes(chunk_content_length - i)
content += pad

## we build the hash-chain of chunks from the end to the start
ptr = bytes(20) # end of chain is signalled by all-zero "hash"
chunks = []
while len(content) > 0:
buf = content[-100:] + ptr
buf = content[-chunk_content_length:] + ptr
chunks.append(buf)
ptr = hashlib.sha256(buf).digest()[:20]
content = content[:-100]
content = content[:-chunk_content_length]
chunks.reverse()
payload += ptr
nam = PFX + self.fid + seq.to_bytes(4,'big') + \
self.state['prev']

# prep the root message
seq = self.state['max_seq'] + 1
nam = PFX + self.fid + seq.to_bytes(4,'big') + self.state['prev']
dmx = hashlib.sha256(nam).digest()[:7]
payload = sz + root_content + ptr
msg = dmx + bytes([PKTTYPE_chain20]) + payload
wire = msg + sign_fct(nam + msg)

assert len(wire) == 120
assert self.verify_fct(self.fid, wire[56:], nam + wire[:56])

# write to log
chunks.insert(0, wire)
log_entry = b''.join(chunks)
log_entry += self.state['max_pos'].to_bytes(4, 'big')
with open(self.log_fname, 'ab') as f:
f.write(log_entry)

# ??
self._persist_frontier(seq, self.state['max_pos'] + len(log_entry),
hashlib.sha256(nam + wire).digest()[:20])

return seq

# ----------------------------------------------------------------------

pass

# eof