...almost done removing singletons...

This commit is contained in:
Netscape Navigator 2020-04-18 09:37:43 -05:00
parent a24486e583
commit 68c4c45427
4 changed files with 50 additions and 65 deletions

30
dist/pigeon.rb vendored
View File

@ -145,6 +145,13 @@ module Pigeon
verify_key.verify(binary_signature, string)
end
def assert(field, actual, expected)
unless actual == expected
message = VERFIY_ERROR % [field, actual || "nil", expected || "nil"]
raise VerificationError, message
end
end
def self.publish_draft(db, draft)
author = db.local_identity
mhash = author.multihash
@ -159,11 +166,32 @@ module Pigeon
unsigned = template.render_without_signature
draft.signature = author.sign(unsigned)
tokens = Lexer.tokenize_unsigned(unsigned, draft.signature)
message = Parser.parse(draft, tokens)[0]
message = Parser.parse(db, tokens)[0]
db.discard_draft
message
end
def publish_message(db, msg)
return db.read_message(multihash) if db.message?(multihash)
key_count = body.count
if key_count > 64
msg = MSG_SIZE_ERROR % key_count
raise MessageSizeError, msg
end
count = db.get_message_count_for(author.multihash)
expected_prev = db.get_message_by_depth(author.multihash, count - 1) || Pigeon::NOTHING
assert("depth", count, depth)
# TODO: Re-visit this. Our current verification method
# is probably too strict and won't allow for partial
# verification of feeds.
assert("lipmaa", Helpers.lipmaa(depth), lipmaa)
assert("prev", prev, expected_prev)
verify_signature
msg.freeze
db.save_message(msg)
msg
end
def self.decode_multihash(string)
if string[SIG_RANGE] == SIG_FOOTER
return b32_decode(string.gsub(SIG_FOOTER, ""))

View File

@ -77,6 +77,22 @@ module Pigeon
Helpers.publish_draft(self, draft)
end
def publish_message(msg)
Helpers.publish_message(self, msg)
end
# Store a message that someone (not the LocalIdentity)
# has authored.
def ingest(author:, body:, depth:, kind:, lipmaa:, prev:, signature:)
self.save_message(Message.new(author: RemoteIdentity.new(author),
kind: kind,
body: body,
prev: prev,
lipmaa: lipmaa,
signature: signature,
depth: depth))
end
private
attr_reader :store

View File

@ -9,30 +9,6 @@ module Pigeon
VERFIY_ERROR = "Expected field `%s` to equal %s, got: %s"
MSG_SIZE_ERROR = "Messages cannot have more than 64 keys. Got %s."
# Store a message that someone (not the LocalIdentity)
# has authored.
def self.ingest(author:,
body:,
depth:,
kind:,
lipmaa:,
prev:,
signature:,
db:)
raise "Type mismatch: #{@db.class}" unless @db.is_a?(Pigeon::Database)
params = { author: RemoteIdentity.new(author),
kind: kind,
body: body,
prev: prev,
lipmaa: lipmaa,
signature: signature,
depth: depth,
db: db }
# Kind of weird to use `send` but #save! is private,
# and I don't want people calling it directly without going through the
# lexer / parser first.
new(**params).send(:save!)
end
def render
template.render.chomp
@ -47,40 +23,6 @@ module Pigeon
private
def save!
return @db.read_message(multihash) if @db.message?(multihash)
verify_counted_fields
verify_signature
old_db = @db
@db = nil
self.freeze
old_db.save_message(self)
self
end
def assert(field, actual, expected)
unless actual == expected
message = VERFIY_ERROR % [field, actual || "nil", expected || "nil"]
raise VerificationError, message
end
end
def verify_counted_fields
key_count = body.count
if key_count > 64
msg = MSG_SIZE_ERROR % key_count
raise MessageSizeError, msg
end
count = @db.get_message_count_for(author.multihash)
expected_prev = @db.get_message_by_depth(author.multihash, count - 1) || Pigeon::NOTHING
assert("depth", count, depth)
# TODO: Re-visit this. Our current verification method
# is probably too strict and won't allow for partial
# verification of feeds.
assert("lipmaa", Helpers.lipmaa(depth), lipmaa)
assert("prev", prev, expected_prev)
end
def verify_signature
tpl = template.render_without_signature
Helpers.verify_string(author, signature, tpl)
@ -92,10 +34,8 @@ module Pigeon
depth:,
prev:,
lipmaa:,
signature:,
db:)
signature:)
raise MISSING_BODY if body.empty?
@db = db
@author = author
@body = body
@depth = depth

View File

@ -3,12 +3,13 @@ module Pigeon
class DuplicateKeyError < StandardError; end
def self.parse(db, tokens)
raise "NO!" unless db.is_a?(Pigeon::Database)
self.new(db, tokens).parse
end
def initialize(db, tokens)
@db = db
reset_scratchpad
@db = db
@tokens = tokens
@results = []
end
@ -34,12 +35,12 @@ module Pigeon
private
def reset_scratchpad
@scratchpad = { db: @db }
@scratchpad = {}
end
def finish_this_message!
@scratchpad.freeze
@results.push(Message.ingest(**@scratchpad))
@results.push(@db.ingest(**@scratchpad))
reset_scratchpad
end