Index: backend/pgsql.t ================================================================== --- backend/pgsql.t +++ backend/pgsql.t @@ -903,11 +903,19 @@ return buf end end; } -local sqlvars = {} +local sqlvars = { + -- unforunately necessary to generate IDs that fill the whole + -- address space (due to floating-point shenanigans); there's + -- just no good way of doing this with SQL + ['def:uniq'] = [[bigint primary key default ( + (random() * ((1::bigint << 32) - 1) )::bigint << 32 | + (random() * ((1::bigint << 32) - 2) + 1)::bigint + )]] +} for i, n in ipairs(lib.store.noticetype.members) do sqlvars['notice:' .. n] = lib.store.noticetype[n]:asvalue() end for i, n in ipairs(lib.store.relation.members) do @@ -976,11 +984,11 @@ in &ipbuf[0] end dumpers[#dumpers+1] = `lib.io.fmt([tostring(i)..'. got inet\n']) elseif ty.ptr_basetype == int8 or ty.ptr_basetype == uint8 then counters[i] = `[args[i]].ct casts[i] = `[&int8]([args[i]].ptr) - dumpers[#dumpers+1] = `lib.io.fmt([tostring(i)..'. got ptr %llu %.*s\n'], [args[i]].ct, [args[i]].ct, [args[i]].ptr) + dumpers[#dumpers+1] = `lib.io.fmt([tostring(i)..'. got ptr %p %.*s\n'], [args[i]].ct, [args[i]].ct, [args[i]].ptr) elseif ty.ptr_basetype == bool then counters[i] = `1 casts[i] = `[&int8]([args[i]].ptr) -- dumpers[#dumpers+1] = `lib.io.fmt([tostring(i)..'. got bool = %hhu\n'], @[args[i]].ptr) elseif ty:isintegral() then Index: backend/schema/pgsql.sql ================================================================== --- backend/schema/pgsql.sql +++ backend/schema/pgsql.sql @@ -15,21 +15,21 @@ -- ('master',:'admin'), -- note that valid ids should always > 0, as 0 is reserved for null -- on the client side, vastly simplifying code create table parsav_servers ( - id bigint primary key default (1+random()*(2^63-1))::bigint, + id , domain text not null unique, key bytea, knownsince bigint, parsav boolean -- whether to use parsav protocol extensions ); comment on table parsav_servers is 'all servers known to the parsav instance. the local server (including its private key) is stored in row (id = 0)'; create table parsav_actors ( - id bigint primary key default (1+random()*(2^63-1))::bigint, + id , nym text, handle text not null, -- nym [@handle@origin] origin bigint references parsav_servers(id) on delete cascade, -- null origin = local actor knownsince bigint not null, @@ -60,11 +60,11 @@ create index on parsav_rights (actor); comment on table parsav_rights is 'a backward-compatible list of every non-default privilege or deprivilege granted to a local user'; create table parsav_posts ( - id bigint primary key default (1+random()*(2^63-1))::bigint, + id , author bigint references parsav_actors(id) on delete cascade, subject text, acl text not null default 'all', -- just store the script raw 🤷 body text, posted bigint not null, @@ -96,11 +96,11 @@ ); comment on table parsav_rels is 'all relationships, positive and negative, between local users and other users; kind is a version-specific integer mapping to a type-of-relationship enum in store.t'; create table parsav_acts ( - id bigint primary key default (1+random()*(2^63-1))::bigint, + id , kind text not null, -- like, rt, react, so on time bigint not null, actor bigint references parsav_actors(id) on delete cascade, subject bigint, -- may be post or act, depending on kind body text -- emoji, if react; complaint, if report @@ -111,21 +111,21 @@ comment on table parsav_acts is 'every simple action taken on a tweet by an actor, including likes, rts, reacts, and reports'; create table parsav_log ( -- accesses are tracked for security & sending delete acts - id bigint primary key default (1+random()*(2^63-1))::bigint, + id , time bigint not null, actor bigint references parsav_actors(id) on delete cascade, post bigint not null ); comment on table parsav_log is 'a log of accesses from foreign servers, tracking which will be sent update & delete events for each post'; create table parsav_artifacts ( - id bigint primary key default (1+random()*(2^63-1))::bigint, + id , birth bigint not null, content bytea, -- if null, this is a "ban record" preventing content matching the hash from being re-uploaded hash bytea unique not null, -- sha256 hash of content -- it would be cool to use a computed column for this, but i don't want -- to lock people into PG12 or drag in the pgcrypto extension just for this @@ -148,21 +148,21 @@ create index on parsav_artifact_claims (uid,folder); comment on table parsav_artifact_claims is 'a list of users who have an ownership interest in each artifact (effectively an index of GC roots)'; create table parsav_circles ( - id bigint primary key default (1+random()*(2^63-1))::bigint, + id , owner bigint not null references parsav_actors(id) on delete cascade, name text not null, members bigint[] not null default array[]::bigint[], unique (owner,name) ); create index on parsav_circles (owner); create table parsav_rooms ( - id bigint primary key default (1+random()*(2^63-1))::bigint, + id , origin bigint references parsav_servers(id) on delete cascade, name text not null, description text not null, policy smallint not null ); @@ -179,11 +179,11 @@ ); create index on parsav_room_members (member); create index on parsav_room_members (room); create table parsav_invites ( - id bigint primary key default (1+random()*(2^63-1))::bigint, + id , -- when a user is created from an invite, the invite is deleted and the invite -- ID becomes the user ID. privileges granted on the invite ID during the invite -- process are thus inherited by the user issuer bigint references parsav_actors(id) on delete set null, handle text, -- admin can lock invite to specific handle @@ -192,11 +192,11 @@ ); comment on table parsav_invites is 'all active invitations and the level of authority they grant if accepted'; create table parsav_sanctions ( - id bigint primary key default (1+random()*(2^63-1))::bigint, + id , issuer bigint references parsav_actors(id) on delete set null, scope bigint, -- can be null or room for local actions nature smallint not null, -- silence, suspend, disemvowel, censor, noreply, etc victim bigint not null, -- can be user, room, or post expire bigint, -- auto-expires if set Index: crypt.t ================================================================== --- crypt.t +++ crypt.t @@ -83,16 +83,17 @@ end end local binblob = lib.mem.ptr(uint8) terra m.der(pub: bool, key: &ctx, buf: &uint8): binblob - var ofs: intptr + var ofs: ptrdiff if pub then ofs = lib.pk.mbedtls_pk_write_pubkey_der(key, buf, const.maxdersz) else ofs = lib.pk.mbedtls_pk_write_key_der(key, buf, const.maxdersz) end + if ofs < 0 then return binblob.null() end return binblob { ptr = buf + (const.maxdersz - ofs); ct = ofs; } end Index: mgtool.t ================================================================== --- mgtool.t +++ mgtool.t @@ -286,18 +286,21 @@ if dbmode.arglist.ct < 1 then goto cmderr end srv:setup(cnf) if lib.str.cmp(dbmode.arglist(0),'init') == 0 and dbmode.arglist.ct == 2 then lib.report('initializing new database structure for domain ', dbmode.arglist(1)) - dlg:tx_enter() + --dlg:tx_enter() if dlg:dbsetup() then srv:conprep(lib.store.prepmode.conf) do var newkp = lib.crypt.genkp() -- generate server privkey var kbuf: uint8[lib.crypt.const.maxdersz] - var derkey = lib.crypt.der(false,&newkp, kbuf) + var derkey = lib.crypt.der(false,&newkp, &kbuf[0]) + if not derkey then + lib.bail('could not write out DER form of server pubkey!') + end dlg:server_setup_self(dbmode.arglist(1), derkey) end dlg:conf_set('instance-name', dbmode.arglist(1)) dlg:conf_set('domain', dbmode.arglist(1)) @@ -304,11 +307,11 @@ do var sec: int8[65] gensec(&sec[0]) dlg:conf_set('server-secret', &sec[0]) end lib.report('database setup complete; use mkroot to create an administrative user') else lib.bail('initialization process interrupted') end - dlg:tx_complete() + --dlg:tx_complete() elseif lib.str.cmp(dbmode.arglist(0),'obliterate') == 0 then var cfmstr: int8[64] gen_cfstr(&cfmstr[0],0) if dbmode.arglist.ct == 1 then lib.bail('you are attempting to completely obliterate all data! make sure you have selected your target correctly. if you really want to do this, pass the confirmation string ', &cfmstr[0]) Index: route.t ================================================================== --- route.t +++ route.t @@ -512,11 +512,10 @@ return quote var [me] [check] in [me] end end)()] - privs:dump() if privs:sz() > 0 then lib.dbg('installing credential restrictions') lib.io.fmt('on priv %llu\n',aid) co.srv:auth_privs_set(aid, privs) end