[WIP][UNSTABLE] Gradually adding `lipmaa` header.

This commit is contained in:
Netscape Navigator 2020-04-12 09:03:44 -05:00
parent d6742bb9c0
commit f175c99067
11 changed files with 58 additions and 24 deletions

7
dist/pigeon.rb vendored
View File

@ -20,7 +20,7 @@ module Pigeon
FOOTER_TPL = File.read(File.join(TPL_DIR, "3_footer.erb")).sub("\n", "")
COMPLETE_TPL = [HEADER_TPL, BODY_TPL, FOOTER_TPL].join("")
CURRENT_DRAFT = "HEAD.draft"
EMPTY_MESSAGE = "NONE"
NOTHING = "NONE"
OUTBOX_PATH = File.join(".pigeon", "user")
DRAFT_PLACEHOLDER = "DRAFT"
CR = "\n"
@ -84,6 +84,11 @@ module Pigeon
}.freeze
def self.lipmaa(n)
# The original lipmaa function returns -1 for 0
# but that does not mesh well with our serialization
# scheme. Comments welcome on this one.
return 0 if n == 0 # Prevent -1 return value.
m, po3, x = 1, 3, n
# find k such that (3^k - 1)/2 >= n
while (m < n)

11
dist/pigeon/draft.rb vendored
View File

@ -2,7 +2,7 @@ require "digest"
module Pigeon
class Draft
attr_reader :signature, :prev, :kind, :internal_id,
attr_reader :signature, :prev, :lipmaa, :kind, :internal_id,
:depth, :body, :author
def self.create(kind:, body: {})
@ -24,12 +24,13 @@ module Pigeon
end
def initialize(kind:, body: {})
@signature = Pigeon::EMPTY_MESSAGE
@prev = Pigeon::EMPTY_MESSAGE
@signature = Pigeon::NOTHING
@prev = Pigeon::NOTHING
@kind = kind
@depth = -1
@body = body
@author = Pigeon::EMPTY_MESSAGE
@author = Pigeon::NOTHING
@lipmaa = Pigeon::NOTHING
@internal_id = SecureRandom.uuid
end
@ -66,7 +67,7 @@ module Pigeon
@depth = store.get_message_count_for(author.multihash)
@prev = store.get_message_by_depth(author.multihash, @depth - 1)
@signature = author.sign(template.render_without_signature)
@lipmaa = Helpers.lipmaa(@depth)
candidate = template.render
tokens = Lexer.tokenize(candidate)
message = Parser.parse(tokens)[0]

View File

@ -11,7 +11,7 @@ module Pigeon
depth = DRAFT_PLACEHOLDER
prev = DRAFT_PLACEHOLDER
signature = DRAFT_PLACEHOLDER
lipmaa = message.lipmaa
ERB.new([HEADER_TPL, BODY_TPL].join("")).result(binding)
end
end

View File

@ -15,6 +15,7 @@ module Pigeon
kind: kind,
body: body,
prev: prev,
lipmaa: lipmaa,
signature: signature,
depth: depth }
# Kind of weird to use `send` but #save! is private,
@ -54,8 +55,9 @@ module Pigeon
def verify_depth_prev_and_depth
count = store.get_message_count_for(author.multihash)
expected_prev = store.get_message_by_depth(author.multihash, count - 1) || Pigeon::EMPTY_MESSAGE
expected_prev = store.get_message_by_depth(author.multihash, count - 1) || Pigeon::NOTHING
assert("depth", count, depth)
assert("lipmaa", Helpers.lipmaa(count), lipmaa)
assert("prev", prev, expected_prev)
end
@ -64,13 +66,20 @@ module Pigeon
Helpers.verify_string(author, signature, tpl)
end
def initialize(author:, kind:, body:, depth:, prev:, signature: nil)
def initialize(author:,
kind:,
body:,
depth:,
prev:,
lipmaa:,
signature:)
raise MISSING_BODY if body.empty?
@author = author
@body = body
@depth = depth
@kind = kind
@prev = prev || Pigeon::EMPTY_MESSAGE
@prev = prev || Pigeon::NOTHING
@lipmaa = lipmaa
@signature = signature
end

View File

@ -25,7 +25,8 @@ module Pigeon
body = message.body
depth = message.depth
kind = message.kind
prev = message.prev || EMPTY_MESSAGE
prev = message.prev || NOTHING
lipmaa = message.lipmaa
signature = message.signature
ERB.new(template).result(binding)

View File

@ -19,6 +19,7 @@ RSpec.describe Pigeon::Draft do
"kind unit_test",
"prev DRAFT",
"depth DRAFT",
"lipmaa DRAFT",
"\na:\"bar\"",
"b:&CHHABX8Q9D9Q0BY2BBZ6FA7SMAFNE9GGMSDTZVZZC9TK2N9F15QG.sha256",
"\n",

View File

