From 68c4c4542754c65a3bcbe28e2d4b105380c7d6a4 Mon Sep 17 00:00:00 2001 From: Rick Carlino Date: Sat, 18 Apr 2020 09:37:43 -0500 Subject: [PATCH] ...almost done removing singletons... --- dist/pigeon.rb | 30 +++++++++++++++++++- dist/pigeon/database.rb | 16 +++++++++++ dist/pigeon/message.rb | 62 +---------------------------------------- dist/pigeon/parser.rb | 7 +++-- 4 files changed, 50 insertions(+), 65 deletions(-) diff --git a/dist/pigeon.rb b/dist/pigeon.rb index bbcf19d..add4602 100644 --- a/dist/pigeon.rb +++ b/dist/pigeon.rb @@ -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, "")) diff --git a/dist/pigeon/database.rb b/dist/pigeon/database.rb index fd6417f..2d2ec1f 100644 --- a/dist/pigeon/database.rb +++ b/dist/pigeon/database.rb @@ -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 diff --git a/dist/pigeon/message.rb b/dist/pigeon/message.rb index 20e8c21..d21b0b1 100644 --- a/dist/pigeon/message.rb +++ b/dist/pigeon/message.rb @@ -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 diff --git a/dist/pigeon/parser.rb b/dist/pigeon/parser.rb index d6fd264..d42daf5 100644 --- a/dist/pigeon/parser.rb +++ b/dist/pigeon/parser.rb @@ -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