WIP. TODO: Make sure client is ingesting blobs in a bundle
This commit is contained in:
parent
e087888e94
commit
8fed4dc0bc
|
@ -0,0 +1,60 @@
|
|||
=> [32m#<Pigeon::Database:0x0000559bd1590cc8[0m
|
||||
@who_am_i[32m=[0m[32m#<Pigeon::LocalIdentity:0x0000559bd15d1890[0m @seed[32m=[0m[31m[1;31m"[0m[31m[1;35m\x1F[0m[31mL^9[1;35m\x90[0m[31me[1;35m\xF8[0m[31mg[1;35m\xF2[0m[31m[1;35m\x83[0m[31m[1;35m\xB4[0m[31m[1;35m\xC4[0m[31m>c[1;35m\x85[0m[31m[1;35m\xAE[0m[31m2w[1;35m\xBA[0m[31m&,@[1;35m\xD3[0m[31m[1;35m\x96[0m[31m[1;35m\xCA[0m[31mlO*[1;35m\xB9[0m[31m[1;35m\x8D[0m[31mkX[1;31m"[0m[31m[0m, @signing_key[32m=[0m[32m#<Ed25519::SigningKey:0x0000559bd15d17c8>[0m[32m>[0m,
|
||||
@store[32m=[0m
|
||||
[32m#<Pigeon::Storage:0x0000559bd15909f8[0m
|
||||
@path[32m=[0m[31m[1;31m"[0m[31mold.db[1;31m"[0m[31m[0m,
|
||||
@store[32m=[0m
|
||||
[32m#<PStore:0x0000559bd1590458[0m
|
||||
@abort[32m=[0m[1;36mfalse[0m,
|
||||
@filename[32m=[0m[31m[1;31m"[0m[31mpigeon.db[1;31m"[0m[31m[0m,
|
||||
@lock[32m=[0m[32m#<Thread::Mutex:0x0000559bd1597988[0m[32m>[0m,
|
||||
@rdonly[32m=[0m[1;36mtrue[0m,
|
||||
@table[32m=[0m
|
||||
{[31m[1;31m"[0m[31mblocked[1;31m"[0m[31m[0m=>[32m#<Set: {[0m}>,
|
||||
[31m[1;31m"[0m[31mconf[1;31m"[0m[31m[0m=>{[31m[1;31m"[0m[31mSEED[1;31m"[0m[31m[0m=>[31m[1;31m"[0m[31m[1;35m\x1F[0m[31mL^9[1;35m\x90[0m[31me[1;35m\xF8[0m[31mg[1;35m\xF2[0m[31m[1;35m\x83[0m[31m[1;35m\xB4[0m[31m[1;35m\xC4[0m[31m>c[1;35m\x85[0m[31m[1;35m\xAE[0m[31m2w[1;35m\xBA[0m[31m&,@[1;35m\xD3[0m[31m[1;35m\x96[0m[31m[1;35m\xCA[0m[31mlO*[1;35m\xB9[0m[31m[1;35m\x8D[0m[31mkX[1;31m"[0m[31m[0m, [31m[1;31m"[0m[31mHEAD.draft[1;31m"[0m[31m[0m=>[1;36mnil[0m},
|
||||
[31m[1;31m"[0m[31mmessages.count[1;31m"[0m[31m[0m=>{[31m[1;31m"[0m[31m@Y4ZFMFQPWCX0S5KD4C4NMFSRCRCT92FY410M4ACFBK3P24RH9MD0.ed25519[1;31m"[0m[31m[0m=>[1;34m4[0m},
|
||||
[31m[1;31m"[0m[31mmessages[1;31m"[0m[31m[0m=>
|
||||
{[31m[1;31m"[0m[31m%8STBRYR0WYJJRSD8DRA9RT6RF6QD6AKARCDYV17X8REGACHZ41W0.sha256[1;31m"[0m[31m[0m=>
|
||||
[32m#<Pigeon::Message:0x0000559bd15eb448[0m
|
||||
@author[32m=[0m[32m#<Pigeon::RemoteIdentity:0x0000559bd15ea4d0[0m @multihash[32m=[0m[31m[1;31m"[0m[31m@Y4ZFMFQPWCX0S5KD4C4NMFSRCRCT92FY410M4ACFBK3P24RH9MD0.ed25519[1;31m"[0m[31m[0m[32m>[0m,
|
||||
@body[32m=[0m{[31m[1;31m"[0m[31ma[1;31m"[0m[31m[0m=>[31m[1;31m"[0m[31m[1;35m\"[0m[31mb[1;35m\"[0m[31m[1;31m"[0m[31m[0m},
|
||||
@depth[32m=[0m[1;34m0[0m,
|
||||
@kind[32m=[0m[31m[1;31m"[0m[31munit_test[1;31m"[0m[31m[0m,
|
||||
@lipmaa[32m=[0m[1;34m0[0m,
|
||||
@prev[32m=[0m[31m[1;31m"[0m[31mNONE[1;31m"[0m[31m[0m,
|
||||
@signature[32m=[0m[31m[1;31m"[0m[31m8581280WEPNQGJ4DA6K0M7W726YVK1QGW5T7EPGZ61V4HV2GD1RKAB5AN8FXREW0NZKYKFANHW64H3YT0RSMMY30T8TBDJJSR0G9E0G.sig.ed25519[1;31m"[0m[31m[0m[32m>[0m,
|
||||
[31m[1;31m"[0m[31m%T88VZKCWN33CVD0TFBRPJ13NJHXF19TFRWP8NFJ1JGE5RB5ETC0G.sha256[1;31m"[0m[31m[0m=>
|
||||
[32m#<Pigeon::Message:0x0000559bd160cb98[0m
|
||||
@author[32m=[0m[32m#<Pigeon::RemoteIdentity:0x0000559bd160c7d8[0m @multihash[32m=[0m[31m[1;31m"[0m[31m@Y4ZFMFQPWCX0S5KD4C4NMFSRCRCT92FY410M4ACFBK3P24RH9MD0.ed25519[1;31m"[0m[31m[0m[32m>[0m,
|
||||
@body[32m=[0m{[31m[1;31m"[0m[31mc[1;31m"[0m[31m[0m=>[31m[1;31m"[0m[31m[1;35m\"[0m[31md[1;35m\"[0m[31m[1;31m"[0m[31m[0m},
|
||||
@depth[32m=[0m[1;34m1[0m,
|
||||
@kind[32m=[0m[31m[1;31m"[0m[31munit_test[1;31m"[0m[31m[0m,
|
||||
@lipmaa[32m=[0m[1;34m0[0m,
|
||||
@prev[32m=[0m[31m[1;31m"[0m[31m%8STBRYR0WYJJRSD8DRA9RT6RF6QD6AKARCDYV17X8REGACHZ41W0.sha256[1;31m"[0m[31m[0m,
|
||||
@signature[32m=[0m[31m[1;31m"[0m[31m60R873HBC5GHGVFWBC3RZBHXTQW0240GNF20JYBR71V4B1Z57HHXJ6N39Y4QZZPD34PQGZEQVMSAXTC71PATXAMWBVDCF2S9S45KM1G.sig.ed25519[1;31m"[0m[31m[0m[32m>[0m,
|
||||
[31m[1;31m"[0m[31m%JD4BETS4YH4ZA7CMP4ZHG0R62T5B0EAFDYHNM5S12M04SAF9AJ4G.sha256[1;31m"[0m[31m[0m=>
|
||||
[32m#<Pigeon::Message:0x0000559bd16165a8[0m
|
||||
@author[32m=[0m[32m#<Pigeon::RemoteIdentity:0x0000559bd1616300[0m @multihash[32m=[0m[31m[1;31m"[0m[31m@Y4ZFMFQPWCX0S5KD4C4NMFSRCRCT92FY410M4ACFBK3P24RH9MD0.ed25519[1;31m"[0m[31m[0m[32m>[0m,
|
||||
@body[32m=[0m{[31m[1;31m"[0m[31me[1;31m"[0m[31m[0m=>[31m[1;31m"[0m[31m[1;35m\"[0m[31mf[1;35m\"[0m[31m[1;31m"[0m[31m[0m},
|
||||
@depth[32m=[0m[1;34m2[0m,
|
||||
@kind[32m=[0m[31m[1;31m"[0m[31munit_test[1;31m"[0m[31m[0m,
|
||||
@lipmaa[32m=[0m[1;34m1[0m,
|
||||
@prev[32m=[0m[31m[1;31m"[0m[31m%T88VZKCWN33CVD0TFBRPJ13NJHXF19TFRWP8NFJ1JGE5RB5ETC0G.sha256[1;31m"[0m[31m[0m,
|
||||
@signature[32m=[0m[31m[1;31m"[0m[31m7DH9ZXMVT6RJEX31BPNSJ3XRA3AMPV97A1CPWW4BV0N99FW2JEPSCVQNJP7SZWA1N7BT560Y9EAK4N7AWFHDEFZV9AJ7PS81CVRF600.sig.ed25519[1;31m"[0m[31m[0m[32m>[0m,
|
||||
[31m[1;31m"[0m[31m%WTRSWSVA84DK2QMX5FDSNCVSAKQ4AFNPBW6VE93X4SJ1R60WDYMG.sha256[1;31m"[0m[31m[0m=>
|
||||
[32m#<Pigeon::Message:0x0000559bd1638978[0m
|
||||
@author[32m=[0m[32m#<Pigeon::RemoteIdentity:0x0000559bd1638590[0m @multihash[32m=[0m[31m[1;31m"[0m[31m@Y4ZFMFQPWCX0S5KD4C4NMFSRCRCT92FY410M4ACFBK3P24RH9MD0.ed25519[1;31m"[0m[31m[0m[32m>[0m,
|
||||
@body[32m=[0m{[31m[1;31m"[0m[31mg[1;31m"[0m[31m[0m=>[31m[1;31m"[0m[31m[1;35m\"[0m[31mh[1;35m\"[0m[31m[1;31m"[0m[31m[0m},
|
||||
@depth[32m=[0m[1;34m3[0m,
|
||||
@kind[32m=[0m[31m[1;31m"[0m[31munit_test[1;31m"[0m[31m[0m,
|
||||
@lipmaa[32m=[0m[1;34m2[0m,
|
||||
@prev[32m=[0m[31m[1;31m"[0m[31m%JD4BETS4YH4ZA7CMP4ZHG0R62T5B0EAFDYHNM5S12M04SAF9AJ4G.sha256[1;31m"[0m[31m[0m,
|
||||
@signature[32m=[0m[31m[1;31m"[0m[31m6KZZ2816J8V28QZG5EFM1BZAB2TF1HC87YTCQRSN1Q7395K91C9E7KE7DATT99N7XGQEJ5MRCNDS7354C5KN7763C1XVARKWRDG4T1R.sig.ed25519[1;31m"[0m[31m[0m[32m>[0m},
|
||||
[31m[1;31m"[0m[31mmessages.by_depth[1;31m"[0m[31m[0m=>
|
||||
{[31m[1;31m"[0m[31m@Y4ZFMFQPWCX0S5KD4C4NMFSRCRCT92FY410M4ACFBK3P24RH9MD0.ed25519.0[1;31m"[0m[31m[0m=>[31m[1;31m"[0m[31m%8STBRYR0WYJJRSD8DRA9RT6RF6QD6AKARCDYV17X8REGACHZ41W0.sha256[1;31m"[0m[31m[0m,
|
||||
[31m[1;31m"[0m[31m@Y4ZFMFQPWCX0S5KD4C4NMFSRCRCT92FY410M4ACFBK3P24RH9MD0.ed25519.1[1;31m"[0m[31m[0m=>[31m[1;31m"[0m[31m%T88VZKCWN33CVD0TFBRPJ13NJHXF19TFRWP8NFJ1JGE5RB5ETC0G.sha256[1;31m"[0m[31m[0m,
|
||||
[31m[1;31m"[0m[31m@Y4ZFMFQPWCX0S5KD4C4NMFSRCRCT92FY410M4ACFBK3P24RH9MD0.ed25519.2[1;31m"[0m[31m[0m=>[31m[1;31m"[0m[31m%JD4BETS4YH4ZA7CMP4ZHG0R62T5B0EAFDYHNM5S12M04SAF9AJ4G.sha256[1;31m"[0m[31m[0m,
|
||||
[31m[1;31m"[0m[31m@Y4ZFMFQPWCX0S5KD4C4NMFSRCRCT92FY410M4ACFBK3P24RH9MD0.ed25519.3[1;31m"[0m[31m[0m=>[31m[1;31m"[0m[31m%WTRSWSVA84DK2QMX5FDSNCVSAKQ4AFNPBW6VE93X4SJ1R60WDYMG.sha256[1;31m"[0m[31m[0m},
|
||||
[31m[1;31m"[0m[31mpeers[1;31m"[0m[31m[0m=>[32m#<Set: {[0m}>},
|
||||
@thread_safe[32m=[0m[1;36mfalse[0m,
|
||||
@ultra_safe[32m=[0m[1;36mtrue[0m[32m>[0m[32m>[0m[32m>[0m
|
|
@ -91,6 +91,7 @@ TODO
|
|||
- [X] Check block list before ingesting bundles.
|
||||
- [X] Need a way of importing / exporting a feeds blobs. (see "Bundle Brainstorming" below)
|
||||
- [X] Need a way of adding peers messages / gossip to bundles. (see "Bundle Brainstorming" below)
|
||||
- [ ] Rename `who_am_i` as `get_who_am_i` to follow VERB + NOUN convention.
|
||||
- [ ] Update README.md / tutorial.rb (user manual for `Pigeon::Database`).
|
||||
- [ ] Update spec document CLI usage examples to reflect API changes in 2020.
|
||||
- [ ] Publish to RubyGems
|
||||
|
|
|
@ -41,13 +41,13 @@ module Pigeon
|
|||
raise ConfigAlreadyExists
|
||||
end
|
||||
$db = Pigeon::Database.new
|
||||
puts db.local_identity.multihash
|
||||
puts db.who_am_i.multihash
|
||||
end
|
||||
|
||||
desc "show", "Prints your identiy string to STDOUT"
|
||||
|
||||
def show
|
||||
puts db.local_identity.multihash
|
||||
puts db.who_am_i.multihash
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -56,7 +56,7 @@ module Pigeon
|
|||
|
||||
def set(data = "")
|
||||
blob = (data != "") ? data : STDIN.read
|
||||
puts db.put_blob(blob)
|
||||
puts db.add_blob(blob)
|
||||
end
|
||||
|
||||
desc "get", "Read arbitrary data from the database"
|
||||
|
@ -103,9 +103,9 @@ module Pigeon
|
|||
|
||||
def append(key, raw_value = "")
|
||||
v = (raw_value != "") ? raw_value : STDIN.read
|
||||
if db.current_draft
|
||||
if db.get_draft
|
||||
db.update_draft(key, v)
|
||||
puts db.current_draft.render_as_draft
|
||||
puts db.get_draft.render_as_draft
|
||||
else
|
||||
bail("You must create a draft first")
|
||||
end
|
||||
|
@ -114,13 +114,13 @@ module Pigeon
|
|||
desc "show", "Print current message to STDOUT."
|
||||
|
||||
def show
|
||||
puts db.current_draft.render_as_draft
|
||||
puts db.get_draft.render_as_draft
|
||||
end
|
||||
|
||||
desc "sign", "Commit current DRAFT to local feed."
|
||||
|
||||
def sign
|
||||
puts db.publish_draft(db.current_draft).render
|
||||
puts db.publish_draft(db.get_draft).render
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -128,13 +128,13 @@ module Pigeon
|
|||
desc "create", "Create a pigeon bundle file"
|
||||
|
||||
def create(file_path = Pigeon::DEFAULT_BUNDLE_PATH)
|
||||
db.create_bundle(file_path)
|
||||
db.save_bundle(file_path)
|
||||
end
|
||||
|
||||
desc "ingest", "Ingest a pigeon bundle file"
|
||||
|
||||
def ingest(file_path = Pigeon::DEFAULT_BUNDLE_PATH)
|
||||
db.ingest_bundle(file_path)
|
||||
db.publish_bundle(file_path)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -148,13 +148,13 @@ module Pigeon
|
|||
desc "find-all", "Find all message IDs of a particular identity."
|
||||
|
||||
def find_all(author = nil)
|
||||
puts db.find_all_messages(author).join(Pigeon::CR) + Pigeon::CR
|
||||
puts db.all_messages(author).join(Pigeon::CR) + Pigeon::CR
|
||||
end
|
||||
|
||||
desc "last", "Grab your last message. INTERNAL USE ONLY"
|
||||
|
||||
def last
|
||||
me = db.local_identity
|
||||
me = db.who_am_i
|
||||
mcount = db.get_message_count_for(me.multihash)
|
||||
multihash = db.get_message_by_depth(me.multihash, mcount - 1)
|
||||
puts multihash
|
||||
|
@ -165,7 +165,7 @@ module Pigeon
|
|||
desc "status", "Show various information about the `.pgn` directory"
|
||||
|
||||
def status
|
||||
me = db.local_identity.multihash
|
||||
me = db.who_am_i.multihash
|
||||
mine = db.get_message_count_for(me)
|
||||
puts "
|
||||
-`. Pigeon Protocol Ruby Client
|
||||
|
@ -173,7 +173,7 @@ module Pigeon
|
|||
_) ( Peers: #{db.all_peers.count}
|
||||
/ ) Blocked: #{db.all_blocks.count}
|
||||
/_,' / Msgs Published: #{mine}
|
||||
\\ / Msgs Total: #{db.find_all_messages.count}
|
||||
\\ / Msgs Total: #{db.all_messages.count}
|
||||
===m\" \"m===
|
||||
Your local identity hash:
|
||||
#{me}
|
||||
|
|
|
@ -154,7 +154,7 @@ module Pigeon
|
|||
end
|
||||
|
||||
def self.publish_draft(db, draft)
|
||||
author = db.local_identity
|
||||
author = db.who_am_i
|
||||
mhash = author.multihash
|
||||
template = MessageSerializer.new(draft)
|
||||
depth = db.get_message_count_for(mhash)
|
||||
|
@ -173,7 +173,7 @@ module Pigeon
|
|||
end
|
||||
|
||||
def self.update_draft(db, key, value)
|
||||
draft = db.current_draft
|
||||
draft = db.get_draft
|
||||
draft[key] = value
|
||||
db.save_draft(draft)
|
||||
return draft.body[key]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module Pigeon
|
||||
class Database
|
||||
attr_reader :local_identity
|
||||
attr_reader :who_am_i
|
||||
|
||||
def initialize(path: PIGEON_DB_PATH)
|
||||
@store = Pigeon::Storage.new(path: path)
|
||||
|
@ -16,10 +16,10 @@ module Pigeon
|
|||
def all_peers(); store.all_peers(); end
|
||||
|
||||
# === MESSAGES
|
||||
def find_all_messages(mhash = nil); store.find_all_messages(mhash); end
|
||||
def all_messages(mhash = nil); store.all_messages(mhash); end
|
||||
def message_saved?(multihash); store.message_saved?(multihash); end
|
||||
|
||||
def save_message(msg_obj)
|
||||
def _save_message(msg_obj)
|
||||
store.insert_message(Helpers.verify_message(self, msg_obj))
|
||||
end
|
||||
|
||||
|
@ -33,19 +33,19 @@ module Pigeon
|
|||
store.get_message_by_depth(multihash, depth)
|
||||
end
|
||||
|
||||
def create_message(kind, params)
|
||||
def add_message(kind, params)
|
||||
publish_draft(new_draft(kind: kind, body: params))
|
||||
end
|
||||
|
||||
# Store a message that someone (not the LocalIdentity)
|
||||
# has authored.
|
||||
def ingest_message(author:,
|
||||
body:,
|
||||
depth:,
|
||||
kind:,
|
||||
lipmaa:,
|
||||
prev:,
|
||||
signature:)
|
||||
def _ingest_message(author:,
|
||||
body:,
|
||||
depth:,
|
||||
kind:,
|
||||
lipmaa:,
|
||||
prev:,
|
||||
signature:)
|
||||
msg = Message.new(author: RemoteIdentity.new(author),
|
||||
kind: kind,
|
||||
body: body,
|
||||
|
@ -53,11 +53,11 @@ module Pigeon
|
|||
lipmaa: lipmaa,
|
||||
signature: signature,
|
||||
depth: depth)
|
||||
save_message(msg)
|
||||
_save_message(msg)
|
||||
end
|
||||
|
||||
# === DRAFTS
|
||||
def reset_current_draft; set_config(CURRENT_DRAFT, nil); end
|
||||
def reset_draft; add_config(CURRENT_DRAFT, nil); end
|
||||
|
||||
def new_draft(kind:, body: {})
|
||||
old = get_config(CURRENT_DRAFT)
|
||||
|
@ -68,11 +68,11 @@ module Pigeon
|
|||
end
|
||||
|
||||
def save_draft(draft)
|
||||
set_config(CURRENT_DRAFT, draft)
|
||||
add_config(CURRENT_DRAFT, draft)
|
||||
draft
|
||||
end
|
||||
|
||||
def current_draft
|
||||
def get_draft
|
||||
draft = store.get_config(CURRENT_DRAFT)
|
||||
if draft
|
||||
return draft
|
||||
|
@ -84,20 +84,20 @@ module Pigeon
|
|||
def update_draft(k, v); Helpers.update_draft(self, k, v); end
|
||||
|
||||
def reset_draft
|
||||
set_config(CURRENT_DRAFT, nil)
|
||||
add_config(CURRENT_DRAFT, nil)
|
||||
end
|
||||
|
||||
# Author a new message.
|
||||
def publish_draft(draft = self.current_draft)
|
||||
def publish_draft(draft = self.get_draft)
|
||||
Helpers.publish_draft(self, draft)
|
||||
end
|
||||
|
||||
# === BUNDLES
|
||||
def create_bundle(file_path = DEFAULT_BUNDLE_PATH)
|
||||
def save_bundle(file_path = DEFAULT_BUNDLE_PATH)
|
||||
# Fetch messages for all peers
|
||||
peers = all_peers + [local_identity.multihash]
|
||||
peers = all_peers + [who_am_i.multihash]
|
||||
messages = peers.map do |peer|
|
||||
find_all_messages(peer)
|
||||
all_messages(peer)
|
||||
.map { |multihash| read_message(multihash) }
|
||||
.sort_by(&:depth)
|
||||
end.flatten
|
||||
|
@ -114,10 +114,11 @@ module Pigeon
|
|||
content = messages
|
||||
.map { |message| message.render }
|
||||
.join(BUNDLE_MESSAGE_SEPARATOR)
|
||||
File.join(file_path, "gossip.pgn")
|
||||
File.write(File.join(file_path, "gossip.pgn"), content + CR)
|
||||
end
|
||||
|
||||
def ingest_bundle(file_path = DEFAULT_BUNDLE_PATH)
|
||||
def publish_bundle(file_path = DEFAULT_BUNDLE_PATH)
|
||||
bundle = File.read(File.join(file_path, "gossip.pgn"))
|
||||
tokens = Pigeon::Lexer.tokenize(bundle)
|
||||
Pigeon::Parser.parse(self, tokens)
|
||||
|
@ -125,11 +126,11 @@ module Pigeon
|
|||
|
||||
# === BLOBS
|
||||
def get_blob(b); store.get_blob(b); end
|
||||
def put_blob(b); store.put_blob(b); end
|
||||
def add_blob(b); store.add_blob(b); end
|
||||
|
||||
# === DB Management
|
||||
def get_config(k); store.get_config(k); end
|
||||
def set_config(k, v); store.set_config(k, v); end
|
||||
def add_config(k, v); store.add_config(k, v); end
|
||||
def reset_database; store.reset; init_ident; end
|
||||
|
||||
private
|
||||
|
@ -139,11 +140,11 @@ module Pigeon
|
|||
def init_ident
|
||||
secret = get_config(SEED_CONFIG_KEY)
|
||||
if secret
|
||||
@local_identity = LocalIdentity.new(secret)
|
||||
@who_am_i = LocalIdentity.new(secret)
|
||||
else
|
||||
new_seed = SecureRandom.random_bytes(Ed25519::KEY_SIZE)
|
||||
set_config(SEED_CONFIG_KEY, new_seed)
|
||||
@local_identity = LocalIdentity.new(new_seed)
|
||||
add_config(SEED_CONFIG_KEY, new_seed)
|
||||
@who_am_i = LocalIdentity.new(new_seed)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -41,7 +41,7 @@ module Pigeon
|
|||
def finish_this_message!
|
||||
@scratchpad.freeze
|
||||
unless @db.peer_blocked?(@scratchpad.fetch(:author))
|
||||
@results.push(@db.ingest_message(**@scratchpad))
|
||||
@results.push(@db._ingest_message(**@scratchpad))
|
||||
end
|
||||
reset_scratchpad
|
||||
end
|
||||
|
|
|
@ -43,7 +43,7 @@ module Pigeon
|
|||
read { store[CONF_NS][key] }
|
||||
end
|
||||
|
||||
def set_config(key, value)
|
||||
def add_config(key, value)
|
||||
write do
|
||||
a = store.fetch(CONF_NS)
|
||||
raise "FIX SAVED DRAFTS" if value.instance_variable_get(:@db)
|
||||
|
@ -51,7 +51,7 @@ module Pigeon
|
|||
end
|
||||
end
|
||||
|
||||
def put_blob(data)
|
||||
def add_blob(data)
|
||||
size = data.bytesize
|
||||
if (size > BLOB_BYTE_LIMIT)
|
||||
raise "Blob size limit is #{BLOB_BYTE_LIMIT} bytes. Got #{size}"
|
||||
|
@ -79,7 +79,7 @@ module Pigeon
|
|||
read { store[COUNT_INDEX_NS][mhash] || 0 }
|
||||
end
|
||||
|
||||
def find_all_messages(author)
|
||||
def all_messages(author)
|
||||
if author
|
||||
all = []
|
||||
depth = -1
|
||||
|
|
|
@ -13,35 +13,41 @@ RSpec.describe Pigeon::Message do
|
|||
end
|
||||
|
||||
def create_fake_messages
|
||||
blobs = [db.create_message(db.put_blob("one"), { "a" => "b" }),
|
||||
db.create_message("a", { db.put_blob("two") => "b" }),
|
||||
db.create_message("a", { "b" => db.put_blob("three") })]
|
||||
blobs = [db.add_message(db.add_blob("one"), { "a" => "b" }),
|
||||
db.add_message("a", { db.add_blob("two") => "b" }),
|
||||
db.add_message("a", { "b" => db.add_blob("three") })]
|
||||
normal = (1..10)
|
||||
.to_a
|
||||
.map do |n| { "foo" => ["bar", "123", SecureRandom.uuid].sample } end
|
||||
.map do |d| db.create_message(SecureRandom.uuid, d) end
|
||||
.map do |d| db.add_message(SecureRandom.uuid, d) end
|
||||
|
||||
blobs + normal
|
||||
end
|
||||
|
||||
it "creates a bundle" do
|
||||
expected_bundle = create_fake_messages.map(&:render).join("\n\n") + "\n"
|
||||
db.create_bundle
|
||||
db.save_bundle
|
||||
actual_bundle = File.read(File.join(Pigeon::DEFAULT_BUNDLE_PATH, "gossip.pgn"))
|
||||
expect(expected_bundle).to eq(actual_bundle)
|
||||
end
|
||||
|
||||
it "does not crash when ingesting old messages" do
|
||||
create_fake_messages
|
||||
db.create_bundle
|
||||
db.ingest_bundle
|
||||
db.save_bundle
|
||||
db.publish_bundle
|
||||
end
|
||||
|
||||
it "does not ingest messages from blocked peers" do
|
||||
db.reset_database
|
||||
antagonist = "@PPJQ3Q36W258VQ1NKYY2G7VW24J8NMAACHXCD83GCQ3K8F4C9X2G.ed25519"
|
||||
db.block_peer(antagonist)
|
||||
db.ingest_bundle("./spec/fixtures/x")
|
||||
expect(db.find_all_messages.count).to eq(0)
|
||||
db.publish_bundle("./spec/fixtures/x")
|
||||
expect(db.all_messages.count).to eq(0)
|
||||
end
|
||||
|
||||
it "ingests a bundle's blobs" do
|
||||
db.reset_database
|
||||
db.publish_bundle("./spec/fixtures/has_blobs")
|
||||
expect(db.all_messages.count).to eq(0)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,8 +12,8 @@ RSpec.describe Pigeon::Draft do
|
|||
db.new_draft(kind: "unit_test")
|
||||
logo = File.read("./logo.png")
|
||||
db.update_draft("a", "bar")
|
||||
db.update_draft("b", db.put_blob(logo))
|
||||
db.current_draft
|
||||
db.update_draft("b", db.add_blob(logo))
|
||||
db.get_draft
|
||||
end
|
||||
|
||||
MSG = [
|
||||
|
@ -28,7 +28,7 @@ RSpec.describe Pigeon::Draft do
|
|||
].join("\n")
|
||||
|
||||
it "renders a message" do
|
||||
pk = db.local_identity.multihash
|
||||
pk = db.who_am_i.multihash
|
||||
actual = message.render_as_draft
|
||||
expected = MSG.gsub("___", pk)
|
||||
expect(actual).to start_with(expected)
|
||||
|
@ -37,7 +37,7 @@ RSpec.describe Pigeon::Draft do
|
|||
it "creates a new message" do
|
||||
db.reset_draft
|
||||
db.new_draft(kind: "unit_test")
|
||||
hash = db.put_blob(File.read("./logo.png"))
|
||||
hash = db.add_blob(File.read("./logo.png"))
|
||||
expectations = {
|
||||
kind: "unit_test",
|
||||
body: {
|
||||
|
@ -52,7 +52,7 @@ RSpec.describe Pigeon::Draft do
|
|||
expect(message.kind).to eq("unit_test")
|
||||
expect(message.body).to eq(expectations.fetch(:body))
|
||||
expectations.map do |k, v|
|
||||
left = db.current_draft.send(k)
|
||||
left = db.get_draft.send(k)
|
||||
expect(left).to eq(v)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,10 +4,10 @@ RSpec.describe Pigeon::Message do
|
|||
def reset_draft(params)
|
||||
db.reset_draft
|
||||
db.new_draft(kind: "unit_test", body: params)
|
||||
db.current_draft
|
||||
db.get_draft
|
||||
end
|
||||
|
||||
def create_message(params)
|
||||
def add_message(params)
|
||||
draft = reset_draft(params)
|
||||
db.publish_draft(draft)
|
||||
end
|
||||
|
@ -19,11 +19,11 @@ RSpec.describe Pigeon::Message do
|
|||
end
|
||||
|
||||
let(:draft) do
|
||||
hash = db.put_blob(File.read("./logo.png"))
|
||||
hash = db.add_blob(File.read("./logo.png"))
|
||||
reset_draft({ "a" => "bar", "b" => hash })
|
||||
end
|
||||
|
||||
let(:templated_message) { create_message({ "a" => "b" }) }
|
||||
let(:templated_message) { add_message({ "a" => "b" }) }
|
||||
|
||||
let (:template) do
|
||||
Pigeon::MessageSerializer.new(templated_message)
|
||||
|
@ -31,12 +31,12 @@ RSpec.describe Pigeon::Message do
|
|||
|
||||
it "discards a draft after signing" do
|
||||
db.publish_draft(draft)
|
||||
expect { db.current_draft }.to raise_error("THERE IS NO DRAFT. CREATE ONE FIRST.")
|
||||
expect { db.get_draft }.to raise_error("THERE IS NO DRAFT. CREATE ONE FIRST.")
|
||||
end
|
||||
|
||||
it "creates a single message" do
|
||||
message = db.publish_draft(draft)
|
||||
expect(message.author.multihash).to eq(db.local_identity.multihash)
|
||||
expect(message.author.multihash).to eq(db.who_am_i.multihash)
|
||||
expect(message.body).to eq(draft.body)
|
||||
expect(message.depth).to eq(0)
|
||||
expect(message.kind).to eq("unit_test")
|
||||
|
@ -79,10 +79,10 @@ RSpec.describe Pigeon::Message do
|
|||
end
|
||||
|
||||
it "verifies accuracy of hash chain" do
|
||||
m1 = create_message({ "a" => "b" })
|
||||
m2 = create_message({ "c" => "d" })
|
||||
m3 = create_message({ "e" => "f" })
|
||||
m4 = create_message({ "g" => "h" })
|
||||
m1 = add_message({ "a" => "b" })
|
||||
m2 = add_message({ "c" => "d" })
|
||||
m3 = add_message({ "e" => "f" })
|
||||
m4 = add_message({ "g" => "h" })
|
||||
|
||||
expect(m1.prev).to eq(Pigeon::NOTHING)
|
||||
expect(m2.prev).to be
|
||||
|
@ -100,7 +100,7 @@ RSpec.describe Pigeon::Message do
|
|||
body[SecureRandom.hex(6)] = SecureRandom.hex(6)
|
||||
end
|
||||
expect do
|
||||
create_message(body)
|
||||
add_message(body)
|
||||
end.to raise_error(Pigeon::Helpers::MessageSizeError, error)
|
||||
end
|
||||
|
||||
|
@ -112,7 +112,7 @@ RSpec.describe Pigeon::Message do
|
|||
plaintext = template.render_without_signature
|
||||
|
||||
# Make fake pairs of data for cross-checking
|
||||
key1 = db.local_identity.instance_variable_get(:@signing_key)
|
||||
key1 = db.who_am_i.instance_variable_get(:@signing_key)
|
||||
key2 = Ed25519::SigningKey.new(secret)
|
||||
|
||||
sig1 = key1.sign(plaintext)
|
||||
|
|
|
@ -30,7 +30,7 @@ RSpec.describe Pigeon::Lexer do
|
|||
end
|
||||
|
||||
it "ingests and reconstructs a bundle" do
|
||||
messages = db.ingest_bundle("./spec/fixtures/normal")
|
||||
messages = db.publish_bundle("./spec/fixtures/normal")
|
||||
expect(messages.length).to eq(10)
|
||||
expect(messages.map(&:class).uniq).to eq([Pigeon::Message])
|
||||
re_bundled = messages.map(&:render).join("\n\n") + "\n"
|
||||
|
|
|
@ -12,22 +12,22 @@ RSpec.describe Pigeon::Storage do
|
|||
end
|
||||
|
||||
it "sets a config" do
|
||||
db.set_config("FOO", "BAR")
|
||||
db.add_config("FOO", "BAR")
|
||||
value = db.get_config("FOO")
|
||||
expect(value).to eq("BAR")
|
||||
db.set_config("FOO", nil)
|
||||
db.add_config("FOO", nil)
|
||||
value = db.get_config("FOO")
|
||||
expect(value).to eq(nil)
|
||||
end
|
||||
|
||||
it "manages configs" do
|
||||
db.set_config("FOO", "BAR")
|
||||
db.add_config("FOO", "BAR")
|
||||
value = db.get_config("FOO")
|
||||
expect(value).to eq("BAR")
|
||||
end
|
||||
|
||||
it "manages blobs" do
|
||||
logo_hash = db.put_blob(LOGO_BLOB)
|
||||
logo_hash = db.add_blob(LOGO_BLOB)
|
||||
expect(db.get_blob(logo_hash)).to eq(LOGO_BLOB)
|
||||
end
|
||||
|
||||
|
@ -48,27 +48,27 @@ RSpec.describe Pigeon::Storage do
|
|||
end
|
||||
|
||||
it "finds all authored by a particular feed" do
|
||||
ingested_messages = db.ingest_bundle("./spec/fixtures/normal")
|
||||
ingested_messages = db.publish_bundle("./spec/fixtures/normal")
|
||||
author = ingested_messages.first.author.multihash
|
||||
actual_messages = db.find_all_messages(author)
|
||||
search_results = db.find_all_messages(author)
|
||||
actual_messages = db.all_messages(author)
|
||||
search_results = db.all_messages(author)
|
||||
end
|
||||
|
||||
it "finds all messages" do
|
||||
msgs = [
|
||||
db.create_message("strings", {
|
||||
db.add_message("strings", {
|
||||
"example_1.1" => "This is a string.",
|
||||
"example=_." => "A second string.",
|
||||
}),
|
||||
db.create_message("d", {
|
||||
"e" => db.put_blob(File.read("./logo.png")),
|
||||
db.add_message("d", {
|
||||
"e" => db.add_blob(File.read("./logo.png")),
|
||||
}),
|
||||
db.create_message("g", {
|
||||
"me_myself_and_i" => db.local_identity.multihash,
|
||||
db.add_message("g", {
|
||||
"me_myself_and_i" => db.who_am_i.multihash,
|
||||
}),
|
||||
]
|
||||
me = db.local_identity.multihash
|
||||
results = db.find_all_messages(me)
|
||||
me = db.who_am_i.multihash
|
||||
results = db.all_messages(me)
|
||||
expect(results.length).to eq(3)
|
||||
expect(msgs[0].multihash).to eq(results[0])
|
||||
expect(msgs[1].multihash).to eq(results[1])
|
||||
|
|
65
tutorial.rb
65
tutorial.rb
|
@ -1,31 +1,36 @@
|
|||
require "pigeon"
|
||||
# add_blob
|
||||
# add_config
|
||||
# add_message
|
||||
# add_peer
|
||||
# all_blocks
|
||||
# all_messages
|
||||
# all_peers
|
||||
# block_peer
|
||||
# get_blob
|
||||
# get_config
|
||||
# get_draft
|
||||
# get_message_by_depth
|
||||
# get_message_count_for
|
||||
# message_saved?
|
||||
# peer_blocked?
|
||||
# who_am_i
|
||||
# new_draft
|
||||
# publish_bundle
|
||||
# publish_draft
|
||||
# read_message
|
||||
# remove_peer
|
||||
# reset_database
|
||||
# reset_draft
|
||||
# save_bundle
|
||||
# save_draft
|
||||
# update_draft
|
||||
|
||||
require_relative "lib/pigeon"
|
||||
require "pry"
|
||||
|
||||
db = Pigeon::Database.new(path: "my.db")
|
||||
|
||||
db.reset_draft
|
||||
db.current_draft
|
||||
db.reset_draft
|
||||
db.publish_draft
|
||||
db.save_draft
|
||||
db.save_message
|
||||
db.reset_current_draft
|
||||
db.message_saved?
|
||||
db.read_message
|
||||
db.create_message
|
||||
db.find_all_messages
|
||||
db.get_message_by_depth
|
||||
db.get_message_count_for
|
||||
db.local_identity
|
||||
db.remove_peer
|
||||
db.add_peer
|
||||
db.block_peer
|
||||
db.all_peers
|
||||
db.all_blocks
|
||||
db.get_blob
|
||||
db.put_blob
|
||||
db.create_bundle
|
||||
db.get_config
|
||||
db.ingest_bundle
|
||||
db.set_config
|
||||
db.reset_database
|
||||
files = %w(a.gif b.gif c.gif)
|
||||
body = { "what" => "A simple bundle with a few blobs" }
|
||||
db = Pigeon::Database.new(path: "new.db")
|
||||
db.add_message("description", body)
|
||||
files.map { |file| db.add_blob(file) }
|
||||
binding.pry
|
||||
db.save_bundle("./spec/fixtures/has_blobs")
|
||||
|
|
Loading…
Reference in New Issue