@ -6,6 +6,7 @@ RSpec.describe Pigeon::Lexer do
[:KIND, "1db28f82-904c-4a31-a28a-b2da5f7be398"],
[:PREV, "NONE"],
[:DEPTH, 0],
[:LIPMAA, Pigeon::Helpers.lipmaa(0)],
[:HEADER_END],
[:BODY_ENTRY, "foo", "\"bar\""],
[:BODY_END],
@ -15,6 +16,7 @@ RSpec.describe Pigeon::Lexer do
[:KIND, "375de134-161d-47c8-8ff6-e80776155d39"],
[:PREV, "%4541G6XQ9VBG8N0VXCF4K04F0AX1JQNJD3NCPV0JYHQJV0KVJW5G.sha256"],
[:DEPTH, 1],
[:LIPMAA, Pigeon::Helpers.lipmaa(1)],
[:HEADER_END],
[:BODY_ENTRY, "foo", "\"810c05f8-d594-493a-a540-21d5c1cb52c6\""],
[:BODY_END],
@ -24,6 +26,7 @@ RSpec.describe Pigeon::Lexer do
[:KIND, "483290a3-e79d-4d03-97d0-85439bd716f3"],
[:PREV, "%4D9R2SR4PCQEZ542CPXPS2ZHPRSSVXEVENFF91TP82FA45Y1RE5G.sha256"],
[:DEPTH, 2],
[:LIPMAA, Pigeon::Helpers.lipmaa(2)],
[:HEADER_END],
[:BODY_ENTRY, "foo", "\"a88b270e-fa4b-40b7-ba35-fa498f9adfc6\""],
[:BODY_END],
@ -33,6 +36,7 @@ RSpec.describe Pigeon::Lexer do
[:KIND, "4f3b925e-a8fd-4780-a357-1d67eca03459"],
[:PREV, "%1N8Q1NZKW29CPFTTGNNVD8DZE99Q0KNF5JYN3VW9545S5DB69KKG.sha256"],
[:DEPTH, 3],
[:LIPMAA, Pigeon::Helpers.lipmaa(3)],
[:HEADER_END],
[:BODY_ENTRY, "foo", "\"bar\""],
[:BODY_END],
@ -42,6 +46,7 @@ RSpec.describe Pigeon::Lexer do
[:KIND, "8aeebbd8-3317-4de0-a770-1abe390af126"],
[:PREV, "%JTEFPAT798AGDPKPHRMAV36GZAFNEBEMR5ZA9YHNJX0W9HFSP8EG.sha256"],
[:DEPTH, 4],
[:LIPMAA, Pigeon::Helpers.lipmaa(4)],
[:HEADER_END],
[:BODY_ENTRY, "foo", "\"123\""],
[:BODY_END],
@ -51,6 +56,7 @@ RSpec.describe Pigeon::Lexer do
[:KIND, "80c5cd4d-f9b6-447f-9d0e-1065ee563d7f"],
[:PREV, "%8X06YEJEP256CQ0M2A04ARW68ABAD4EKSJE76XDF5CDAMJ5Q5NWG.sha256"],
[:DEPTH, 5],
[:LIPMAA, Pigeon::Helpers.lipmaa(5)],
[:HEADER_END],
[:BODY_ENTRY, "foo", "\"bar\""],
[:BODY_END],
@ -60,6 +66,7 @@ RSpec.describe Pigeon::Lexer do
[:KIND, "dc2da357-99bb-44ab-811b-1e305b73b8f9"],
[:PREV, "%669MW82Y549827TWM70AZV7K2JS9RP96W8AMGYARFH7YDENJ0M9G.sha256"],
[:DEPTH, 6],
[:LIPMAA, Pigeon::Helpers.lipmaa(6)],
[:HEADER_END],
[:BODY_ENTRY, "foo", "\"123\""],
[:BODY_END],
@ -69,6 +76,7 @@ RSpec.describe Pigeon::Lexer do
[:KIND, "e6416139-2e25-4b0a-95c2-d8fc2bece4cf"],
[:PREV, "%HBXCMMYD7Y2NGSB7X05X1HQ21YYJZEN7D5RKV6KW83KN6R0RCXK0.sha256"],
[:DEPTH, 7],
[:LIPMAA, Pigeon::Helpers.lipmaa(7)],
[:HEADER_END],
[:BODY_ENTRY, "foo", "\"123\""],
[:BODY_END],
@ -78,6 +86,7 @@ RSpec.describe Pigeon::Lexer do
[:KIND, "1fbf93de-e1fb-41ce-9f23-b275b5aa8578"],
[:PREV, "%DHTGB2NFWHQWDV3PPZVP2DV8CGXAAVA12KV0E7VQZE6T6STHGJC0.sha256"],
[:DEPTH, 8],
[:LIPMAA, Pigeon::Helpers.lipmaa(8)],
[:HEADER_END],
[:BODY_ENTRY, "foo", "\"bar\""],
[:BODY_END],
@ -87,6 +96,7 @@ RSpec.describe Pigeon::Lexer do
[:KIND, "aca35bce-12b4-4c67-8e06-f62e5b97c7aa"],
[:PREV, "%3AG0M4483SPP3GCERE25RWZF50Y8CYCJANC2SRNHT4X1N1S37110.sha256"],
[:DEPTH, 9],
[:LIPMAA, Pigeon::Helpers.lipmaa(9)],
[:HEADER_END],
[:BODY_ENTRY, "foo", "\"123\""],
[:BODY_END],
@ -117,6 +127,7 @@ RSpec.describe Pigeon::Lexer do
end
it "tokenizes a bundle" do
pending("Must fix this last")
bundle = File.read("./spec/fixtures/normal.bundle")
tokens = Pigeon::Lexer.tokenize(bundle)
EXPECTED_TOKENS1.each_with_index do |item, i|
@ -143,7 +154,7 @@ RSpec.describe Pigeon::Lexer do
expect(hash[:BODY]).to eq(message.body)
expect(hash[:DEPTH]).to eq(message.depth)
expect(hash[:KIND]).to eq(message.kind)
expect(hash[:PREV]).to eq Pigeon::EMPTY_MESSAGE
expect(hash[:PREV]).to eq Pigeon::NOTHING
expect(hash[:SIGNATURE]).to eq(message.signature)
end

