From 8f32e14c899f14c1e95254f669fa9817da8f55b6 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 1 Sep 2020 09:00:07 +1000 Subject: [PATCH 01/15] contact-hook: add /synced scry --- pkg/arvo/app/contact-hook.hoon | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pkg/arvo/app/contact-hook.hoon b/pkg/arvo/app/contact-hook.hoon index acb3b95724..ad523ed8f9 100644 --- a/pkg/arvo/app/contact-hook.hoon +++ b/pkg/arvo/app/contact-hook.hoon @@ -169,7 +169,13 @@ == :: ++ on-leave on-leave:def - ++ on-peek on-peek:def + ++ on-peek + |= =path + ^- (unit (unit cage)) + ?. ?=([%x %synced ~] path) + (on-peek:def path) + ``noun+!>(~(key by synced)) + :: ++ on-arvo on-arvo:def ++ on-fail on-fail:def -- From f5c57911f04ec13b465d7a5be37beb36073b02ce Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 1 Sep 2020 09:01:17 +1000 Subject: [PATCH 02/15] group-store: /y/groups returns a set --- pkg/arvo/app/group-store.hoon | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/pkg/arvo/app/group-store.hoon b/pkg/arvo/app/group-store.hoon index bec2254017..ad22ee200f 100644 --- a/pkg/arvo/app/group-store.hoon +++ b/pkg/arvo/app/group-store.hoon @@ -187,17 +187,7 @@ ^- (unit (unit cage)) ?+ path (on-peek:def path) [%y %groups ~] - =/ =arch - :- ~ - %- malt - %+ turn - ~(tap by groups) - |= [rid=resource *] - ^- [@ta ~] - =/ group=^path - (en-path:resource rid) - [(spat group) ~] - ``noun+!>(arch) + ``noun+!>(~(key by groups)) :: [%x %groups %ship @ @ ~] =/ rid=(unit resource) From 2c91af22c51e40652be3852d105b408e3fb612af Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 1 Sep 2020 09:01:41 +1000 Subject: [PATCH 03/15] metadata-hook: add synced scry --- pkg/arvo/app/metadata-hook.hoon | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/arvo/app/metadata-hook.hoon b/pkg/arvo/app/metadata-hook.hoon index e3acbd0129..e41f1ee752 100644 --- a/pkg/arvo/app/metadata-hook.hoon +++ b/pkg/arvo/app/metadata-hook.hoon @@ -49,7 +49,12 @@ `this :: ++ on-leave on-leave:def - ++ on-peek on-peek:def + ++ on-peek + |= =path + ^- (unit (unit cage)) + ?. ?=([%x %synced ~] path) + (on-peek:def path) + ``noun+!>(~(key by synced)) ++ on-arvo on-arvo:def ++ on-fail on-fail:def ++ on-poke From ca309fb8318676d3120d9d302e7fc68e5ee894b1 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 1 Sep 2020 15:11:17 +1000 Subject: [PATCH 04/15] marks: add hook actions --- pkg/arvo/mar/contact-hook-action.hoon | 10 ++++++++++ pkg/arvo/mar/metadata-hook-action.hoon | 10 ++++++++++ 2 files changed, 20 insertions(+) create mode 100644 pkg/arvo/mar/contact-hook-action.hoon create mode 100644 pkg/arvo/mar/metadata-hook-action.hoon diff --git a/pkg/arvo/mar/contact-hook-action.hoon b/pkg/arvo/mar/contact-hook-action.hoon new file mode 100644 index 0000000000..c6f27976f1 --- /dev/null +++ b/pkg/arvo/mar/contact-hook-action.hoon @@ -0,0 +1,10 @@ +/- *contact-hook +|_ act=contact-hook-action +++ grab |% + ++ noun contact-hook-action + -- +++ grow |% + ++ noun act + -- +++ grad %noun +-- diff --git a/pkg/arvo/mar/metadata-hook-action.hoon b/pkg/arvo/mar/metadata-hook-action.hoon new file mode 100644 index 0000000000..2a457cdf0d --- /dev/null +++ b/pkg/arvo/mar/metadata-hook-action.hoon @@ -0,0 +1,10 @@ +/- *metadata-hook +|_ act=metadata-hook-action +++ grab |% + ++ noun metadata-hook-action + -- +++ grow |% + ++ noun act + -- +++ grad %noun +-- From 361c1203efffb4d9c15060284d9cbda597a58857 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 1 Sep 2020 15:11:48 +1000 Subject: [PATCH 05/15] pull-hook: add /synced scry --- pkg/arvo/lib/pull-hook.hoon | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/arvo/lib/pull-hook.hoon b/pkg/arvo/lib/pull-hook.hoon index 23903fda6e..0195b2c49b 100644 --- a/pkg/arvo/lib/pull-hook.hoon +++ b/pkg/arvo/lib/pull-hook.hoon @@ -209,7 +209,12 @@ =^ cards pull-hook (on-fail:og term tang) [cards this] - ++ on-peek on-peek:def + ++ on-peek + |= =path + ^- (unit (unit cage)) + ?. =(/x/helper/pull-hook/synced path) + (on-peek:og path) + ``noun+!>(~(key by tracking)) -- |_ =bowl:gall +* og ~(. pull-hook bowl) From a810f6c58803e2d1b8a7e9225efc2fd4353d0bb5 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 1 Sep 2020 15:13:06 +1000 Subject: [PATCH 06/15] sane: added %sane app to sanity check state --- pkg/arvo/app/sane.hoon | 288 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 pkg/arvo/app/sane.hoon diff --git a/pkg/arvo/app/sane.hoon b/pkg/arvo/app/sane.hoon new file mode 100644 index 0000000000..86ff4c7056 --- /dev/null +++ b/pkg/arvo/app/sane.hoon @@ -0,0 +1,288 @@ +:: %sane: sanity checker for the landscape suite of applications +:: +:: Userspace currently uses certain identifiers as foreign keys, and +:: expects those foreign keys to exist in a number of locations. +:: +:: These foreign key relationships are prone to breaking during OTAs +:: and there are enough of them that they rarely get tested for +:: manually. %sane is a gall app that will check the validity of +:: these relationships. The MVP will just print the errors as it +:: finds them. +:: +:: Pokes: +:: %off - turn off checking on a reload +:: %lax - check on reload, printing errors +:: %strict - check on reload, aborting commit if invalid +:: %check-print - run a check now, printing errors +:: %check-crash - run a check now, crashing nondeterministically +:: if invalid +:: +:: Currently validates: +:: - Entries in {contact,metadata,group} stores are in sync with +:: their hooks +:: - Each group has its associated metadata and contacts +:: +:: Future validation: +:: - Subscriptions are correctly setup for hooks +:: - Graph store integration +:: +:: + +:: +/- *metadata-store, contacts=contact-store, *group +/+ default-agent, verb, dbug, resource +~% %sane-app ..is ~ +|% ++$ card card:agent:gall +:: ++$ state-zero [%0 =mode] +:: ++$ issues (list tank) +:: ++$ mode ?(%strict %lax %off) +:: ++$ action ?(mode check) +:: ++$ check ?(%check-print %check-crash) +:: +-- +:: +=| state-zero +=* state - +:: +%- agent:dbug +%+ verb | +^- agent:gall +=< +|_ =bowl:gall ++* this . + sane-core +> + sc ~(. sane-core bowl) + def ~(. (default-agent this %|) bowl) +:: +++ on-init + ^- (quip card _this) + :_ this + ~[subscribe-to-agent-builds] +++ on-save !>(state) +:: +:: +++ on-load + |= =vase + =/ old + !<(state-zero vase) + `this(mode mode.old) +:: +:: +++ on-poke + |= [=mark =vase] + ^- (quip card _this) + ?. =(%noun mark) + (on-poke:def mark vase) + ~! action + =/ act=action + !<(action vase) + ?: ?=(^mode act) + `this(mode act) + %- (check-sane:sc act) + `this +:: +:: +++ on-agent on-agent:def +:: +++ on-watch on-watch:def +:: +++ on-leave on-leave:def + +++ on-peek + |= =path + ^- (unit (unit cage)) + ?. ?=([%x %bad-path ~] path) + (on-peek:def path) + ~ +:: +++ on-arvo + |= [=wire =sign-arvo] + ?> ?=([%rebuilds ~] wire) + ?> ?=([%c %wris *] sign-arvo) + =/ ucheck + check-type:sc + :_ this + %. ~[subscribe-to-agent-builds] + ?~ ucheck same + (check-sane:sc u.ucheck) +:: +++ on-fail on-fail:def +-- +:: +|_ =bowl:gall +++ subscribe-to-agent-builds + ^- card + ~& >> "Subscribing..." + =/ =mool:clay + :- da+now.bowl + %- ~(gas in *(set [care:clay path])) + :~ [%a /app/metadata-hook/hoon] + [%a /app/metadata-store/hoon] + [%a /app/group-store/hoon] + [%a /app/group-pull-hook/hoon] + [%a /app/group-push-hook/hoon] + [%a /app/contact-store/hoon] + [%a /app/contact-hook/hoon] + == + [%pass /rebuilds %arvo %c %warp our.bowl %home ~ %mult mool] +:: +++ check-type + ^- (unit check) + ?+ mode ~ + %strict `%check-crash + %lax `%check-print + == +:: +++ print + |= [pri=@ud =issues] + ^+ same + %. same + %- %*(. slog pri pri) + issues +:: +++ xor + |* [a=(set) b=(set)] + %- + %~ uni in (~(dif in a) b) + (~(dif in b) a) +:: +++ check-sane + |= =check + ^+ same + =/ =issues + ;: weld + store-hook-desync + metadata-group-desync + contact-group-desync + == + ?~ issues + ((print 1 ~[leaf+"Sane!"]) same) + %- (print 3 issues) + ?: =(%check-print check) + same + =/ failure + ~| %crashing-to-abort-merge + (bex (bex 256)) + same +:: +store-hook-desync: check desync between store and hookk +:: +:: check desync between store and hook for contacts, +:: metadata, group and graph +++ store-hook-desync + ^- issues + =| =issues + |^ + =. issues + metadata-desync + =. issues + contact-desync + issues + ++ report-desync + |= [app=term =(set path)] + ^+ issues + %+ weld + issues + %+ turn + ~(tap in set) + |= =path + `tank`leaf+"store-hook desync: {}: {}" + :: + ++ metadata-desync + ^+ issues + =/ groups=(set path) + =- ~(key by -) + (scry (jug path md-resource) /y/metadata-store/group-indices) + =/ group-syncs + (scry (set path) /x/metadata-hook/synced/noun) + =/ desyncs=(set path) + (xor groups group-syncs) + (report-desync %metadata-store desyncs) + ++ contact-desync + ^+ issues + =/ contacts + contact-store-paths + =/ contact-syncs + (scry (set path) /x/contact-hook/synced/noun) + =/ desyncs + (xor contact-syncs contacts) + (report-desync %contact-store desyncs) + -- +:: +metadata-group-desync: check desync between metadata and groups +:: +++ metadata-group-desync + ^- issues + =/ groups=(set path) + group-store-paths + =/ metadata + metadata-store-paths + =/ desyncs + (xor groups metadata) + %+ turn + ~(tap in desyncs) + |= =path + leaf+"metadata-group-desync: {}" +:: +contact-group-desync: check desync between contacts and groups +:: +++ contact-group-desync + ^- issues + =/ groups=(set path) + managed-group-store-paths + =/ contacts + contact-store-paths + =/ desyncs + (xor contacts groups) + %+ turn + ~(tap in desyncs) + |= =path + leaf+"contact-group-desync: {}" +:: +++ contact-store-paths + ^- (set path) + %- %~ del in + ~(key by (scry rolodex:contacts /x/contact-store/all/noun)) + /~/default +:: +++ metadata-store-paths + ^- (set path) + ~(key by (scry (jug path md-resource) /y/metadata-store/group-indices)) +:: +++ group-store-paths + ^- (set path) + %- sy + %+ turn + ^- (list resource) + ~(tap in (scry (set resource) /y/group-store/groups)) + en-path:resource +:: +++ managed-group-store-paths + %- sy + ^- (list path) + %+ murn + ~(tap in group-store-paths) + |= =path + ^- (unit ^path) + =/ scry-pax=^path + :(weld /x/group-store/groups path /noun) + ?: hidden:(need (scry (unit group) scry-pax)) + ~ + `path +:: +++ scry + |* [=mold =path] + ^- mold + ?> ?=(^ path) + ?> ?=(^ t.path) + .^ mold + (cat 3 %g i.path) + (scot %p our.bowl) + i.t.path + (scot %da now.bowl) + t.t.path + == +-- From 8b23703dbba79f5c5b28b3c8c0071b5ee610c6ac Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 8 Sep 2020 15:26:43 +1000 Subject: [PATCH 07/15] sane: address review comments --- pkg/arvo/app/sane.hoon | 47 ++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/pkg/arvo/app/sane.hoon b/pkg/arvo/app/sane.hoon index 86ff4c7056..dc33515cbe 100644 --- a/pkg/arvo/app/sane.hoon +++ b/pkg/arvo/app/sane.hoon @@ -26,8 +26,6 @@ :: - Subscriptions are correctly setup for hooks :: - Graph store integration :: -:: - :: /- *metadata-store, contacts=contact-store, *group /+ default-agent, verb, dbug, resource @@ -66,34 +64,26 @@ ~[subscribe-to-agent-builds] ++ on-save !>(state) :: -:: ++ on-load |= =vase - =/ old - !<(state-zero vase) + =/ old !<(state-zero vase) `this(mode mode.old) :: -:: ++ on-poke |= [=mark =vase] ^- (quip card _this) ?. =(%noun mark) (on-poke:def mark vase) - ~! action - =/ act=action - !<(action vase) + =/ act=action !<(action vase) ?: ?=(^mode act) `this(mode act) %- (check-sane:sc act) `this :: -:: ++ on-agent on-agent:def -:: ++ on-watch on-watch:def -:: ++ on-leave on-leave:def - +:: ++ on-peek |= =path ^- (unit (unit cage)) @@ -105,8 +95,7 @@ |= [=wire =sign-arvo] ?> ?=([%rebuilds ~] wire) ?> ?=([%c %wris *] sign-arvo) - =/ ucheck - check-type:sc + =/ ucheck check-type:sc :_ this %. ~[subscribe-to-agent-builds] ?~ ucheck same @@ -116,6 +105,7 @@ -- :: |_ =bowl:gall +:: ++ subscribe-to-agent-builds ^- card ~& >> "Subscribing..." @@ -148,9 +138,7 @@ :: ++ xor |* [a=(set) b=(set)] - %- - %~ uni in (~(dif in a) b) - (~(dif in b) a) + (~(uni in (~(dif in a) b)) (~(dif in b) a)) :: ++ check-sane |= =check @@ -170,7 +158,7 @@ ~| %crashing-to-abort-merge (bex (bex 256)) same -:: +store-hook-desync: check desync between store and hookk +:: +store-hook-desync: check desync between store and hook :: :: check desync between store and hook for contacts, :: metadata, group and graph @@ -183,6 +171,7 @@ =. issues contact-desync issues + :: ++ report-desync |= [app=term =(set path)] ^+ issues @@ -203,6 +192,7 @@ =/ desyncs=(set path) (xor groups group-syncs) (report-desync %metadata-store desyncs) + :: ++ contact-desync ^+ issues =/ contacts @@ -212,17 +202,15 @@ =/ desyncs (xor contact-syncs contacts) (report-desync %contact-store desyncs) + :: -- :: +metadata-group-desync: check desync between metadata and groups :: ++ metadata-group-desync ^- issues - =/ groups=(set path) - group-store-paths - =/ metadata - metadata-store-paths - =/ desyncs - (xor groups metadata) + =/ groups=(set path) group-store-paths + =/ metadata metadata-store-paths + =/ desyncs (xor groups metadata) %+ turn ~(tap in desyncs) |= =path @@ -231,12 +219,9 @@ :: ++ contact-group-desync ^- issues - =/ groups=(set path) - managed-group-store-paths - =/ contacts - contact-store-paths - =/ desyncs - (xor contacts groups) + =/ groups=(set path) managed-group-store-paths + =/ contacts contact-store-paths + =/ desyncs (xor contacts groups) %+ turn ~(tap in desyncs) |= =path From 1ed07f32954cbac8e548f41bb1b21390dc48618d Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Wed, 25 Nov 2020 16:01:07 +1000 Subject: [PATCH 08/15] pull-hook: restart subscriptions in on-load --- pkg/arvo/lib/pull-hook.hoon | 71 +++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/pkg/arvo/lib/pull-hook.hoon b/pkg/arvo/lib/pull-hook.hoon index 2c4895db56..c24446673f 100644 --- a/pkg/arvo/lib/pull-hook.hoon +++ b/pkg/arvo/lib/pull-hook.hoon @@ -162,33 +162,44 @@ =| cards=(list card:agent:gall) |^ ?- -.old + %0 $(-.old %1) + :: %1 =^ og-cards pull-hook (on-load:og inner-state.old) - [(weld cards og-cards) this(state old)] - :: - %0 - %_ $ - -.old %1 - :: - cards - (weld cards (missing-subscriptions tracking.old)) - == + =. state old + =/ restart-cards + (restart-subscriptions tracking.old) + :_ this + :(weld restart-cards cards og-cards) == - ++ missing-subscriptions - |= tracking=(map resource ship) + :: + ++ check-subscription + |= [rid=resource =ship] + ^- ? + %+ lien + ~(tap in ~(key by wex.bowl)) + |= [=wire her=^ship app=term] + ^- ? + ?& =(app push-hook-name.config) + =(ship her) + =((scag 4 wire) /helper/pull-hook/pull/resource) + =(`rid (de-path-soft:resource (slag 4 wire))) + == + :: + ++ restart-subscriptions + |= pulling=(map resource ship) ^- (list card:agent:gall) %+ murn - ~(tap by tracking) - |= [rid=resource =ship] + ~(tap by pulling) + |= [rid=resource =ship] ^- (unit card:agent:gall) - =/ =path - resource+(en-path:resource rid) - =/ =wire - (make-wire pull+path) - ?: (~(has by wex.bowl) [wire ship push-hook-name.config]) - ~ - `[%pass wire %agent [ship push-hook-name.config] %watch path] + ?: (check-subscription rid ship) ~ + ~& >> "restarting: {}" + =/ pax=(unit path) + (on-pull-kick:og rid) + ?~ pax ~ + `(watch-resource:hc rid u.pax) -- :: ++ on-save @@ -196,6 +207,7 @@ =. inner-state on-save:og !>(state) + :: ++ on-poke |= [=mark =vase] ^- [(list card:agent:gall) agent:gall] @@ -310,18 +322,23 @@ :: ++ remove |= =resource - :- ~[(leave-resource resource)] + :- (leave-resource resource) state(tracking (~(del by tracking) resource)) -- :: ++ leave-resource |= rid=resource - ^- card - =/ =ship - (~(got by tracking) rid) - =/ =wire - (make-wire pull+resource+(en-path:resource rid)) - [%pass wire %agent [ship push-hook-name.config] %leave ~] + ^- (list card) + %+ roll + ~(tap in ~(key by wex.bowl)) + |= [[=wire her=ship app=term] out=(list card)] + ?. =(`rid (de-path-soft:resource (slag 4 wire))) + out + =/ him=(unit ship) + (~(get by tracking) rid) + ?. =(`her him) out + :_ out + [%pass wire %agent [her push-hook-name.config] %leave ~] ++ watch-resource |= [rid=resource pax=path] From ec3f404325f895e6f0f38c1a6f72d0e8b9c8521b Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Mon, 30 Nov 2020 13:34:55 +1000 Subject: [PATCH 09/15] pull-hook: move subscription restart to %sane poke --- pkg/arvo/lib/pull-hook.hoon | 100 ++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 43 deletions(-) diff --git a/pkg/arvo/lib/pull-hook.hoon b/pkg/arvo/lib/pull-hook.hoon index c24446673f..b69a871978 100644 --- a/pkg/arvo/lib/pull-hook.hoon +++ b/pkg/arvo/lib/pull-hook.hoon @@ -160,47 +160,19 @@ =/ old !<(versioned-state old-vase) =| cards=(list card:agent:gall) - |^ + |- ?- -.old - %0 $(-.old %1) + %0 $(-.old %1) :: %1 =^ og-cards pull-hook (on-load:og inner-state.old) - =. state old - =/ restart-cards - (restart-subscriptions tracking.old) - :_ this - :(weld restart-cards cards og-cards) + =. cards + :_ cards + [%pass / %agent [our.bowl dap.bowl] %poke %sane !>(%sane)] + :_ this(state old) + (weld cards og-cards) == - :: - ++ check-subscription - |= [rid=resource =ship] - ^- ? - %+ lien - ~(tap in ~(key by wex.bowl)) - |= [=wire her=^ship app=term] - ^- ? - ?& =(app push-hook-name.config) - =(ship her) - =((scag 4 wire) /helper/pull-hook/pull/resource) - =(`rid (de-path-soft:resource (slag 4 wire))) - == - :: - ++ restart-subscriptions - |= pulling=(map resource ship) - ^- (list card:agent:gall) - %+ murn - ~(tap by pulling) - |= [rid=resource =ship] - ^- (unit card:agent:gall) - ?: (check-subscription rid ship) ~ - ~& >> "restarting: {}" - =/ pax=(unit path) - (on-pull-kick:og rid) - ?~ pax ~ - `(watch-resource:hc rid u.pax) - -- :: ++ on-save ^- vase @@ -212,13 +184,21 @@ |= [=mark =vase] ^- [(list card:agent:gall) agent:gall] ?> (team:title our.bowl src.bowl) - ?. =(mark %pull-hook-action) - =^ cards pull-hook - (on-poke:og mark vase) - [cards this] - =^ cards state - (poke-hook-action:hc !<(action vase)) - [cards this] + ?+ mark + =^ cards pull-hook + (on-poke:og mark vase) + [cards this] + :: + %sane + =^ cards state + poke-sane:hc + [cards this] + :: + %pull-hook-action + =^ cards state + (poke-hook-action:hc !<(action vase)) + [cards this] + == :: ++ on-watch |= =path @@ -294,12 +274,46 @@ ++ on-peek |= =path ^- (unit (unit cage)) - ?. =(/x/helper/pull-hook/synced path) + ?. =(/x/tracking path) (on-peek:og path) ``noun+!>(~(key by tracking)) -- |_ =bowl:gall +* og ~(. pull-hook bowl) + ++ poke-sane + ^- (quip card:agent:gall _state) + =/ cards + restart-subscriptions + ~? > ?=(^ cards) + "Fixed subscriptions in {}" + :_ state + restart-subscriptions + :: + ++ check-subscription + |= [rid=resource =ship] + ^- ? + %+ lien + ~(tap in ~(key by wex.bowl)) + |= [=wire her=^ship app=term] + ^- ? + ?& =(app push-hook-name.config) + =(ship her) + =((scag 4 wire) /helper/pull-hook/pull/resource) + =(`rid (de-path-soft:resource (slag 4 wire))) + == + :: + ++ restart-subscriptions + ^- (list card:agent:gall) + %+ murn + ~(tap by tracking) + |= [rid=resource =ship] + ^- (unit card:agent:gall) + ?: (check-subscription rid ship) ~ + ~& >> "restarting: {}" + =/ pax=(unit path) + (on-pull-kick:og rid) + ?~ pax ~ + `(watch-resource rid u.pax) :: ++ poke-hook-action |= =action From 5b7802a3a6c4a14b2931f16988de7eb45f634b2f Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Mon, 30 Nov 2020 13:35:11 +1000 Subject: [PATCH 10/15] push-hook: add /x/sharing scry --- pkg/arvo/lib/push-hook.hoon | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/arvo/lib/push-hook.hoon b/pkg/arvo/lib/push-hook.hoon index 9553745eb1..18d0b3e7bf 100644 --- a/pkg/arvo/lib/push-hook.hoon +++ b/pkg/arvo/lib/push-hook.hoon @@ -285,7 +285,12 @@ =^ cards push-hook (on-fail:og term tang) [cards this] - ++ on-peek on-peek:og + ++ on-peek + |= =path + ^- (unit (unit cage)) + ?. =(/x/sharing path) + (on-peek:og path) + ``noun+!>(sharing) -- |_ =bowl:gall +* og ~(. push-hook bowl) From 8145e66078d10953292cf62cb65ed37121d240bf Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Mon, 30 Nov 2020 13:35:26 +1000 Subject: [PATCH 11/15] chat-hook: add /x/synced scry --- pkg/arvo/app/chat-hook.hoon | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/arvo/app/chat-hook.hoon b/pkg/arvo/app/chat-hook.hoon index 340d1e6c14..f5e3d87f8e 100644 --- a/pkg/arvo/app/chat-hook.hoon +++ b/pkg/arvo/app/chat-hook.hoon @@ -417,7 +417,12 @@ == :: ++ on-leave on-leave:def - ++ on-peek on-peek:def + ++ on-peek + |= =path + ^- (unit (unit cage)) + ?. =(/x/synced path) + (on-peek:def path) + ``noun+!>(~(key by synced)) ++ on-arvo on-arvo:def ++ on-fail on-fail:def -- From 3d51d6827f8cf30bee284109f688b73a2a9e5f77 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Mon, 30 Nov 2020 13:36:03 +1000 Subject: [PATCH 12/15] sane: refactor to automatically fix issues --- pkg/arvo/app/sane.hoon | 378 ++++++++++++++++++++++------------------- 1 file changed, 203 insertions(+), 175 deletions(-) diff --git a/pkg/arvo/app/sane.hoon b/pkg/arvo/app/sane.hoon index dc33515cbe..b012adfd18 100644 --- a/pkg/arvo/app/sane.hoon +++ b/pkg/arvo/app/sane.hoon @@ -6,43 +6,42 @@ :: These foreign key relationships are prone to breaking during OTAs :: and there are enough of them that they rarely get tested for :: manually. %sane is a gall app that will check the validity of -:: these relationships. The MVP will just print the errors as it -:: finds them. +:: these relationships, and fix them if asked. +:: +:: Sane has a companion thread, -sane, which should be run instead +:: of attempting :sane %fix directly from the dojo. :: :: Pokes: -:: %off - turn off checking on a reload -:: %lax - check on reload, printing errors -:: %strict - check on reload, aborting commit if invalid -:: %check-print - run a check now, printing errors -:: %check-crash - run a check now, crashing nondeterministically -:: if invalid -:: +:: %fix - Find issues and fix them +:: %check - Find issues and print them +:: :: Currently validates: :: - Entries in {contact,metadata,group} stores are in sync with :: their hooks :: - Each group has its associated metadata and contacts -:: -:: Future validation: -:: - Subscriptions are correctly setup for hooks -:: - Graph store integration -:: +:: - Each graph is being synced +:: - Each chat is being synced :: /- *metadata-store, contacts=contact-store, *group -/+ default-agent, verb, dbug, resource +/+ default-agent, verb, dbug, resource, graph, mdl=metadata, group ~% %sane-app ..is ~ |% +$ card card:agent:gall :: -+$ state-zero [%0 =mode] ++$ state-zero [%0 ~] :: -+$ issues (list tank) ++$ issue + $% [%lib-pull-hook-desync app=term =resource] + [%lib-push-hook-desync app=term =resource] + [%md-hook-desync =path] + [%contact-hook-desync =path] + [%chat-desync =path] + == :: -+$ mode ?(%strict %lax %off) -:: -+$ action ?(mode check) -:: -+$ check ?(%check-print %check-crash) ++$ issues + (list issue) :: ++$ action ?(%check %fix) -- :: =| state-zero @@ -60,14 +59,12 @@ :: ++ on-init ^- (quip card _this) - :_ this - ~[subscribe-to-agent-builds] + `this ++ on-save !>(state) :: ++ on-load |= =vase - =/ old !<(state-zero vase) - `this(mode mode.old) + `this :: ++ on-poke |= [=mark =vase] @@ -75,10 +72,12 @@ ?. =(%noun mark) (on-poke:def mark vase) =/ act=action !<(action vase) - ?: ?=(^mode act) - `this(mode act) - %- (check-sane:sc act) - `this + =^ cards state + ?- act + %fix fix-sane:sc + %check print-sane:sc + == + [cards this] :: ++ on-agent on-agent:def ++ on-watch on-watch:def @@ -91,172 +90,201 @@ (on-peek:def path) ~ :: -++ on-arvo - |= [=wire =sign-arvo] - ?> ?=([%rebuilds ~] wire) - ?> ?=([%c %wris *] sign-arvo) - =/ ucheck check-type:sc - :_ this - %. ~[subscribe-to-agent-builds] - ?~ ucheck same - (check-sane:sc u.ucheck) -:: +++ on-arvo on-arvo:def ++ on-fail on-fail:def -- :: |_ =bowl:gall :: -++ subscribe-to-agent-builds - ^- card - ~& >> "Subscribing..." - =/ =mool:clay - :- da+now.bowl - %- ~(gas in *(set [care:clay path])) - :~ [%a /app/metadata-hook/hoon] - [%a /app/metadata-store/hoon] - [%a /app/group-store/hoon] - [%a /app/group-pull-hook/hoon] - [%a /app/group-push-hook/hoon] - [%a /app/contact-store/hoon] - [%a /app/contact-hook/hoon] - == - [%pass /rebuilds %arvo %c %warp our.bowl %home ~ %mult mool] +++ gra ~(. graph bowl) :: -++ check-type - ^- (unit check) - ?+ mode ~ - %strict `%check-crash - %lax `%check-print - == +++ md ~(. mdl bowl) :: -++ print - |= [pri=@ud =issues] - ^+ same - %. same - %- %*(. slog pri pri) - issues +++ grp ~(. group bowl) :: -++ xor - |* [a=(set) b=(set)] - (~(uni in (~(dif in a) b)) (~(dif in b) a)) -:: -++ check-sane - |= =check - ^+ same - =/ =issues - ;: weld - store-hook-desync - metadata-group-desync - contact-group-desync - == - ?~ issues - ((print 1 ~[leaf+"Sane!"]) same) - %- (print 3 issues) - ?: =(%check-print check) - same - =/ failure - ~| %crashing-to-abort-merge - (bex (bex 256)) - same -:: +store-hook-desync: check desync between store and hook -:: -:: check desync between store and hook for contacts, -:: metadata, group and graph -++ store-hook-desync - ^- issues - =| =issues - |^ - =. issues - metadata-desync - =. issues - contact-desync - issues +++ foreign-keys + |_ =issues + ++ fk-core . :: - ++ report-desync - |= [app=term =(set path)] + ++ abet ^+ issues - %+ weld - issues + issues + :: + ++ abet-fix + ^- (list card) + (turn issues fix-issue) + :: + ++ report + |= =issue + fk-core(issues (snoc issues issue)) + :: + ++ report-many + |= many=^issues + fk-core(issues (weld issues many)) + :: + ++ check-all + => (lib-hooks-desync %group scry-groups) + => (lib-hooks-desync %graph get-keys:gra) + groups + :: + ++ chat + ^+ fk-core + =/ missing=(set path) + (~(dif in scry-chats) scry-chat-syncs) + %- report-many %+ turn - ~(tap in set) + ~(tap in missing) |= =path - `tank`leaf+"store-hook desync: {}: {}" + ^- issue + [%chat-desync path] :: - ++ metadata-desync - ^+ issues - =/ groups=(set path) - =- ~(key by -) - (scry (jug path md-resource) /y/metadata-store/group-indices) - =/ group-syncs - (scry (set path) /x/metadata-hook/synced/noun) - =/ desyncs=(set path) - (xor groups group-syncs) - (report-desync %metadata-store desyncs) - :: - ++ contact-desync - ^+ issues - =/ contacts - contact-store-paths - =/ contact-syncs - (scry (set path) /x/contact-hook/synced/noun) - =/ desyncs - (xor contact-syncs contacts) - (report-desync %contact-store desyncs) + ++ groups + ^+ fk-core + =/ groups=(list resource) + ~(tap in scry-groups) + |- + ?~ groups + fk-core + =* group i.groups + =? fk-core !(~(has in scry-md-syncs) group) + (report %md-hook-desync (en-path:resource group)) + =? fk-core &((is-managed:grp group) !(~(has in scry-contact-syncs) group)) + (report %contact-hook-desync (en-path:resource group)) + $(groups t.groups) :: + ++ lib-hooks-desync + |= [app=term storing=(set resource)] + ^+ fk-core + =/ tracking + (tracking-pull-hook (pull-hook-name app)) + =/ sharing + (sharing-push-hook (push-hook-name app)) + =/ resources + ~(tap in storing) + |- + ?~ resources + fk-core + =* rid i.resources + =? fk-core &(=(our.bowl entity.rid) !(~(has in sharing) rid)) + (report %lib-push-hook-desync (push-hook-name app) rid) + =? fk-core &(!=(our.bowl entity.rid) !(~(has in tracking) rid)) + (report %lib-pull-hook-desync (pull-hook-name app) rid) + $(resources t.resources) -- -:: +metadata-group-desync: check desync between metadata and groups :: -++ metadata-group-desync - ^- issues - =/ groups=(set path) group-store-paths - =/ metadata metadata-store-paths - =/ desyncs (xor groups metadata) - %+ turn - ~(tap in desyncs) - |= =path - leaf+"metadata-group-desync: {}" -:: +contact-group-desync: check desync between contacts and groups +++ pull-hook-name + |= app=term + :(join-cord app '-' %pull-hook) :: -++ contact-group-desync - ^- issues - =/ groups=(set path) managed-group-store-paths - =/ contacts contact-store-paths - =/ desyncs (xor contacts groups) - %+ turn - ~(tap in desyncs) - |= =path - leaf+"contact-group-desync: {}" +++ push-hook-name + |= app=term + :(join-cord app '-' %push-hook) :: -++ contact-store-paths +++ fix-sane + ^- (quip card _state) + =/ cards=(list card) + => foreign-keys + => check-all + abet-fix + [cards state] +:: +++ print-sane + ^- (quip card _state) + =/ =issues + => foreign-keys + => check-all + abet + `state +:: +++ fix-issue + |= =issue + ^- card + |^ + ?- -.issue + :: + %lib-pull-hook-desync + =* rid resource.issue + (poke-our app.issue pull-hook-action+!>([%add entity.rid rid])) + :: + %lib-push-hook-desync + (poke-our app.issue push-hook-action+!>([%add resource.issue])) + :: + %md-hook-desync + =/ rid=resource + (de-path:resource path.issue) + =/ act + ?: =(entity.rid our.bowl) + [%add-owned path.issue] + [%add-synced entity.rid path.issue] + (poke-our %metadata-hook metadata-hook-action+!>(act)) + :: + %contact-hook-desync + =/ rid=resource + (de-path:resource path.issue) + =/ act + ?: =(entity.rid our.bowl) + [%add-owned path.issue] + [%add-synced entity.rid path.issue] + (poke-our %contact-hook contact-hook-action+!>(act)) + %chat-desync + =/ =ship + (slav %p (snag 0 path.issue)) + =/ act + ?: =(ship our.bowl) + [%add-owned path.issue %.n] + [%add-synced ship path.issue %.n] + (poke-our %chat-hook chat-hook-action+!>(act)) + == + :: + ++ poke-our + |= [app=term =cage] + ^- card + [%pass /fix %agent [our.bowl app] %poke cage] + -- +:: +++ join-cord + (cury cat 3) +:: +++ scry-groups + (scry ,(set resource) /y/group-store/groups) +:: +++ tracking-pull-hook + |= hook=term + %+ scry + ,(set resource) + /x/[hook]/tracking/noun +:: +++ sharing-push-hook + |= hook=term + %+ scry + ,(set resource) + /x/[hook]/sharing/noun +:: +++ scry-md-syncs + ^- (set resource) + =- (~(run in -) de-path:resource) + %+ scry + ,(set path) + /x/metadata-hook/synced/noun +:: +++ scry-contact-syncs + ^- (set resource) + =- (~(run in -) de-path:resource) + %+ scry + ,(set path) + /x/contact-hook/synced/noun +:: +++ scry-chat-syncs ^- (set path) - %- %~ del in - ~(key by (scry rolodex:contacts /x/contact-store/all/noun)) - /~/default + %+ scry + ,(set path) + /x/chat-hook/synced/noun :: -++ metadata-store-paths +++ scry-chats ^- (set path) - ~(key by (scry (jug path md-resource) /y/metadata-store/group-indices)) -:: -++ group-store-paths - ^- (set path) - %- sy - %+ turn - ^- (list resource) - ~(tap in (scry (set resource) /y/group-store/groups)) - en-path:resource -:: -++ managed-group-store-paths - %- sy - ^- (list path) - %+ murn - ~(tap in group-store-paths) - |= =path - ^- (unit ^path) - =/ scry-pax=^path - :(weld /x/group-store/groups path /noun) - ?: hidden:(need (scry (unit group) scry-pax)) - ~ - `path + %+ scry + ,(set path) + /x/chat-store/keys/noun :: ++ scry |* [=mold =path] From f5524924149edcdccbf08320cf8d6fa5a6c5a2e6 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Mon, 30 Nov 2020 13:44:31 +1000 Subject: [PATCH 13/15] ted/sane: add thread to run sanity checking --- pkg/arvo/ted/sane.hoon | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 pkg/arvo/ted/sane.hoon diff --git a/pkg/arvo/ted/sane.hoon b/pkg/arvo/ted/sane.hoon new file mode 100644 index 0000000000..c4f1830edd --- /dev/null +++ b/pkg/arvo/ted/sane.hoon @@ -0,0 +1,30 @@ +/- spider +/+ *strandio +=> +|% +++ strand strand:spider +:: +++ supported-apps + ^- (list term) + :~ %graph-pull-hook + %group-pull-hook + == +:: +++ poke-all-sane + =/ m (strand ,~) + ^- form:m + =/ apps supported-apps + |- =* loop $ + ?~ apps + (pure:m ~) + =* app i.apps + ;< ~ bind:m (poke-our app sane+!>(%sane)) + loop(apps t.apps) +-- +:: +^- thread:spider +|= vase +=/ m (strand ,vase) +;< ~ bind:m poke-all-sane +;< ~ bind:m (poke-our %sane noun+!>(%fix)) +(pure:m !>("Done")) From 2caf1dac24b5a565d99b0ed4b5c480686b71d40e Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Thu, 3 Dec 2020 15:58:32 +1000 Subject: [PATCH 14/15] group-push-hook: kick members who are not subscribed If a ship breaches, it may no longer be subscribed to the group, but still be in it. This causes DM breakage amongst other things. To fix it, we loop over the incoming subscriptions and kick everyone who is a part of a group, but not subscribed to it. --- pkg/arvo/app/group-push-hook.hoon | 63 ++++++++++++++++++++++++++++++- pkg/arvo/ted/sane.hoon | 1 + 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/pkg/arvo/app/group-push-hook.hoon b/pkg/arvo/app/group-push-hook.hoon index 7e5215fa02..f243982e90 100644 --- a/pkg/arvo/app/group-push-hook.hoon +++ b/pkg/arvo/app/group-push-hook.hoon @@ -36,7 +36,68 @@ ++ on-init on-init:def ++ on-save !>(~) ++ on-load on-load:def -++ on-poke on-poke:def +++ on-poke + |= [=mark =vase] + ^- (quip card _this) + |^ + ?. =(mark %sane) + (on-poke:def mark vase) + [sane this] + :: + ++ scry-sharing + .^ (set resource) + %gx + (scot %p our.bowl) + %group-push-hook + (scot %da now.bowl) + /sharing/noun + == + :: + ++ sane + ^- (list card) + %+ murn + ~(tap in scry-sharing) + |= rid=resource + ^- (unit card) + =/ u-g=(unit group) + (scry-group:grp rid) + ?~ u-g + `(poke-us %remove rid) + =* group u.u-g + =/ subs=(set ship) + (get-subscribers-for-group rid) + =/ to-remove=(set ship) + (~(dif in members.group) subs) + ?~ to-remove ~ + `(poke-store %remove-members rid to-remove) + :: + ++ poke-us + |= =action:push-hook + ^- card + =- [%pass / %agent [our.bowl %group-push-hook] %poke -] + push-hook-action+!>(action) + :: + ++ poke-store + |= =update:store + ^- card + =+ group-update+!>(update) + [%pass /sane %agent [our.bowl %group-store] %poke -] + :: + ++ get-subscribers-for-group + |= rid=resource + ^- (set ship) + =/ target=path + (en-path:resource rid) + %- ~(gas in *(set ship)) + %+ murn + ~(val by sup.bowl) + |= [her=ship =path] + ^- (unit ship) + ?. =(path resource+target) + ~ + `her + -- + ++ on-agent on-agent:def ++ on-watch on-watch:def ++ on-leave on-leave:def diff --git a/pkg/arvo/ted/sane.hoon b/pkg/arvo/ted/sane.hoon index c4f1830edd..e02d38f129 100644 --- a/pkg/arvo/ted/sane.hoon +++ b/pkg/arvo/ted/sane.hoon @@ -8,6 +8,7 @@ ^- (list term) :~ %graph-pull-hook %group-pull-hook + %group-push-hook == :: ++ poke-all-sane From aec6b1d754358d4453c17edf6c40b8e9a1fedc40 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 12 Jan 2021 14:52:52 +1000 Subject: [PATCH 15/15] sane: add dangling metadata checker --- pkg/arvo/app/sane.hoon | 64 ++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/pkg/arvo/app/sane.hoon b/pkg/arvo/app/sane.hoon index b012adfd18..b70296cc06 100644 --- a/pkg/arvo/app/sane.hoon +++ b/pkg/arvo/app/sane.hoon @@ -24,7 +24,7 @@ :: /- *metadata-store, contacts=contact-store, *group /+ default-agent, verb, dbug, resource, graph, mdl=metadata, group -~% %sane-app ..is ~ +~% %sane-app ..card ~ |% +$ card card:agent:gall :: @@ -35,7 +35,7 @@ [%lib-push-hook-desync app=term =resource] [%md-hook-desync =path] [%contact-hook-desync =path] - [%chat-desync =path] + [%dangling-md =path] == :: +$ issues @@ -112,7 +112,7 @@ :: ++ abet-fix ^- (list card) - (turn issues fix-issue) + (zing (turn issues fix-issue)) :: ++ report |= =issue @@ -125,18 +125,8 @@ ++ check-all => (lib-hooks-desync %group scry-groups) => (lib-hooks-desync %graph get-keys:gra) - groups - :: - ++ chat - ^+ fk-core - =/ missing=(set path) - (~(dif in scry-chats) scry-chat-syncs) - %- report-many - %+ turn - ~(tap in missing) - |= =path - ^- issue - [%chat-desync path] + => groups + metadata :: ++ groups ^+ fk-core @@ -152,6 +142,19 @@ (report %contact-hook-desync (en-path:resource group)) $(groups t.groups) :: + ++ metadata + ^+ fk-core + =/ md-groups=(list path) + ~(tap in ~(key by md-group-indices)) + |- + ?~ md-groups + fk-core + =/ rid=resource + (de-path:resource i.md-groups) + =? fk-core !(~(has in scry-groups) rid) + (report %dangling-md i.md-groups) + $(md-groups t.md-groups) + :: ++ lib-hooks-desync |= [app=term storing=(set resource)] ^+ fk-core @@ -194,20 +197,21 @@ => foreign-keys => check-all abet + ~& issues `state :: ++ fix-issue |= =issue - ^- card |^ + ^- (list card) ?- -.issue :: %lib-pull-hook-desync =* rid resource.issue - (poke-our app.issue pull-hook-action+!>([%add entity.rid rid])) + (poke-our app.issue pull-hook-action+!>([%add entity.rid rid]))^~ :: %lib-push-hook-desync - (poke-our app.issue push-hook-action+!>([%add resource.issue])) + (poke-our app.issue push-hook-action+!>([%add resource.issue]))^~ :: %md-hook-desync =/ rid=resource @@ -216,7 +220,7 @@ ?: =(entity.rid our.bowl) [%add-owned path.issue] [%add-synced entity.rid path.issue] - (poke-our %metadata-hook metadata-hook-action+!>(act)) + (poke-our %metadata-hook metadata-hook-action+!>(act))^~ :: %contact-hook-desync =/ rid=resource @@ -225,15 +229,16 @@ ?: =(entity.rid our.bowl) [%add-owned path.issue] [%add-synced entity.rid path.issue] - (poke-our %contact-hook contact-hook-action+!>(act)) - %chat-desync - =/ =ship - (slav %p (snag 0 path.issue)) - =/ act - ?: =(ship our.bowl) - [%add-owned path.issue %.n] - [%add-synced ship path.issue %.n] - (poke-our %chat-hook chat-hook-action+!>(act)) + (poke-our %contact-hook contact-hook-action+!>(act))^~ + :: + %dangling-md + =/ app-indices + (~(get ju md-group-indices) path.issue) + %+ turn + ~(tap in app-indices) + |= =md-resource + ^- card + (poke-our %metadata-store metadata-action+!>([%remove path.issue md-resource])) == :: ++ poke-our @@ -286,6 +291,9 @@ ,(set path) /x/chat-store/keys/noun :: +++ md-group-indices + (scry (jug group-path md-resource) /y/metadata-store/group-indices) +:: ++ scry |* [=mold =path] ^- mold