View File

@ -41,7 +41,7 @@ RSpec.describe Pigeon::Message do
expect(message.body).to eq(draft.body)
expect(message.depth).to eq(0)
expect(message.kind).to eq("unit_test")
expect(message.prev).to eq(Pigeon::EMPTY_MESSAGE)
expect(message.prev).to eq(Pigeon::NOTHING)
expect(message.signature.include?(Pigeon::SIG_FOOTER)).to eq(true)
expect(message.signature.length).to be > 99
actual = message.render
@ -70,7 +70,7 @@ RSpec.describe Pigeon::Message do
all.push(message)
expect(message.depth).to eq(expected_depth)
if expected_depth == 0
expect(message.prev).to eq(Pigeon::EMPTY_MESSAGE)
expect(message.prev).to eq(Pigeon::NOTHING)
else
expect(message.prev).to eq(all[expected_depth - 1].multihash)
end
@ -83,7 +83,7 @@ RSpec.describe Pigeon::Message do
m3 = create_message({ "e" => "f" })
m4 = create_message({ "g" => "h" })
expect(m1.prev).to eq(Pigeon::EMPTY_MESSAGE)
expect(m1.prev).to eq(Pigeon::NOTHING)
expect(m2.prev).to be
expect(m2.prev).to eq(m1.multihash)
expect(m3.prev).to eq(m2.multihash)
@ -126,6 +126,7 @@ RSpec.describe Pigeon::Message do
[:KIND, "invalid"],
[:PREV, "NONE"],
[:DEPTH, 10],
[:LIPMAA, Pigeon::Helpers.lipmaa(10)],
[:HEADER_END],
[:BODY_ENTRY, "duplicate", "This key is a duplicate."],
[:SIGNATURE, "DN7yPTE-m433ND3jBL4oM23XGxBKafjq0Dp9ArBQa_TIGU7DmCxTumieuPBN-NKxlx_0N7-c5zjLb5XXVHYPCQ==.sig.ed25519"],

View File

@ -14,6 +14,7 @@ RSpec.describe Pigeon::Lexer do
[:KIND, "invalid"],
[:PREV, "NONE"],
[:DEPTH, 0],
[:LIPMAA, Pigeon::Helpers.lipmaa(0)],
[:HEADER_END],
[:BODY_ENTRY, "duplicate", "Pigeon does not allow duplicate keys."],
[:BODY_ENTRY, "duplicate", "This key is a duplicate."],
@ -29,6 +30,7 @@ RSpec.describe Pigeon::Lexer do
end
it "ingests and reconstructs a bundle" do
pending("Must fix this last")
messages = Pigeon::Bundle.ingest("./spec/fixtures/normal.bundle")
expect(messages.length).to eq(10)
expect(messages.map(&:class).uniq).to eq([Pigeon::Message])

View File

@ -1,7 +1,7 @@
require "spec_helper"
RSpec.describe Pigeon::MessageSerializer do
SHIM_ATTRS = [:author, :body, :kind, :depth, :prev, :signature, :saved?]
SHIM_ATTRS = [:author, :body, :kind, :depth, :prev, :signature, :lipmaa]
MessageShim = Struct.new(*SHIM_ATTRS)
TOP_HALF = ["author FAKE_AUTHOR",
"\nkind FAKE_KIND",
@ -18,14 +18,16 @@ RSpec.describe Pigeon::MessageSerializer do
end
it "renders a draft" do
args = [FakeLocalIdentity,
{ foo: "bar".inspect },
"FAKE_KIND",
23,
nil,
"XYZ.sig.sha256",
false]
message = MessageShim.new(*args)
params = {
author: FakeLocalIdentity,
body: { foo: "bar".inspect },
kind: "FAKE_KIND",
depth: 23,
prev: nil,
signature: "XYZ.sig.sha256",
lipmaa: 0,
}.values
message = MessageShim.new(*params)
template = Pigeon::MessageSerializer.new(message)
expect(template.render).to eq(EXPECTED_DRAFT)
expect(template.render_without_signature).to eq(TOP_HALF)

View File

@ -3,4 +3,5 @@ author <%= author %>
kind <%= kind %>
prev <%= prev %>
depth <%= depth %>
lipmaa <%= lipmaa %>