From 6ad92cfeb7ba494c4fa7cde3b8eb11109d46ec2a Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Thu, 9 Feb 2023 14:05:23 -0500 Subject: [PATCH 001/152] boiler plate for loch --- pkg/arvo/sys/arvo.hoon | 1 + pkg/arvo/sys/lull.hoon | 20 +++++ pkg/arvo/sys/vane/loch.hoon | 160 ++++++++++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 pkg/arvo/sys/vane/loch.hoon diff --git a/pkg/arvo/sys/arvo.hoon b/pkg/arvo/sys/arvo.hoon index 9d97a1d9c5..9a9fde830a 100644 --- a/pkg/arvo/sys/arvo.hoon +++ b/pkg/arvo/sys/arvo.hoon @@ -1724,6 +1724,7 @@ %i %iris %j %jael %k %khan + %l %loch == -- => :: diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index e05500f747..f6bb63d6a3 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -2293,6 +2293,22 @@ :: :: +$ shed _*form:(strand:rand ,vase) :: compute vase -- ::khan +:: :::: +:::: ++loch :: (1b) timekeeping + :: :::: +++ loch ^? + |% + +$ gift :: out result <-$ + $% [%read p=(unit @da)] :: next alarm + == + +$ task :: in request ->$ + $~ [%vega ~] :: + $% $>(%born vane-task) :: new unix process + $>(%trim vane-task) :: trim state + $>(%vega vane-task) :: report upgrade + == + -- ::loch + :: ++ rand :: computation |% @@ -2495,6 +2511,7 @@ gift:iris gift:jael gift:khan + gift:loch == +$ task-arvo :: in request ->$ $% task:ames @@ -2506,6 +2523,7 @@ task:iris task:jael task:khan + task:loch == +$ note-arvo :: out request $-> $~ [%b %wake ~] @@ -2518,6 +2536,7 @@ [%i task:iris] [%j task:jael] [%k task:khan] + [%l task:loch] [%$ %whiz ~] [@tas %meta vase] == @@ -2540,6 +2559,7 @@ [%iris gift:iris] [%jael gift:jael] [%khan gift:khan] + [%loch gift:loch] == :: $unix-task: input from unix :: diff --git a/pkg/arvo/sys/vane/loch.hoon b/pkg/arvo/sys/vane/loch.hoon new file mode 100644 index 0000000000..e073806495 --- /dev/null +++ b/pkg/arvo/sys/vane/loch.hoon @@ -0,0 +1,160 @@ +:: %loch +!: +!? 164 +:: +=, loch +|= our=ship +=> |% + +$ move [p=duct q=(wite note gift)] + +$ note :: out request $-> + $% + $: %j :: to %jael + $>(%step task:jael) + == + $: %d :: to %dill + $>(%flog task:dill) :: log output + == == + :: + +$ sign + $% [%loch $>(%read gift)] :: read + == + :: + +$ loch-state + $: %0 + unix-duct=duct + == + :: + -- +:: +=> +~% %loch ..part ~ +|% +++ per-event + =| moves=(list move) + |= [[now=@da =duct] state=loch-state] + :: + |% + ++ this . + :: %entry-points + :: + :: +crud: handle failure of previous arvo event + :: + ++ crud + |= [tag=@tas error=tang] + ^+ [moves state] + [[duct %slip %d %flog %crud tag error]~ state] + :: +read: give back + :: + ++ read [moves state] + :: +fyrd: commands + :: + ::++ fyrd + ::|= com=^fyrd + ::^+ [moves state] + ::=< [moves state] + ::~& > fyrd+com + ::~! -.com + ::?- -.com + ::%mas ~& todo+com event-core :: |mass + ::%cod + ::::=/ cov + ::[duct %pass %j %step ~]~ + ::::~! move+cov event-core(moves cov) + ::== + :: +born: in response to memory pressue + :: + ++ born [moves state] + :: +trim: in response to memory pressue + :: + ++ trim [moves state] + :: +vega: learn of a kernel upgrade + :: + ++ vega [moves state] + :: %utilities + :: + ::+| + :: + ++ event-core . + -- +-- +:: +=| loch-state +=* state - +|= [now=@da eny=@uvJ rof=roof] +=* loch-gate . +^? +|% +:: +call: handle a +task:loch request +:: +++ call + ~% %loch-call ..part ~ + |= $: hen=duct + dud=(unit goof) + wrapped-task=(hobo task) + == + ^- [(list move) _loch-gate] + :: + =/ =task ((harden task) wrapped-task) + =/ event-core (per-event [now hen] state) + :: + =^ moves state + :: + :: handle error notifications + :: + :: + ?^ dud + (crud:event-core -.task tang.u.dud) + :: + ~! -.task + ?- -.task + %born born:event-core + %trim trim:event-core + %vega vega:event-core :: vega + ::%read read:event-core + == + [moves loch-gate] +:: +load: migrate an old state to a new loch version +:: +++ load + |= old=loch-state + ^+ loch-gate + loch-gate(state old) +:: +scry: view state +:: +++ scry + ^- roon + |= [lyc=gang car=term bem=beam] + ^- (unit (unit cage)) + =* ren car + =* why=shop &/p.bem + =* syd q.bem + =* lot=coin $/r.bem + =* tyl s.bem + + ?: &(=(ren %$) =(tyl /whey)) + =/ maz=(list mass) + :~ state+&+state + == + ``mass+!>(maz) + :: only respond for the local identity, %$ desk, current timestamp + :: + ?. ?& =(&+our why) + =([%$ %da now] lot) + =(%$ syd) + == + ~ + ?. ?=(%x ren) ~ + ?+ tyl [~ ~] + [%debug %state ~] + ``state+!>([~ state]) + == +:: +++ stay state +++ take + |= [tea=wire hen=duct dud=(unit goof) hin=sign] + ^- [(list move) _loch-gate] + ?^ dud + ~|(%loch-take-dud (mean tang.u.dud)) + :: + [~ loch-gate] +-- From 7b0c370319299a9b4a2cf500d22269fd4405def3 Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Wed, 15 Feb 2023 14:26:38 -0500 Subject: [PATCH 002/152] added %read and %writ cards --- pkg/arvo/sys/lull.hoon | 4 ++ pkg/arvo/sys/vane/loch.hoon | 97 +++++++++---------------------------- 2 files changed, 28 insertions(+), 73 deletions(-) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index f6bb63d6a3..73ae296432 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -2306,7 +2306,11 @@ $% $>(%born vane-task) :: new unix process $>(%trim vane-task) :: trim state $>(%vega vane-task) :: report upgrade + [%read =wut dev=@tas cmd=@] :: %read from device dev for cnt bytes + [%writ =wut dev=@tas cmd=@ dat=@ud] :: %writ out to device dev == + :: + +$ wut $?(%con %mem) -- ::loch :: diff --git a/pkg/arvo/sys/vane/loch.hoon b/pkg/arvo/sys/vane/loch.hoon index e073806495..f246c5776b 100644 --- a/pkg/arvo/sys/vane/loch.hoon +++ b/pkg/arvo/sys/vane/loch.hoon @@ -7,13 +7,10 @@ => |% +$ move [p=duct q=(wite note gift)] +$ note :: out request $-> - $% - $: %j :: to %jael - $>(%step task:jael) - == - $: %d :: to %dill - $>(%flog task:dill) :: log output - == == + $% $: %g :: to %gall + $>(%deal task:gall) :: full transmission + == :: + == :: :: +$ sign $% [%loch $>(%read gift)] :: read @@ -39,31 +36,10 @@ :: :: +crud: handle failure of previous arvo event :: - ++ crud - |= [tag=@tas error=tang] - ^+ [moves state] - [[duct %slip %d %flog %crud tag error]~ state] + ++ crud [moves state] :: +read: give back :: ++ read [moves state] - :: +fyrd: commands - :: - ::++ fyrd - ::|= com=^fyrd - ::^+ [moves state] - ::=< [moves state] - ::~& > fyrd+com - ::~! -.com - ::?- -.com - ::%mas ~& todo+com event-core :: |mass - ::%cod - ::::=/ cov - ::[duct %pass %j %step ~]~ - ::::~! move+cov event-core(moves cov) - ::== - :: +born: in response to memory pressue - :: - ++ born [moves state] :: +trim: in response to memory pressue :: ++ trim [moves state] @@ -86,38 +62,31 @@ |% :: +call: handle a +task:loch request :: -++ call - ~% %loch-call ..part ~ +++ call |= $: hen=duct dud=(unit goof) wrapped-task=(hobo task) == ^- [(list move) _loch-gate] + ~& > ["loch call hen:" hen] + ::~& >> ["loch call dud:" dud] + ~& >>> ["loch call wrapped-task:" wrapped-task] :: =/ =task ((harden task) wrapped-task) - =/ event-core (per-event [now hen] state) - :: - =^ moves state - :: - :: handle error notifications - :: - :: - ?^ dud - (crud:event-core -.task tang.u.dud) - :: - ~! -.task - ?- -.task - %born born:event-core - %trim trim:event-core - %vega vega:event-core :: vega - ::%read read:event-core - == - [moves loch-gate] + ~& >> ["loch call task:" task] + ::?^ dud + ::~|(%loch-call-dud (mean tang.u.dud)) + ?+ -.task + ~& >> ["loch task:" -.task] + [~ loch-gate] + %born [~ loch-gate] + == :: +load: migrate an old state to a new loch version :: ++ load |= old=loch-state ^+ loch-gate + ~& >> "loch load:" loch-gate(state old) :: +scry: view state :: @@ -125,36 +94,18 @@ ^- roon |= [lyc=gang car=term bem=beam] ^- (unit (unit cage)) - =* ren car - =* why=shop &/p.bem - =* syd q.bem - =* lot=coin $/r.bem - =* tyl s.bem - - ?: &(=(ren %$) =(tyl /whey)) - =/ maz=(list mass) - :~ state+&+state - == - ``mass+!>(maz) - :: only respond for the local identity, %$ desk, current timestamp - :: - ?. ?& =(&+our why) - =([%$ %da now] lot) - =(%$ syd) - == - ~ - ?. ?=(%x ren) ~ - ?+ tyl [~ ~] - [%debug %state ~] - ``state+!>([~ state]) - == + ~& >> "loch scry:" + ~ :: -++ stay state +++ stay + ~& >> "loch stay:" + state ++ take |= [tea=wire hen=duct dud=(unit goof) hin=sign] ^- [(list move) _loch-gate] ?^ dud ~|(%loch-take-dud (mean tang.u.dud)) :: + ~& >> "loch take:" [~ loch-gate] -- From b4a61ad2d0aa83d208a66ad2aa19ca667e246c70 Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Wed, 15 Feb 2023 16:35:09 -0500 Subject: [PATCH 003/152] loch has some state change --- pkg/arvo/sys/vane/loch.hoon | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/pkg/arvo/sys/vane/loch.hoon b/pkg/arvo/sys/vane/loch.hoon index f246c5776b..a01543904f 100644 --- a/pkg/arvo/sys/vane/loch.hoon +++ b/pkg/arvo/sys/vane/loch.hoon @@ -19,8 +19,13 @@ +$ loch-state $: %0 unix-duct=duct + devices=(map @tas device) + commands=(list cmd) == :: + +$ cmd [cmd=@tas =wut dev=@tas =duct] + :: + +$ device [name=@tas status=@ reg=(unit @tas)] -- :: => @@ -74,12 +79,22 @@ :: =/ =task ((harden task) wrapped-task) ~& >> ["loch call task:" task] + ~& > ["loch" unix-duct:loch-gate] + ~& > ["loch" devices:loch-gate] + ~& > ["loch" commands:loch-gate] ::?^ dud ::~|(%loch-call-dud (mean tang.u.dud)) - ?+ -.task - ~& >> ["loch task:" -.task] - [~ loch-gate] - %born [~ loch-gate] + ?+ -.task [~ loch-gate] + %born :: When born you need to wipe your current state + :- ~ + loch-gate(unix-duct hen, commands [~]) + %read :: When you read you need to save the command and the wire to return the results + =/ =wut wut:task + ::=/ =dev dev:task + =/ =cmd [%read wut %uart hen] + ~& >> ['cmd' cmd] + :- ~ + loch-gate(commands [cmd commands]) == :: +load: migrate an old state to a new loch version :: From 60bbf9507b98cae7fb0a3631c5e3112fc98a4f50 Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Mon, 20 Feb 2023 14:40:52 -0500 Subject: [PATCH 004/152] modified some stuff to return a card to vere --- pkg/arvo/sys/lull.hoon | 9 ++++++--- pkg/arvo/sys/vane/loch.hoon | 31 ++++++++++++++++++------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 73ae296432..46e38697b2 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -2299,18 +2299,21 @@ ++ loch ^? |% +$ gift :: out result <-$ - $% [%read p=(unit @da)] :: next alarm + $% [%read =param] :: next alarm + ::$% [%writ =param dat=@ud] :: next alarm == +$ task :: in request ->$ $~ [%vega ~] :: $% $>(%born vane-task) :: new unix process $>(%trim vane-task) :: trim state $>(%vega vane-task) :: report upgrade - [%read =wut dev=@tas cmd=@] :: %read from device dev for cnt bytes - [%writ =wut dev=@tas cmd=@ dat=@ud] :: %writ out to device dev + [%read =param] :: %read from device dev for cnt bytes + [%writ =param dat=@ud] :: %writ out to device dev + [%devs name=@tas stat=@] :: provide a device with status == :: +$ wut $?(%con %mem) + +$ param [=wut dev=@tas cmd=@] -- ::loch :: diff --git a/pkg/arvo/sys/vane/loch.hoon b/pkg/arvo/sys/vane/loch.hoon index a01543904f..f368e82734 100644 --- a/pkg/arvo/sys/vane/loch.hoon +++ b/pkg/arvo/sys/vane/loch.hoon @@ -73,28 +73,33 @@ wrapped-task=(hobo task) == ^- [(list move) _loch-gate] - ~& > ["loch call hen:" hen] - ::~& >> ["loch call dud:" dud] - ~& >>> ["loch call wrapped-task:" wrapped-task] :: =/ =task ((harden task) wrapped-task) - ~& >> ["loch call task:" task] - ~& > ["loch" unix-duct:loch-gate] - ~& > ["loch" devices:loch-gate] - ~& > ["loch" commands:loch-gate] + ~& > ["loch call task:" task] + ~& > :^ "loch" + ["unix duct" unix-duct:loch-gate] + ["devices" devices:loch-gate] + ["commands" commands:loch-gate] ::?^ dud ::~|(%loch-call-dud (mean tang.u.dud)) ?+ -.task [~ loch-gate] %born :: When born you need to wipe your current state :- ~ - loch-gate(unix-duct hen, commands [~]) + loch-gate(unix-duct hen, commands [~], devices ~) + :: %read :: When you read you need to save the command and the wire to return the results - =/ =wut wut:task - ::=/ =dev dev:task - =/ =cmd [%read wut %uart hen] - ~& >> ['cmd' cmd] + =/ =param param:task + ~& >> ['param' param] + :- ~[[unix-duct.state %give [%read param]]] + loch-gate + :: + %devs + =/ dev +.task + ~& > dev :- ~ - loch-gate(commands [cmd commands]) + %_ loch-gate + devices (~(put by devices) name.dev [name.dev stat.dev ~]) + == == :: +load: migrate an old state to a new loch version :: From cd5c25b48af40979abfb58029deb3f22a1092325 Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Tue, 21 Feb 2023 16:44:00 -0500 Subject: [PATCH 005/152] modified flow for read red, and turn --- pkg/arvo/sys/lull.hoon | 12 +++++++++--- pkg/arvo/sys/vane/loch.hoon | 35 +++++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 46e38697b2..528f1f0c0d 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -2300,20 +2300,26 @@ |% +$ gift :: out result <-$ $% [%read =param] :: next alarm - ::$% [%writ =param dat=@ud] :: next alarm + [%red =dev dat=@ud] + ::[%writ =param dat=@ud] :: next alarm == +$ task :: in request ->$ $~ [%vega ~] :: $% $>(%born vane-task) :: new unix process $>(%trim vane-task) :: trim state $>(%vega vane-task) :: report upgrade + [%turn =dev =act dat=@ud] [%read =param] :: %read from device dev for cnt bytes - [%writ =param dat=@ud] :: %writ out to device dev + ::[%writ =param dat=@ud] :: %writ out to device dev [%devs name=@tas stat=@] :: provide a device with status + ::[%red =dev dat=@ud] + ::[%wrot dat=@ud] == :: +$ wut $?(%con %mem) - +$ param [=wut dev=@tas cmd=@] + +$ dev @tas + +$ param [=wut =dev cmd=@] + +$ act $?(%read %writ) -- ::loch :: diff --git a/pkg/arvo/sys/vane/loch.hoon b/pkg/arvo/sys/vane/loch.hoon index f368e82734..376fe40ca5 100644 --- a/pkg/arvo/sys/vane/loch.hoon +++ b/pkg/arvo/sys/vane/loch.hoon @@ -13,7 +13,8 @@ == :: :: +$ sign - $% [%loch $>(%read gift)] :: read + $% [%loch $>(%red gift)] :: read + [%loch $>(%read gift)] == :: +$ loch-state @@ -21,9 +22,10 @@ unix-duct=duct devices=(map @tas device) commands=(list cmd) + pathing=(map dev duct) == :: - +$ cmd [cmd=@tas =wut dev=@tas =duct] + +$ cmd [cmd=@tas =wut =dev =duct] :: +$ device [name=@tas status=@ reg=(unit @tas)] -- @@ -75,31 +77,40 @@ ^- [(list move) _loch-gate] :: =/ =task ((harden task) wrapped-task) - ~& > ["loch call task:" task] - ~& > :^ "loch" - ["unix duct" unix-duct:loch-gate] - ["devices" devices:loch-gate] - ["commands" commands:loch-gate] + ~& > ["1 loch call task:" task] + ~& >> ["2 loch hen:" hen] + ::~& >> :* "loch" + ::["unix duct" unix-duct:loch-gate] + ::["devices" devices:loch-gate] + ::["commands" commands:loch-gate] + ::["pathing" pathing:loch-gate] + ::== ::?^ dud ::~|(%loch-call-dud (mean tang.u.dud)) - ?+ -.task [~ loch-gate] + ?+ -.task [~ loch-gate] %born :: When born you need to wipe your current state :- ~ - loch-gate(unix-duct hen, commands [~], devices ~) + loch-gate(unix-duct hen, commands [~], devices ~, pathing ~) :: %read :: When you read you need to save the command and the wire to return the results =/ =param param:task - ~& >> ['param' param] + ::~& >> ['param' param] :- ~[[unix-duct.state %give [%read param]]] - loch-gate + %_ loch-gate + pathing (~(put by pathing) dev.param hen) + == :: %devs =/ dev +.task - ~& > dev :- ~ %_ loch-gate devices (~(put by devices) name.dev [name.dev stat.dev ~]) == + :: + %turn + =/ duct (~(get by pathing) dev.task) + :- ~[[+.duct %give %red dev.task dat.task]] + loch-gate == :: +load: migrate an old state to a new loch version :: From 81f6df38455789fc7daeada3f43c9e7a70417176 Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Thu, 23 Feb 2023 17:16:58 -0500 Subject: [PATCH 006/152] cleaned up interface --- pkg/arvo/sys/lull.hoon | 14 +++++++------- pkg/arvo/sys/vane/loch.hoon | 22 +++++++++++----------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 528f1f0c0d..e49030719c 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -2299,21 +2299,21 @@ ++ loch ^? |% +$ gift :: out result <-$ - $% [%read =param] :: next alarm - [%red =dev dat=@ud] - ::[%writ =param dat=@ud] :: next alarm + $% [%read =param] :: Gift to unix read + [%rite =param dat=@] :: Gift to unix write + [%seen =dev dat=@] :: Gift iof read data back to duct + [%rote =dev tus=@] :: Gift of wrote status to duct == +$ task :: in request ->$ $~ [%vega ~] :: $% $>(%born vane-task) :: new unix process $>(%trim vane-task) :: trim state $>(%vega vane-task) :: report upgrade - [%turn =dev =act dat=@ud] [%read =param] :: %read from device dev for cnt bytes - ::[%writ =param dat=@ud] :: %writ out to device dev + [%rite =param dat=@] :: %writ out to device dev + [%seen =dev dat=@] + [%rote =dev tus=@] [%devs name=@tas stat=@] :: provide a device with status - ::[%red =dev dat=@ud] - ::[%wrot dat=@ud] == :: +$ wut $?(%con %mem) diff --git a/pkg/arvo/sys/vane/loch.hoon b/pkg/arvo/sys/vane/loch.hoon index 376fe40ca5..d6df5bbf68 100644 --- a/pkg/arvo/sys/vane/loch.hoon +++ b/pkg/arvo/sys/vane/loch.hoon @@ -6,16 +6,16 @@ |= our=ship => |% +$ move [p=duct q=(wite note gift)] - +$ note :: out request $-> - $% $: %g :: to %gall - $>(%deal task:gall) :: full transmission - == :: - == :: + +$ note ~ :: out request $-> + ::$% $: %g :: to %gall + ::$>(%deal task:gall) :: full transmission + ::== :: + ::== :: :: - +$ sign - $% [%loch $>(%red gift)] :: read - [%loch $>(%read gift)] - == + +$ sign ~ + ::$% [%loch $>(%red gift)] :: read + :: [%loch $>(%read gift)] + ::== :: +$ loch-state $: %0 @@ -107,9 +107,9 @@ devices (~(put by devices) name.dev [name.dev stat.dev ~]) == :: - %turn + %seen =/ duct (~(get by pathing) dev.task) - :- ~[[+.duct %give %red dev.task dat.task]] + :- ~[[+.duct %give %seen dev.task dat.task]] loch-gate == :: +load: migrate an old state to a new loch version From fb9f890a625372d98c1cb56cc9a124ede2402f82 Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Fri, 24 Feb 2023 15:28:29 -0500 Subject: [PATCH 007/152] fixed api and added rote path --- pkg/arvo/sys/lull.hoon | 17 +++++++++-------- pkg/arvo/sys/vane/loch.hoon | 19 ++++++++++++++----- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index e49030719c..215e8471ca 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -2299,9 +2299,9 @@ ++ loch ^? |% +$ gift :: out result <-$ - $% [%read =param] :: Gift to unix read - [%rite =param dat=@] :: Gift to unix write - [%seen =dev dat=@] :: Gift iof read data back to duct + $% [%read =dev =wut =cmd =cnt] :: Gift to unix read + [%rite =dev =wut =cmd dat=@ =cnt] :: Gift to unix write + [%seen =dev dat=@ tus=@] :: Gift of read data back to duct [%rote =dev tus=@] :: Gift of wrote status to duct == +$ task :: in request ->$ @@ -2309,16 +2309,17 @@ $% $>(%born vane-task) :: new unix process $>(%trim vane-task) :: trim state $>(%vega vane-task) :: report upgrade - [%read =param] :: %read from device dev for cnt bytes - [%rite =param dat=@] :: %writ out to device dev - [%seen =dev dat=@] - [%rote =dev tus=@] + [%read =dev =wut =cmd =cnt] :: %read from device dev for cnt bytes + [%rite =dev =wut =cmd dat=@ =cnt] :: %rite out to device dev + [%seen =dev dat=@ tus=@] :: data read from device + [%rote =dev tus=@] :: data wrote from device [%devs name=@tas stat=@] :: provide a device with status == :: +$ wut $?(%con %mem) +$ dev @tas - +$ param [=wut =dev cmd=@] + +$ cmd @ + +$ cnt @ +$ act $?(%read %writ) -- ::loch diff --git a/pkg/arvo/sys/vane/loch.hoon b/pkg/arvo/sys/vane/loch.hoon index d6df5bbf68..03c0108bbd 100644 --- a/pkg/arvo/sys/vane/loch.hoon +++ b/pkg/arvo/sys/vane/loch.hoon @@ -93,11 +93,15 @@ loch-gate(unix-duct hen, commands [~], devices ~, pathing ~) :: %read :: When you read you need to save the command and the wire to return the results - =/ =param param:task - ::~& >> ['param' param] - :- ~[[unix-duct.state %give [%read param]]] + :- ~[[unix-duct.state %give [%read dev.task wut.task cmd.task cnt.task]]] %_ loch-gate - pathing (~(put by pathing) dev.param hen) + pathing (~(put by pathing) dev.task hen) + == + :: + %rite :: When you read you need to save the command and the wire to return the results + :- ~[[unix-duct.state %give [%rite dev.task wut.task cmd.task dat.task cnt.task]]] + %_ loch-gate + pathing (~(put by pathing) dev.task hen) == :: %devs @@ -109,7 +113,12 @@ :: %seen =/ duct (~(get by pathing) dev.task) - :- ~[[+.duct %give %seen dev.task dat.task]] + :- ~[[+.duct %give %seen dev.task dat.task tus.task]] + loch-gate + :: + %rote + =/ duct (~(get by pathing) dev.task) + :- ~[[+.duct %give %rote dev.task tus.task]] loch-gate == :: +load: migrate an old state to a new loch version From 32adcdf0059763e68ce2d13e863405d6709e668c Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Mon, 27 Feb 2023 15:47:38 -0500 Subject: [PATCH 008/152] loch mods --- pkg/arvo/sys/vane/loch.hoon | 4 ++++ pkg/arvo/ted/loch.hoon | 13 +++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 pkg/arvo/ted/loch.hoon diff --git a/pkg/arvo/sys/vane/loch.hoon b/pkg/arvo/sys/vane/loch.hoon index 03c0108bbd..ab10c56107 100644 --- a/pkg/arvo/sys/vane/loch.hoon +++ b/pkg/arvo/sys/vane/loch.hoon @@ -113,6 +113,10 @@ :: %seen =/ duct (~(get by pathing) dev.task) + ~& > ["Data" `@ux`dat.task] + ~& > ["Data" `@ta`dat.task] + ~& > ["Data" (trip dat.task)] + ~& >> ["duct" +.duct] :- ~[[+.duct %give %seen dev.task dat.task tus.task]] loch-gate :: diff --git a/pkg/arvo/ted/loch.hoon b/pkg/arvo/ted/loch.hoon new file mode 100644 index 0000000000..e8c992ff35 --- /dev/null +++ b/pkg/arvo/ted/loch.hoon @@ -0,0 +1,13 @@ +/- spider +/+ strandio +=, strand=strand:spider +^- thread:spider +|= arg=vase +=/ m (strand ,vase) +^- form:m +::=; loch +=+ !<([~ arg=[=dev:loch =wut:loch =cmd:loch =cnt:loch]] arg) +;< now=@da bind:m get-time:strandio +;< ~ bind:m (send-raw-card:strandio [%pass /ted/loch/(scot %da now) %arvo %l %read dev.arg wut.arg cmd.arg cnt.arg]) +::;< ~ bind:m (scry:strandio @ux /l/ +(pure:m !>("loch-read suc")) From 0950355c383c4202b5266d39b70be85eb622e89c Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Tue, 14 Mar 2023 15:20:49 -0400 Subject: [PATCH 009/152] added inital scry stuff for loch devices --- pkg/arvo/sys/vane/loch.hoon | 63 ++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/pkg/arvo/sys/vane/loch.hoon b/pkg/arvo/sys/vane/loch.hoon index ab10c56107..59e5b0b621 100644 --- a/pkg/arvo/sys/vane/loch.hoon +++ b/pkg/arvo/sys/vane/loch.hoon @@ -27,7 +27,7 @@ :: +$ cmd [cmd=@tas =wut =dev =duct] :: - +$ device [name=@tas status=@ reg=(unit @tas)] + +$ device [name=@tas dat=@ tus=@] -- :: => @@ -77,8 +77,8 @@ ^- [(list move) _loch-gate] :: =/ =task ((harden task) wrapped-task) - ~& > ["1 loch call task:" task] - ~& >> ["2 loch hen:" hen] + ~& > ["loch call task:" task] + ~& >> ["loch hen:" hen] ::~& >> :* "loch" ::["unix duct" unix-duct:loch-gate] ::["devices" devices:loch-gate] @@ -108,22 +108,25 @@ =/ dev +.task :- ~ %_ loch-gate - devices (~(put by devices) name.dev [name.dev stat.dev ~]) + devices (~(put by devices) name.dev [name.dev ~ stat.dev]) == :: %seen =/ duct (~(get by pathing) dev.task) - ~& > ["Data" `@ux`dat.task] - ~& > ["Data" `@ta`dat.task] - ~& > ["Data" (trip dat.task)] - ~& >> ["duct" +.duct] + =/ device-save [dev.task dat.task tus.task] + ~& >> ["devicesave" device-save] :- ~[[+.duct %give %seen dev.task dat.task tus.task]] - loch-gate + %_ loch-gate + devices (~(put by devices) dev.task device-save) + == :: %rote =/ duct (~(get by pathing) dev.task) + =/ device-save [dev.task 0 tus.task] :- ~[[+.duct %give %rote dev.task tus.task]] - loch-gate + %_ loch-gate + devices (~(put by devices) dev.task device-save) + == == :: +load: migrate an old state to a new loch version :: @@ -134,12 +137,50 @@ loch-gate(state old) :: +scry: view state :: +:: %a scry out a list of devices +:: %d get a device's dat and tus ++ scry ^- roon |= [lyc=gang car=term bem=beam] ^- (unit (unit cage)) + =* ren car + =* why=shop &/p.bem + =* syd q.bem + =* lot=coin $/r.bem + =* tyl s.bem ~& >> "loch scry:" - ~ + ~& >> ["lyc" lyc] + ~& >> ["car" car] + ~& >> ["bem" bem] + |^ + :: only respond for the local identity, current timestamp + :: + ?. ?& =(&+our why) + =([%$ %da now] lot) + == + ~ + ?+ car ~ + %a (read-a lyc bem) + %d (read-d lyc bem) + == + :: +read-a: scry our list of devices + :: + ++ read-a ::^- roon + |= [lyc=gang bem=beam] + ^- (unit (unit cage)) + =/ devs ~(tap in ~(key by devices)) + ``[%noun !>(devs)] + :: +read d: get devices dat and tus + :: + ++ read-d ::^- roon + |= [lyc=gang bem=beam] + ^- (unit (unit cage)) + ~& >>> ["lyc" lyc] + ~& >>> ["bem" bem] + =* tyl -.s.bem + =/ devs (~(got by devices) tyl) + ``[%noun !>(devs)] + -- :: ++ stay ~& >> "loch stay:" From 5c80fb430f408e0c44ad0e3551975b761383f65b Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Tue, 14 Mar 2023 15:58:23 -0400 Subject: [PATCH 010/152] removed some old code --- pkg/arvo/sys/vane/loch.hoon | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/arvo/sys/vane/loch.hoon b/pkg/arvo/sys/vane/loch.hoon index 59e5b0b621..ad18da342b 100644 --- a/pkg/arvo/sys/vane/loch.hoon +++ b/pkg/arvo/sys/vane/loch.hoon @@ -165,14 +165,14 @@ == :: +read-a: scry our list of devices :: - ++ read-a ::^- roon + ++ read-a |= [lyc=gang bem=beam] ^- (unit (unit cage)) =/ devs ~(tap in ~(key by devices)) ``[%noun !>(devs)] :: +read d: get devices dat and tus :: - ++ read-d ::^- roon + ++ read-d |= [lyc=gang bem=beam] ^- (unit (unit cage)) ~& >>> ["lyc" lyc] From 3aafd12b404dbc9263100767d7360f91f666c555 Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Fri, 24 Mar 2023 11:20:02 -0400 Subject: [PATCH 011/152] modified API to use units and such --- pkg/arvo/sys/vane/loch.hoon | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pkg/arvo/sys/vane/loch.hoon b/pkg/arvo/sys/vane/loch.hoon index ad18da342b..23c1a2e6b2 100644 --- a/pkg/arvo/sys/vane/loch.hoon +++ b/pkg/arvo/sys/vane/loch.hoon @@ -27,7 +27,7 @@ :: +$ cmd [cmd=@tas =wut =dev =duct] :: - +$ device [name=@tas dat=@ tus=@] + +$ device [name=@tas dat=(unit @) tus=@] -- :: => @@ -77,8 +77,8 @@ ^- [(list move) _loch-gate] :: =/ =task ((harden task) wrapped-task) - ~& > ["loch call task:" task] - ~& >> ["loch hen:" hen] + ::~& > ["loch call task:" task] + ::~& >> ["loch hen:" hen] ::~& >> :* "loch" ::["unix duct" unix-duct:loch-gate] ::["devices" devices:loch-gate] @@ -113,8 +113,8 @@ :: %seen =/ duct (~(get by pathing) dev.task) - =/ device-save [dev.task dat.task tus.task] - ~& >> ["devicesave" device-save] + =/ device-save [dev.task `dat.task tus.task] + ::~& >> ["devicesave" device-save] :- ~[[+.duct %give %seen dev.task dat.task tus.task]] %_ loch-gate devices (~(put by devices) dev.task device-save) @@ -122,7 +122,7 @@ :: %rote =/ duct (~(get by pathing) dev.task) - =/ device-save [dev.task 0 tus.task] + =/ device-save [dev.task ~ tus.task] :- ~[[+.duct %give %rote dev.task tus.task]] %_ loch-gate devices (~(put by devices) dev.task device-save) @@ -179,6 +179,7 @@ ~& >>> ["bem" bem] =* tyl -.s.bem =/ devs (~(got by devices) tyl) + ~& > devs ``[%noun !>(devs)] -- :: From 813b03b1c67ed93d91c0d7d1ed934b7f620d6ac7 Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Fri, 24 Mar 2023 11:26:37 -0400 Subject: [PATCH 012/152] removed unnecessary ted file --- pkg/arvo/ted/loch.hoon | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 pkg/arvo/ted/loch.hoon diff --git a/pkg/arvo/ted/loch.hoon b/pkg/arvo/ted/loch.hoon deleted file mode 100644 index e8c992ff35..0000000000 --- a/pkg/arvo/ted/loch.hoon +++ /dev/null @@ -1,13 +0,0 @@ -/- spider -/+ strandio -=, strand=strand:spider -^- thread:spider -|= arg=vase -=/ m (strand ,vase) -^- form:m -::=; loch -=+ !<([~ arg=[=dev:loch =wut:loch =cmd:loch =cnt:loch]] arg) -;< now=@da bind:m get-time:strandio -;< ~ bind:m (send-raw-card:strandio [%pass /ted/loch/(scot %da now) %arvo %l %read dev.arg wut.arg cmd.arg cnt.arg]) -::;< ~ bind:m (scry:strandio @ux /l/ -(pure:m !>("loch-read suc")) From 3f744cd35bf54cf5a08f44d5153f0b9b06796793 Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Wed, 12 Apr 2023 10:50:29 -0400 Subject: [PATCH 013/152] changed to lick --- pkg/arvo/sys/arvo.hoon | 2 +- pkg/arvo/sys/lull.hoon | 32 ++---- pkg/arvo/sys/vane/lick.hoon | 130 ++++++++++++++++++++++++ pkg/arvo/sys/vane/loch.hoon | 197 ------------------------------------ 4 files changed, 142 insertions(+), 219 deletions(-) create mode 100644 pkg/arvo/sys/vane/lick.hoon delete mode 100644 pkg/arvo/sys/vane/loch.hoon diff --git a/pkg/arvo/sys/arvo.hoon b/pkg/arvo/sys/arvo.hoon index 9a9fde830a..bd3f276b2e 100644 --- a/pkg/arvo/sys/arvo.hoon +++ b/pkg/arvo/sys/arvo.hoon @@ -1724,7 +1724,7 @@ %i %iris %j %jael %k %khan - %l %loch + %l %lick == -- => :: diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 3a1d0ffce1..1c6234f45b 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -2351,34 +2351,24 @@ +$ shed _*form:(strand:rand ,vase) :: compute vase -- ::khan :: :::: -:::: ++loch :: (1b) timekeeping +:::: ++lick :: (1b) timekeeping :: :::: -++ loch ^? +++ lick ^? |% +$ gift :: out result <-$ - $% [%read =dev =wut =cmd =cnt] :: Gift to unix read - [%rite =dev =wut =cmd dat=@ =cnt] :: Gift to unix write - [%seen =dev dat=@ tus=@] :: Gift of read data back to duct - [%rote =dev tus=@] :: Gift of wrote status to duct + $% [%book =nam =ver] :: register a IPC vane == +$ task :: in request ->$ $~ [%vega ~] :: $% $>(%born vane-task) :: new unix process $>(%trim vane-task) :: trim state $>(%vega vane-task) :: report upgrade - [%read =dev =wut =cmd =cnt] :: %read from device dev for cnt bytes - [%rite =dev =wut =cmd dat=@ =cnt] :: %rite out to device dev - [%seen =dev dat=@ tus=@] :: data read from device - [%rote =dev tus=@] :: data wrote from device - [%devs name=@tas stat=@] :: provide a device with status + [%book =nam =ver] == :: - +$ wut $?(%con %mem) - +$ dev @tas - +$ cmd @ - +$ cnt @ - +$ act $?(%read %writ) - -- ::loch + +$ nam @tas + +$ ver @tas + -- ::lick :: ++ rand :: computation @@ -2582,7 +2572,7 @@ gift:iris gift:jael gift:khan - gift:loch + gift:lick == +$ task-arvo :: in request ->$ $% task:ames @@ -2594,7 +2584,7 @@ task:iris task:jael task:khan - task:loch + task:lick == +$ note-arvo :: out request $-> $~ [%b %wake ~] @@ -2607,7 +2597,7 @@ [%i task:iris] [%j task:jael] [%k task:khan] - [%l task:loch] + [%l task:lick] [%$ %whiz ~] [@tas %meta vase] == @@ -2630,7 +2620,7 @@ [%iris gift:iris] [%jael gift:jael] [%khan gift:khan] - [%loch gift:loch] + [%lick gift:lick] == :: $unix-task: input from unix :: diff --git a/pkg/arvo/sys/vane/lick.hoon b/pkg/arvo/sys/vane/lick.hoon new file mode 100644 index 0000000000..cbfed2b495 --- /dev/null +++ b/pkg/arvo/sys/vane/lick.hoon @@ -0,0 +1,130 @@ +:: %lick +!: +!? 164 +:: +=, lick +|= our=ship +=> |% + +$ move [p=duct q=(wite note gift)] + +$ note ~ :: out request $-> + ::$% $: %g :: to %gall + ::$>(%deal task:gall) :: full transmission + ::== :: + ::== :: + :: + +$ sign ~ + ::$% [%lick $>(%red gift)] :: read + :: [%lick $>(%read gift)] + ::== + :: + +$ lick-state + $: %0 + unix-duct=duct + agents=(list agent) + == + :: + +$ agent [name=@tas ver=@tas] + -- +:: +=> +~% %lick ..part ~ +|% +++ per-event + =| moves=(list move) + |= [[now=@da =duct] state=lick-state] + :: + |% + ++ this . + :: %entry-points + :: + :: +crud: handle failure of previous arvo event + :: + ++ crud [moves state] + :: +read: give back + :: + ++ read [moves state] + :: +trim: in response to memory pressue + :: + ++ trim [moves state] + :: +vega: learn of a kernel upgrade + :: + ++ vega [moves state] + :: %utilities + :: + ::+| + :: + ++ event-core . + -- +-- +:: +=| lick-state +=* state - +|= [now=@da eny=@uvJ rof=roof] +=* lick-gate . +^? +|% +:: +register: Create a move to register an agent with vere +:: +++ register + |= =agent + ^- move + [unix-duct.state %give [%book name.agent ver.agent]] +:: +call: handle a +task:lick request +:: +++ call + |= $: hen=duct + dud=(unit goof) + wrapped-task=(hobo task) + == + ^- [(list move) _lick-gate] + :: + =/ =task ((harden task) wrapped-task) + ?+ -.task [~ lick-gate] + %born :: When born you need to register all devices + :- (turn agents.state register) + lick-gate(unix-duct hen) + :: + %book :: A gall agent wants to book a communication line + =/ =agent [nam.task ver.task] + :- ~[(register agent)] + lick-gate(agents (snoc agents agent)) + + == +:: +load: migrate an old state to a new lick version +:: +++ load + |= old=lick-state + ^+ lick-gate + ~& >> "lick load:" + lick-gate(state old) +:: +scry: view state +:: +:: %a scry out a list of devices +:: %d get a device's dat and tus +++ scry + ^- roon + |= [lyc=gang car=term bem=beam] + ^- (unit (unit cage)) + =* ren car + =* why=shop &/p.bem + =* syd q.bem + =* lot=coin $/r.bem + =* tyl s.bem + ~& >> "lick scry:" + ~& >> ["lyc" lyc] + ~& >> ["car" car] + ~& >> ["bem" bem] + ~ +:: +++ stay + ~& >> "lick stay:" + state +++ take + |= [tea=wire hen=duct dud=(unit goof) hin=sign] + ^- [(list move) _lick-gate] + ?^ dud + ~|(%lick-take-dud (mean tang.u.dud)) + :: + ~& >> "lick take:" + [~ lick-gate] +-- diff --git a/pkg/arvo/sys/vane/loch.hoon b/pkg/arvo/sys/vane/loch.hoon deleted file mode 100644 index 23c1a2e6b2..0000000000 --- a/pkg/arvo/sys/vane/loch.hoon +++ /dev/null @@ -1,197 +0,0 @@ -:: %loch -!: -!? 164 -:: -=, loch -|= our=ship -=> |% - +$ move [p=duct q=(wite note gift)] - +$ note ~ :: out request $-> - ::$% $: %g :: to %gall - ::$>(%deal task:gall) :: full transmission - ::== :: - ::== :: - :: - +$ sign ~ - ::$% [%loch $>(%red gift)] :: read - :: [%loch $>(%read gift)] - ::== - :: - +$ loch-state - $: %0 - unix-duct=duct - devices=(map @tas device) - commands=(list cmd) - pathing=(map dev duct) - == - :: - +$ cmd [cmd=@tas =wut =dev =duct] - :: - +$ device [name=@tas dat=(unit @) tus=@] - -- -:: -=> -~% %loch ..part ~ -|% -++ per-event - =| moves=(list move) - |= [[now=@da =duct] state=loch-state] - :: - |% - ++ this . - :: %entry-points - :: - :: +crud: handle failure of previous arvo event - :: - ++ crud [moves state] - :: +read: give back - :: - ++ read [moves state] - :: +trim: in response to memory pressue - :: - ++ trim [moves state] - :: +vega: learn of a kernel upgrade - :: - ++ vega [moves state] - :: %utilities - :: - ::+| - :: - ++ event-core . - -- --- -:: -=| loch-state -=* state - -|= [now=@da eny=@uvJ rof=roof] -=* loch-gate . -^? -|% -:: +call: handle a +task:loch request -:: -++ call - |= $: hen=duct - dud=(unit goof) - wrapped-task=(hobo task) - == - ^- [(list move) _loch-gate] - :: - =/ =task ((harden task) wrapped-task) - ::~& > ["loch call task:" task] - ::~& >> ["loch hen:" hen] - ::~& >> :* "loch" - ::["unix duct" unix-duct:loch-gate] - ::["devices" devices:loch-gate] - ::["commands" commands:loch-gate] - ::["pathing" pathing:loch-gate] - ::== - ::?^ dud - ::~|(%loch-call-dud (mean tang.u.dud)) - ?+ -.task [~ loch-gate] - %born :: When born you need to wipe your current state - :- ~ - loch-gate(unix-duct hen, commands [~], devices ~, pathing ~) - :: - %read :: When you read you need to save the command and the wire to return the results - :- ~[[unix-duct.state %give [%read dev.task wut.task cmd.task cnt.task]]] - %_ loch-gate - pathing (~(put by pathing) dev.task hen) - == - :: - %rite :: When you read you need to save the command and the wire to return the results - :- ~[[unix-duct.state %give [%rite dev.task wut.task cmd.task dat.task cnt.task]]] - %_ loch-gate - pathing (~(put by pathing) dev.task hen) - == - :: - %devs - =/ dev +.task - :- ~ - %_ loch-gate - devices (~(put by devices) name.dev [name.dev ~ stat.dev]) - == - :: - %seen - =/ duct (~(get by pathing) dev.task) - =/ device-save [dev.task `dat.task tus.task] - ::~& >> ["devicesave" device-save] - :- ~[[+.duct %give %seen dev.task dat.task tus.task]] - %_ loch-gate - devices (~(put by devices) dev.task device-save) - == - :: - %rote - =/ duct (~(get by pathing) dev.task) - =/ device-save [dev.task ~ tus.task] - :- ~[[+.duct %give %rote dev.task tus.task]] - %_ loch-gate - devices (~(put by devices) dev.task device-save) - == - == -:: +load: migrate an old state to a new loch version -:: -++ load - |= old=loch-state - ^+ loch-gate - ~& >> "loch load:" - loch-gate(state old) -:: +scry: view state -:: -:: %a scry out a list of devices -:: %d get a device's dat and tus -++ scry - ^- roon - |= [lyc=gang car=term bem=beam] - ^- (unit (unit cage)) - =* ren car - =* why=shop &/p.bem - =* syd q.bem - =* lot=coin $/r.bem - =* tyl s.bem - ~& >> "loch scry:" - ~& >> ["lyc" lyc] - ~& >> ["car" car] - ~& >> ["bem" bem] - |^ - :: only respond for the local identity, current timestamp - :: - ?. ?& =(&+our why) - =([%$ %da now] lot) - == - ~ - ?+ car ~ - %a (read-a lyc bem) - %d (read-d lyc bem) - == - :: +read-a: scry our list of devices - :: - ++ read-a - |= [lyc=gang bem=beam] - ^- (unit (unit cage)) - =/ devs ~(tap in ~(key by devices)) - ``[%noun !>(devs)] - :: +read d: get devices dat and tus - :: - ++ read-d - |= [lyc=gang bem=beam] - ^- (unit (unit cage)) - ~& >>> ["lyc" lyc] - ~& >>> ["bem" bem] - =* tyl -.s.bem - =/ devs (~(got by devices) tyl) - ~& > devs - ``[%noun !>(devs)] - -- -:: -++ stay - ~& >> "loch stay:" - state -++ take - |= [tea=wire hen=duct dud=(unit goof) hin=sign] - ^- [(list move) _loch-gate] - ?^ dud - ~|(%loch-take-dud (mean tang.u.dud)) - :: - ~& >> "loch take:" - [~ loch-gate] --- From 28ed8f1477c6484539940b59c621cfad14762266 Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Thu, 13 Apr 2023 14:11:17 -0400 Subject: [PATCH 014/152] switch to lick --- pkg/arvo/sys/vane/lick.hoon | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pkg/arvo/sys/vane/lick.hoon b/pkg/arvo/sys/vane/lick.hoon index cbfed2b495..de97a1cec6 100644 --- a/pkg/arvo/sys/vane/lick.hoon +++ b/pkg/arvo/sys/vane/lick.hoon @@ -20,10 +20,12 @@ +$ lick-state $: %0 unix-duct=duct - agents=(list agent) + agents=(map name.agent agent) == :: - +$ agent [name=@tas ver=@tas] + +$ agent [=name =ver] + +$ name @tas + +$ ver @tas -- :: => @@ -81,13 +83,15 @@ =/ =task ((harden task) wrapped-task) ?+ -.task [~ lick-gate] %born :: When born you need to register all devices - :- (turn agents.state register) + =/ m=(list move) (turn ~(val by agents.state) register) + ~& >>> m + :- (turn ~(val by agents.state) register) lick-gate(unix-duct hen) :: %book :: A gall agent wants to book a communication line =/ =agent [nam.task ver.task] :- ~[(register agent)] - lick-gate(agents (snoc agents agent)) + lick-gate(agents (~(put by agents) nam.task agent)) == :: +load: migrate an old state to a new lick version From 30e23ddfa048c086e5a75f721e8fab726453e6ea Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Thu, 13 Apr 2023 16:57:27 -0400 Subject: [PATCH 015/152] modified api --- pkg/arvo/sys/lull.hoon | 6 ++++-- pkg/arvo/sys/vane/lick.hoon | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 0492c19eb0..58a075eb9b 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -2357,14 +2357,16 @@ ++ lick ^? |% +$ gift :: out result <-$ - $% [%book =nam =ver] :: register a IPC vane + $% [%sync =nam =ver] :: register a IPC vane == +$ task :: in request ->$ $~ [%vega ~] :: $% $>(%born vane-task) :: new unix process $>(%trim vane-task) :: trim state $>(%vega vane-task) :: report upgrade - [%book =nam =ver] + [%sync =nam =ver] :: register a IPC + [%soak =nam info=*] :: read a noun + [%spew =nam info=*] :: write a noun == :: +$ nam @tas diff --git a/pkg/arvo/sys/vane/lick.hoon b/pkg/arvo/sys/vane/lick.hoon index de97a1cec6..d1375c7d92 100644 --- a/pkg/arvo/sys/vane/lick.hoon +++ b/pkg/arvo/sys/vane/lick.hoon @@ -70,7 +70,7 @@ ++ register |= =agent ^- move - [unix-duct.state %give [%book name.agent ver.agent]] + [unix-duct.state %give [%sync name.agent ver.agent]] :: +call: handle a +task:lick request :: ++ call @@ -88,7 +88,7 @@ :- (turn ~(val by agents.state) register) lick-gate(unix-duct hen) :: - %book :: A gall agent wants to book a communication line + %sync :: A gall agent wants to book a communication line =/ =agent [nam.task ver.task] :- ~[(register agent)] lick-gate(agents (~(put by agents) nam.task agent)) From 3fbefe36d15b21bb710b19594536da941e86d491 Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Fri, 14 Apr 2023 08:43:21 -0400 Subject: [PATCH 016/152] changed spew to spit: --- pkg/arvo/sys/lull.hoon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 58a075eb9b..a2d7d9ac65 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -2366,7 +2366,7 @@ $>(%vega vane-task) :: report upgrade [%sync =nam =ver] :: register a IPC [%soak =nam info=*] :: read a noun - [%spew =nam info=*] :: write a noun + [%spit =nam info=*] :: write a noun == :: +$ nam @tas From 4abeedf74437cbd8eef8198cefb63ee30ef05104 Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Thu, 20 Apr 2023 12:25:57 -0400 Subject: [PATCH 017/152] modified api and compiled --- pkg/arvo/sys/lull.hoon | 18 +++++---- pkg/arvo/sys/vane/lick.hoon | 75 +++++++++++++------------------------ 2 files changed, 36 insertions(+), 57 deletions(-) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index a2d7d9ac65..394c0b1146 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -2352,27 +2352,29 @@ +$ shed _*form:(strand:rand ,vase) :: compute vase -- ::khan :: :::: -:::: ++lick :: (1b) timekeeping +:::: ++lick :: (1j) IPC :: :::: ++ lick ^? |% +$ gift :: out result <-$ - $% [%sync =nam =ver] :: register a IPC vane + $% [%spin =name] :: open an IPC port + [%shut =name] :: close an IPC port + [%spit =name =mark =noun] :: spit a noun to the IPC port + [%soak =name =mark =noun] :: soak a noun from the IPC port == +$ task :: in request ->$ $~ [%vega ~] :: $% $>(%born vane-task) :: new unix process $>(%trim vane-task) :: trim state $>(%vega vane-task) :: report upgrade - [%sync =nam =ver] :: register a IPC - [%soak =nam info=*] :: read a noun - [%spit =nam info=*] :: write a noun + [%spin =name] :: open an IPC port + [%shut =name] :: close an IPC port + [%spit =name =mark =noun] :: spit a noun to the IPC port + [%soak =name =mark =noun] :: soak a noun from the IPC port == :: - +$ nam @tas - +$ ver @tas + +$ name @tas -- ::lick - :: ++ rand :: computation |% diff --git a/pkg/arvo/sys/vane/lick.hoon b/pkg/arvo/sys/vane/lick.hoon index d1375c7d92..35257853d8 100644 --- a/pkg/arvo/sys/vane/lick.hoon +++ b/pkg/arvo/sys/vane/lick.hoon @@ -6,58 +6,24 @@ |= our=ship => |% +$ move [p=duct q=(wite note gift)] - +$ note ~ :: out request $-> + +$ note ~ :: out request $-> ::$% $: %g :: to %gall - ::$>(%deal task:gall) :: full transmission - ::== :: + :: $>(%deal task:gall) :: full transmission + :: == :: ::== :: :: +$ sign ~ - ::$% [%lick $>(%red gift)] :: read - :: [%lick $>(%read gift)] - ::== :: +$ lick-state $: %0 unix-duct=duct - agents=(map name.agent agent) + agents=(map name duct) == :: - +$ agent [=name =ver] +$ name @tas - +$ ver @tas -- :: -=> ~% %lick ..part ~ -|% -++ per-event - =| moves=(list move) - |= [[now=@da =duct] state=lick-state] - :: - |% - ++ this . - :: %entry-points - :: - :: +crud: handle failure of previous arvo event - :: - ++ crud [moves state] - :: +read: give back - :: - ++ read [moves state] - :: +trim: in response to memory pressue - :: - ++ trim [moves state] - :: +vega: learn of a kernel upgrade - :: - ++ vega [moves state] - :: %utilities - :: - ::+| - :: - ++ event-core . - -- --- :: =| lick-state =* state - @@ -68,9 +34,9 @@ :: +register: Create a move to register an agent with vere :: ++ register - |= =agent + |= =name ^- move - [unix-duct.state %give [%sync name.agent ver.agent]] + [unix-duct.state %give [%spin name]] :: +call: handle a +task:lick request :: ++ call @@ -83,16 +49,27 @@ =/ =task ((harden task) wrapped-task) ?+ -.task [~ lick-gate] %born :: When born you need to register all devices - =/ m=(list move) (turn ~(val by agents.state) register) - ~& >>> m - :- (turn ~(val by agents.state) register) - lick-gate(unix-duct hen) + ::=/ m=(list move) (turn ~(key by agents.state) register) + ::~& >>> m + :- (turn ~(tap in ~(key by agents.state)) register) + lick-gate(unix-duct hen) :: - %sync :: A gall agent wants to book a communication line - =/ =agent [nam.task ver.task] - :- ~[(register agent)] - lick-gate(agents (~(put by agents) nam.task agent)) - + %spin :: A gall agent wants to spin a communication line + :- ~[(register name.task)] + lick-gate(agents (~(put by agents) name.task hen)) + :: + %shut :: shut down a communication line + :- ~[[unix-duct.state %give [%shut name.task]]] + lick-gate(agents (~(del by agents) name.task)) + :: + %soak :: push a soak to the ipc's owner + =/ ner=duct (~(get by agents.state) name.task) + :_ lick-gate + ~[[ner %give [%soak name.task mark.task noun.task]]] + :: + %spit :: push a spit to ipc + :_ lick-gate + ~[[unix-duct.state %give [%spit name.task mark.task noun.task]]] == :: +load: migrate an old state to a new lick version :: From 18b9ed3242dd4c3d785ebe35ff648127d2670307 Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Wed, 26 Apr 2023 22:11:17 -0400 Subject: [PATCH 018/152] modified duct to return data --- pkg/arvo/sys/vane/lick.hoon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/arvo/sys/vane/lick.hoon b/pkg/arvo/sys/vane/lick.hoon index 35257853d8..635721642f 100644 --- a/pkg/arvo/sys/vane/lick.hoon +++ b/pkg/arvo/sys/vane/lick.hoon @@ -65,7 +65,7 @@ %soak :: push a soak to the ipc's owner =/ ner=duct (~(get by agents.state) name.task) :_ lick-gate - ~[[ner %give [%soak name.task mark.task noun.task]]] + ~[[+.ner %give [%soak name.task mark.task noun.task]]] :: %spit :: push a spit to ipc :_ lick-gate From 4728ee68c6dfbf7a9bf8f6be6ac4057c6f658443 Mon Sep 17 00:00:00 2001 From: yosoyubik Date: Thu, 27 Apr 2023 14:42:34 +0200 Subject: [PATCH 019/152] Revert "Revert "ames: make +abet pure"" This reverts commit d214fad1bdb77e08c97b52a84f45955c9a9f5df3. https://github.com/urbit/urbit/pull/6403 got closed, probably due to its previous inclusion in the Remote Scry PR, so we reopen it (as a draft). --- pkg/arvo/sys/vane/ames.hoon | 99 +++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 42 deletions(-) diff --git a/pkg/arvo/sys/vane/ames.hoon b/pkg/arvo/sys/vane/ames.hoon index 1721de1002..bde56cde63 100644 --- a/pkg/arvo/sys/vane/ames.hoon +++ b/pkg/arvo/sys/vane/ames.hoon @@ -1718,16 +1718,6 @@ ++ on-plea |= [=ship =plea] ^+ event-core - :: since flow kill goes like: - :: client vane cork task -> client ames pass cork as plea -> - :: -> server ames sinks plea -> server ames +on-plea (we are here); - :: if it's %cork plea passed to ames from its sink, - :: give %done and process flow closing after +on-take-done call - :: - ?: =([%a /close ~] plea) (emit duct %give %done ~) - :: - :: .plea is from local vane to foreign ship - :: =/ ship-state (~(get by peers.ames-state) ship) :: ?. ?=([~ %known *] ship-state) @@ -1736,15 +1726,30 @@ todos(messages [[duct plea] messages.todos]) :: =/ =peer-state +.u.ship-state - =/ =channel [[our ship] now channel-state -.peer-state] + =/ peer-core (abed-peer:pe ship peer-state) + |^ ?+ plea foreign-plea + [%a [%kill ~] =bone] kill-plea + [%a [%cork ~] =bone] =~(cork-plea (emit duct %give %done ~)) + == + :: .plea is from local vane to foreign ship :: - =^ =bone ossuary.peer-state (bind-duct ossuary.peer-state duct) - %- %^ ev-trace msg.veb ship - |. ^- tape - =/ sndr [our our-life.channel] - =/ rcvr [ship her-life.channel] - "plea {}" - abet:(~(on-memo pe [peer-state channel]) bone plea %plea) + ++ foreign-plea + =^ =bone ossuary.peer-state (bind-duct ossuary.peer-state duct) + %- %^ ev-trace msg.veb ship + |. ^- tape + =/ sndr [our our-life.channel.peer-core] + =/ rcvr [ship her-life.channel.peer-core] + "plea {}" + abet:(on-memo:peer-core bone plea %plea) + :: client ames [%cork as plea] -> server ames sinks plea, + :: passes a+/close to itself, + :: put flow in closing, and give %done + :: sink ack, pass a+/kill task <- after +on-take-done, ack %cork pea + :: to itself and delete the flow + :: + ++ cork-plea abet:(on-close-flow:peer-core ;;(@ +.payload.plea)) + ++ kill-plea abet:(on-kill-flow:peer-core ;;(@ +.payload.plea)) + -- :: +on-cork: handle request to kill a flow :: ++ on-cork @@ -2614,6 +2619,36 @@ =. keens (~(put by keens) path *keen-state) fi-abet:(fi-start:(abed:fi path) duct) :: + :: +on-close-flow: close flow on cork receiver side + :: + ++ on-close-flow + |= =bone + ^+ peer-core + peer-core(closing.peer-state (~(put in closing.peer-state) bone)) + :: +on-kill-flow: kill flow on cork sender side + :: + ++ on-kill-flow + |= =bone + ^+ peer-core + ?: (~(has in corked.peer-state) bone) + ~> %slog.0^leaf/"ames: ignoring kill on corked bone {}" + peer-core + =. peer-state + =, peer-state + %_ peer-state + :: if the publisher was behind, preemptively remove any nacks + :: + rcv (~(del by (~(del by rcv) bone)) (mix 0b10 bone)) + snd (~(del by snd) bone) + corked (~(put in corked) bone) + closing (~(del in closing) bone) + by-duct.ossuary (~(del by by-duct.ossuary) (got-duct bone)) + by-bone.ossuary (~(del by by-bone.ossuary) bone) + == + :: since we got one cork ack, try the next one + :: + recork-one + :: +| %implementation :: +dedup-message: replace with any existing copy of this message :: @@ -3042,8 +3077,7 @@ :: not a nack-trace bone; relay ack to client vane :: (pe-emit (got-duct bone) %give %done error) - :: XX impure +abet pattern - :: +pump-cork: kill flow on cork sender side + :: +pump-cork: handle %cork on the publisher :: ++ pump-cork |= =message-num @@ -3055,24 +3089,8 @@ %- %+ pe-trace odd.veb |.("trying to delete a corked bone={}") peer-core - =/ nack-bone=^bone (mix 0b10 bone) - =? rcv.peer-state (~(has by rcv.peer-state) nack-bone) - :: if the publisher was behind we remove nacks on that bone - :: - (~(del by rcv.peer-state) nack-bone) - =. peer-state - =, peer-state - %_ peer-state - snd (~(del by snd) bone) - rcv (~(del by rcv) bone) - corked (~(put in corked) bone) - closing (~(del in closing) bone) - by-duct.ossuary (~(del by by-duct.ossuary) (got-duct bone)) - by-bone.ossuary (~(del by by-bone.ossuary) bone) - == - :: since we got one cork ack, try the next one - :: - recork-one + =/ =wire (make-bone-wire her her-rift.channel bone) + (pe-emit duct %pass wire %a %plea her [%a /kill bone]) :: +pu: construct |packet-pump core :: ++ pu @@ -3651,10 +3669,7 @@ :: account for publishers that still handle ames-to-ames %pleas :: ?> &(?=([%cork *] payload.plea) ?=(%flow -.path.plea)) - :: XX FIXME impure +abet pattern... - :: - =. closing.peer-state (~(put in closing.peer-state) bone) - (pe-emit duct %pass wire %a %plea her [%a /close ~]) + (pe-emit duct %pass wire %a %plea her [%a /close bone]) :: :: +ha-boon: handle response message, acking unconditionally :: From b51445a5c8cf97d26ec73af510313290001a95e0 Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Thu, 27 Apr 2023 09:14:54 -0400 Subject: [PATCH 020/152] added disconnect soak during born --- pkg/arvo/sys/vane/lick.hoon | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/pkg/arvo/sys/vane/lick.hoon b/pkg/arvo/sys/vane/lick.hoon index 635721642f..489214529a 100644 --- a/pkg/arvo/sys/vane/lick.hoon +++ b/pkg/arvo/sys/vane/lick.hoon @@ -37,6 +37,13 @@ |= =name ^- move [unix-duct.state %give [%spin name]] +:: +disconnect: Create Move to send a disconnect soak to am agent +:: +++ disconnect + |= =name + ^- move + =/ =duct (~(get by agents) name) + [+.duct %give [%soak name %disconnect ~]] :: +call: handle a +task:lick request :: ++ call @@ -48,10 +55,10 @@ :: =/ =task ((harden task) wrapped-task) ?+ -.task [~ lick-gate] - %born :: When born you need to register all devices - ::=/ m=(list move) (turn ~(key by agents.state) register) - ::~& >>> m - :- (turn ~(tap in ~(key by agents.state)) register) + %born :: need to register devices with vere and send disconnect soak + :- %+ weld + (turn ~(tap in ~(key by agents.state)) register) + (turn ~(tap in ~(key by agents.state)) disconnect) lick-gate(unix-duct hen) :: %spin :: A gall agent wants to spin a communication line From dd90bb9bda2b77fd75ed5ea001d73c32ada8f5d7 Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Thu, 27 Apr 2023 15:29:54 -0400 Subject: [PATCH 021/152] changed name from term to path --- pkg/arvo/sys/lull.hoon | 2 +- pkg/arvo/sys/vane/lick.hoon | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 394c0b1146..a076fec09d 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -2373,7 +2373,7 @@ [%soak =name =mark =noun] :: soak a noun from the IPC port == :: - +$ name @tas + +$ name path -- ::lick :: ++ rand :: computation diff --git a/pkg/arvo/sys/vane/lick.hoon b/pkg/arvo/sys/vane/lick.hoon index 489214529a..292b78a4db 100644 --- a/pkg/arvo/sys/vane/lick.hoon +++ b/pkg/arvo/sys/vane/lick.hoon @@ -20,7 +20,7 @@ agents=(map name duct) == :: - +$ name @tas + +$ name path -- :: ~% %lick ..part ~ From cc15cd017bb644f4ebfbe2db0b020eab57a25b6e Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Thu, 4 May 2023 10:06:02 -0400 Subject: [PATCH 022/152] cleaned up and renamed some stuff. added scry endpoints --- pkg/arvo/sys/vane/lick.hoon | 63 ++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/pkg/arvo/sys/vane/lick.hoon b/pkg/arvo/sys/vane/lick.hoon index 292b78a4db..391612f4dc 100644 --- a/pkg/arvo/sys/vane/lick.hoon +++ b/pkg/arvo/sys/vane/lick.hoon @@ -7,17 +7,12 @@ => |% +$ move [p=duct q=(wite note gift)] +$ note ~ :: out request $-> - ::$% $: %g :: to %gall - :: $>(%deal task:gall) :: full transmission - :: == :: - ::== :: - :: +$ sign ~ :: +$ lick-state $: %0 unix-duct=duct - agents=(map name duct) + owners=(map name duct) == :: +$ name path @@ -42,7 +37,7 @@ ++ disconnect |= =name ^- move - =/ =duct (~(get by agents) name) + =/ =duct (~(get by owners) name) [+.duct %give [%soak name %disconnect ~]] :: +call: handle a +task:lick request :: @@ -57,38 +52,37 @@ ?+ -.task [~ lick-gate] %born :: need to register devices with vere and send disconnect soak :- %+ weld - (turn ~(tap in ~(key by agents.state)) register) - (turn ~(tap in ~(key by agents.state)) disconnect) + (turn ~(tap in ~(key by owners.state)) register) + (turn ~(tap in ~(key by owners.state)) disconnect) lick-gate(unix-duct hen) :: %spin :: A gall agent wants to spin a communication line :- ~[(register name.task)] - lick-gate(agents (~(put by agents) name.task hen)) + lick-gate(owners (~(put by owners) name.task hen)) :: %shut :: shut down a communication line - :- ~[[unix-duct.state %give [%shut name.task]]] - lick-gate(agents (~(del by agents) name.task)) + :- [unix-duct.state %give [%shut name.task]]~ + lick-gate(owners (~(del by owners) name.task)) :: %soak :: push a soak to the ipc's owner - =/ ner=duct (~(get by agents.state) name.task) + =/ ner=duct (~(get by owners.state) name.task) :_ lick-gate - ~[[+.ner %give [%soak name.task mark.task noun.task]]] + [+.ner %give [%soak name.task mark.task noun.task]]~ :: %spit :: push a spit to ipc :_ lick-gate - ~[[unix-duct.state %give [%spit name.task mark.task noun.task]]] + [unix-duct.state %give [%spit name.task mark.task noun.task]]~ == :: +load: migrate an old state to a new lick version :: ++ load |= old=lick-state ^+ lick-gate - ~& >> "lick load:" lick-gate(state old) :: +scry: view state :: -:: %a scry out a list of devices -:: %d get a device's dat and tus +:: %a scry out a list of all ipc ports +:: %d get the owner of an ipc port ++ scry ^- roon |= [lyc=gang car=term bem=beam] @@ -98,14 +92,34 @@ =* syd q.bem =* lot=coin $/r.bem =* tyl s.bem - ~& >> "lick scry:" - ~& >> ["lyc" lyc] - ~& >> ["car" car] - ~& >> ["bem" bem] - ~ + :: only respond for the local identity, current timestamp + :: + ?. ?& =(&+our why) + =([%$ %da now] lot) + == + ~ + ?+ car ~ + %a (read-a lyc bem) + %d (read-d lyc bem) + == + :: +read-a: scry our list of devices + :: + ++ read-a + |= [lyc=gang bem=beam] + ^- (unit (unit cage)) + =/ ports ~(tap in ~(key by owners)) + ``[%noun !>(ports)] + :: +read d: get ports owner + :: + ++ read-d + |= [lyc=gang bem=beam] + ^- (unit (unit cage)) + =* tyl s.bem + =/ devs (~(got by owners) tyl) + ``[%noun !>(devs)] + -- :: ++ stay - ~& >> "lick stay:" state ++ take |= [tea=wire hen=duct dud=(unit goof) hin=sign] @@ -113,6 +127,5 @@ ?^ dud ~|(%lick-take-dud (mean tang.u.dud)) :: - ~& >> "lick take:" [~ lick-gate] -- From f5910678697fe44019c3574289d529eee9aec714 Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Thu, 4 May 2023 10:07:11 -0400 Subject: [PATCH 023/152] deleted a wrong line --- pkg/arvo/sys/vane/lick.hoon | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/arvo/sys/vane/lick.hoon b/pkg/arvo/sys/vane/lick.hoon index 391612f4dc..47168dc055 100644 --- a/pkg/arvo/sys/vane/lick.hoon +++ b/pkg/arvo/sys/vane/lick.hoon @@ -92,6 +92,7 @@ =* syd q.bem =* lot=coin $/r.bem =* tyl s.bem + |^ :: only respond for the local identity, current timestamp :: ?. ?& =(&+our why) From 8bd18039cb520365a71a00de5cfc39be500fc09d Mon Sep 17 00:00:00 2001 From: Amadeo Bellotti Date: Thu, 4 May 2023 10:17:16 -0400 Subject: [PATCH 024/152] XX for spin --- pkg/arvo/sys/vane/lick.hoon | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/arvo/sys/vane/lick.hoon b/pkg/arvo/sys/vane/lick.hoon index 47168dc055..76ec68a0ef 100644 --- a/pkg/arvo/sys/vane/lick.hoon +++ b/pkg/arvo/sys/vane/lick.hoon @@ -57,6 +57,8 @@ lick-gate(unix-duct hen) :: %spin :: A gall agent wants to spin a communication line + :: XX Right now the last agent to register a port owns it. Should + :: this change? :- ~[(register name.task)] lick-gate(owners (~(put by owners) name.task hen)) :: From 65b069a1d99db346873fcf4f0236dec623ff6b8d Mon Sep 17 00:00:00 2001 From: Ted Blackman Date: Thu, 4 May 2023 11:42:41 -0400 Subject: [PATCH 025/152] zuse: kelvin 412 --- pkg/arvo/sys.kelvin | 2 +- pkg/arvo/sys/zuse.hoon | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/arvo/sys.kelvin b/pkg/arvo/sys.kelvin index f5efeaa294..5d8a35da3e 100644 --- a/pkg/arvo/sys.kelvin +++ b/pkg/arvo/sys.kelvin @@ -1 +1 @@ -[%zuse 413] +[%zuse 412] diff --git a/pkg/arvo/sys/zuse.hoon b/pkg/arvo/sys/zuse.hoon index 166c6727b9..9f7950ebbc 100644 --- a/pkg/arvo/sys/zuse.hoon +++ b/pkg/arvo/sys/zuse.hoon @@ -4,7 +4,7 @@ => ..lull ~% %zuse ..part ~ |% -++ zuse %413 +++ zuse %412 :: :: :: :::: :: :: (2) engines :: :: :: From 6213e0bbb3c4680dea8044d2e79f4c5eaeb7b5b6 Mon Sep 17 00:00:00 2001 From: yosoyubik Date: Fri, 5 May 2023 13:06:17 +0200 Subject: [PATCH 026/152] ames: move +bind-duct to peer-core --- pkg/arvo/sys/vane/ames.hoon | 76 ++++++++++++++++++------------------- tests/sys/grq.hoon | 31 +++++++++++---- 2 files changed, 60 insertions(+), 47 deletions(-) diff --git a/pkg/arvo/sys/vane/ames.hoon b/pkg/arvo/sys/vane/ames.hoon index f18550bee1..e708b4c71a 100644 --- a/pkg/arvo/sys/vane/ames.hoon +++ b/pkg/arvo/sys/vane/ames.hoon @@ -180,20 +180,6 @@ =+ wid=(met 3 pat) ?> (lte wid 384) [pat wid] -:: -:: +bind-duct: find or make new $bone for .duct in .ossuary -:: -++ bind-duct - |= [=ossuary =duct] - ^+ [next-bone.ossuary ossuary] - :: - ?^ existing=(~(get by by-duct.ossuary) duct) - [u.existing ossuary] - :: - :- next-bone.ossuary - :+ (add 4 next-bone.ossuary) - (~(put by by-duct.ossuary) duct next-bone.ossuary) - (~(put by by-bone.ossuary) next-bone.ossuary duct) :: +make-bone-wire: encode ship, rift and bone in wire for sending to vane :: ++ make-bone-wire @@ -2040,8 +2026,7 @@ |= todos=alien-agenda todos(messages [[duct plea] messages.todos]) :: - =/ =peer-state +.u.ship-state - =/ peer-core (abed-peer:pe ship peer-state) + =+ peer-core=(abed-peer:pe ship +.u.ship-state) |^ ?+ plea foreign-plea [%a [%kill ~] =bone] kill-plea [%a [%cork ~] =bone] =~(cork-plea (emit duct %give %done ~)) @@ -2049,21 +2034,22 @@ :: .plea is from local vane to foreign ship :: ++ foreign-plea - =^ =bone ossuary.peer-state (bind-duct ossuary.peer-state duct) + =^ =bone peer-core (bind-duct:peer-core duct) %- %^ ev-trace msg.veb ship |. ^- tape =/ sndr [our our-life.channel.peer-core] =/ rcvr [ship her-life.channel.peer-core] "plea {}" abet:(on-memo:peer-core bone plea %plea) - :: client ames [%cork as plea] -> server ames sinks plea, - :: passes a+/close to itself, - :: put flow in closing, and give %done - :: sink ack, pass a+/kill task <- after +on-take-done, ack %cork pea - :: to itself and delete the flow + :: client ames [%cork as plea] -> server ames [sinks %cork plea], + :: pass a+/close task to self + :: put flow in closing, and give %done + :: sink %ack, pass a+/kill task <- after +on-take-done, ack %cork plea + :: to self, and delete the flow and delete the flow in +handle-cork :: - ++ cork-plea abet:(on-close-flow:peer-core ;;(@ +.payload.plea)) - ++ kill-plea abet:(on-kill-flow:peer-core ;;(@ +.payload.plea)) + :: + ++ cork-plea abet:(on-cork-flow:peer-core ;;(@ payload.plea)) + ++ kill-plea abet:(on-kill-flow:peer-core ;;(@ payload.plea)) -- :: +on-cork: handle request to kill a flow :: @@ -2076,26 +2062,23 @@ %+ enqueue-alien-todo ship |= todos=alien-agenda todos(messages [[duct plea] messages.todos]) - =/ =peer-state +.u.ship-state - =/ =channel [[our ship] now channel-state -.peer-state] :: - =/ [=bone ossuary=_ossuary.peer-state] - ?^ cork-bone [u.cork-bone ossuary.peer-state] - (bind-duct ossuary.peer-state duct) - =. ossuary.peer-state ossuary + =+ peer-core=(abed-peer:pe ship +.u.ship-state) + =^ =bone peer-core + ?^ cork-bone [u.cork-bone peer-core] + (bind-duct:peer-core duct) :: - ?. (~(has by by-bone.ossuary.peer-state) bone) + ?. (~(has by by-bone.ossuary.peer-state.peer-core) bone) %. event-core %^ ev-trace odd.veb ship |.("trying to cork {}, not in the ossuary, ignoring") :: - =. closing.peer-state (~(put in closing.peer-state) bone) %- %^ ev-trace msg.veb ship |. ^- tape - =/ sndr [our our-life.channel] - =/ rcvr [ship her-life.channel] + =/ sndr [our our-life.channel.peer-core] + =/ rcvr [ship her-life.channel.peer-core] "cork plea {}" - abet:(~(on-memo pe [peer-state channel]) bone plea %plea) + abet:(on-memo:(on-cork-flow:peer-core bone) bone plea %plea) :: +on-kroc: cork all stale flows from failed subscriptions :: ++ on-kroc @@ -2763,6 +2746,21 @@ ~| %dangling-bone^her^bone (~(got by by-bone.ossuary.peer-state) bone) :: + :: +bind-duct: find or make new $bone for .duct in .ossuary + :: + ++ bind-duct + |= =^duct + =* ossa ossuary.peer-state + ^+ [next-bone.ossa peer-core] + ?^ existing=(~(get by by-duct.ossa) duct) + [u.existing peer-core] + :- next-bone.ossa + =. ossa + :+ (add 4 next-bone.ossa) + (~(put by by-duct.ossa) duct next-bone.ossa) + (~(put by by-bone.ossa) next-bone.ossa duct) + peer-core + :: ++ is-corked |= =bone ?| (~(has in corked.peer-state) bone) @@ -2934,13 +2932,13 @@ =. keens (~(put by keens) path *keen-state) fi-abet:(fi-start:(abed:fi path) duct) :: - :: +on-close-flow: close flow on cork receiver side + :: +on-cork-flow: mark .bone as closing :: - ++ on-close-flow + ++ on-cork-flow |= =bone ^+ peer-core peer-core(closing.peer-state (~(put in closing.peer-state) bone)) - :: +on-kill-flow: kill flow on cork sender side + :: +on-kill-flow: delete flow on cork sender side :: ++ on-kill-flow |= =bone @@ -3984,7 +3982,7 @@ :: account for publishers that still handle ames-to-ames %pleas :: ?> &(?=([%cork *] payload.plea) ?=(%flow -.path.plea)) - (pe-emit duct %pass wire %a %plea her [%a /close bone]) + (pe-emit duct %pass wire %a %plea her [%a /cork bone]) :: :: +ha-boon: handle response message, acking unconditionally :: diff --git a/tests/sys/grq.hoon b/tests/sys/grq.hoon index d10c15c528..2e7df59495 100644 --- a/tests/sys/grq.hoon +++ b/tests/sys/grq.hoon @@ -398,7 +398,7 @@ 0xb.130c.ab37.ca24.49cd.aecb.23ba.70f1.6f1c.4d00.124e.c9a5. 3413.3843.d81c.47c4.7040.6e62.3700.0200.0132.e1ab.9004 == - :~ :- ~[//unix] [%pass /bone/~nec/0/1 %a %plea ~nec [%a /close ~]] + :~ :- ~[//unix] [%pass /bone/~nec/0/1 %a %plea ~nec [%a /cork 1]] == == :- t27 |. :- %| @@ -408,12 +408,12 @@ %: ames-check-call:v ames.bud [~1111.1.8 0xbeef.dead *roof] :- ~[/bone/~nec/0/1 //unix] - [%plea ~nec [%a /close ~]] + [%plea ~nec [%a /cork 1]] :~ :- ~[/bone/~nec/0/1 //unix] [%give %done ~] == == - :: publisher ames hears cork done from self, sends ack packet - ~& > 'publisher ames hears cork done from self, sends ack packet' + :: publisher ames hears cork done from self, sends ack and /cork to self + ~& > 'publisher ames hears cork done from self, sends ack and /cork to self' :- t28 |. :- %| =^ t29 ames.bud %: ames-check-take:v ames.bud @@ -474,8 +474,8 @@ [%gall %unto %watch-ack ~] ~ == - :: subscriber ames hears %cork ack - ~& > 'subscriber ames hears %cork ack' + :: subscriber ames hears %cork ack, sends /kill to self + ~& > 'subscriber ames hears %cork ack, sends /kill to self' :- t32 |. :- %| =^ t33 ames.nec %: ames-check-call:v ames.nec @@ -485,9 +485,24 @@ 0x5f.f966.8e00.0449.bdec.9006.c7e5.1237. 1d87.53fe.d7bb.ad00.0100.0223.c6a8.5804 == - [~[/ames] [%pass /pump/~bud/0 %b %rest ~1111.1.5..00.02.00]]~ + :~ :- ~[//unix] + [%pass /bone/~bud/0/0 %a %plea ~bud [%a /kill 0]] + :: + :- ~[/ames] + [%pass /pump/~bud/0 %b %rest ~1111.1.5..00.02.00] + == == - :- t33 |. :- %& + :: subscriber ames hears /kill from self, deletes the flow + ~& > 'subscriber ames hears /kill from self, deletes the flow' + :- t33 |. :- %| + =^ t34 ames.nec + %: ames-check-call:v ames.nec + [~1111.1.10 0xdead.beef *roof] + :- ~[/bone/~bud/0/0 //unix] + [%plea ~bud [%a /kill 0]] + ~ + == + :- t34 |. :- %& ;: weld %+ expect-eq !> (sy 0 ~) From 0fee4ce50b0a2211fb5b4ad6e59ce3dab89d9128 Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 5 May 2023 21:59:17 +0200 Subject: [PATCH 027/152] eyre: guest ids for unauthenticated requests aka "the open eyre" aka "universal basic identity" Urbit already supports presence on the clearnet, but fails to expose any of its interactive affordances to unauthenticated users. Here, we improve this situation by granting "guest identity" @ps to every unauthenticated HTTP request, and extending the channels functionality to them. Sessions no longer represent only the local identity. Instead, each session has either the local identity, or a fake guest identity associated with it. Every request that does not provide a session key/cookie gets assigned a fresh one with a guest identity on the spot. As a result, every single request has an identity associated with it. The identity of a request gets propagated into userspace, if the request ends up there. For normal HTTP requests, this means the src.bowl gets set to that identity for both the watch and poke of the request. For backwards compatibility, the authenticated flag on the request noun gets set at normal: only true if the request came from the local identity. For channel requests, this means the src.bowl gets set to that identity for any pokes and watches it sends, and it can only send those to agents running on the local ship. The scry endpoint remains unchanged in its behavior: only available to the local identity. Notable implementation detail changes in this diff include: - Factored all gall interactions out into +deal-as. - Sessions no longer represent exclusively the local identity. This matters a lot to +give-session-tokens, %code-changed, and logout handling. - Session management got factored out into explicit +start-session and +close-session arms. --- pkg/arvo/sys/lull.hoon | 22 +- pkg/arvo/sys/vane/eyre.hoon | 547 ++++++++++++++++++++++-------------- 2 files changed, 362 insertions(+), 207 deletions(-) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index ed6e156c53..b54fd43f7a 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -2163,6 +2163,14 @@ :: inbound-request: the original request which caused this connection :: =inbound-request + :: session-id: the session associated with this connection + :: identity: the identity associated with this connection + :: + ::NOTE technically the identity is associated with the session (id), + :: but we may still need to know the identity that was used + :: after the session proper expires. + :: + [session-id=@uv =identity] :: response-header: set when we get our first %start :: response-header=(unit response-header:http) @@ -2180,7 +2188,10 @@ :: +session: server side data about a session :: +$ session - $: :: expiry-time: when this session expires + $: :: identity: authentication level & id of this session + :: + =identity + :: expiry-time: when this session expires :: :: We check this server side, too, so we aren't relying on the browser :: to properly handle cookie expiration as a security mechanism. @@ -2194,6 +2205,14 @@ :: mint some sort of long lived cookie for mobile apps which only has :: access to a single application path. == + :: $identity: authentication method & @p + :: + +$ identity + $~ [%ours ~] + $% [%ours ~] :: local, root + [%fake who=@p] :: guest id + :: [%real who=@p] :: authed cross-ship + == :: channel-state: state used in the channel system :: +$ channel-state @@ -2237,6 +2256,7 @@ :: +$ channel $: mode=?(%json %jam) + =identity :: channel-state: expiration time or the duct currently listening :: :: For each channel, there is at most one open EventSource diff --git a/pkg/arvo/sys/vane/eyre.hoon b/pkg/arvo/sys/vane/eyre.hoon index 674e592171..1a8d826cf9 100644 --- a/pkg/arvo/sys/vane/eyre.hoon +++ b/pkg/arvo/sys/vane/eyre.hoon @@ -70,7 +70,7 @@ ++ axle $: :: date: date at which http-server's state was updated to this data structure :: - date=%~2023.4.11 + date=%~2023.5.3 :: server-state: state of inbound requests :: =server-state @@ -623,14 +623,14 @@ =/ act [%app app=%lens] :: =/ connection=outstanding-connection - [act [& secure address request] ~ 0] + [act [& secure address request] [*@uv [%ours ~]] ~ 0] :: =. connections.state %. (~(put by connections.state) duct connection) (trace 2 |.("{} creating local")) :: :_ state - (subscribe-to-app app.act inbound-request.connection) + (subscribe-to-app [%ours ~] app.act inbound-request.connection) :: +request: starts handling an inbound http request :: ++ request @@ -650,13 +650,19 @@ =/ [=action suburl=@t] (get-action-for-binding host url.request) :: - =/ authenticated (request-is-logged-in:authentication request) + =^ [suv=@uv =identity som=(list move)] state + (session-for-request:authentication request) + =; [moz=(list move) sat=server-state] + [(weld som moz) sat] + :: + =/ authenticated ?=(%ours -.identity) :: record that we started an asynchronous response :: =/ connection=outstanding-connection - [action [authenticated secure address request] ~ 0] + [action [authenticated secure address request] [suv identity] ~ 0] =. connections.state - :: NB: required by +handle-response. XX optimize + :: NB: required by +handle-response and +handle-request:authentication. + :: XX optimize :: (~(put by connections.state) duct connection) :: redirect to https if insecure, redirects enabled @@ -781,16 +787,16 @@ :: %app :_ state - (subscribe-to-app app.action inbound-request.connection) + (subscribe-to-app identity app.action inbound-request.connection) :: %authentication (handle-request:authentication secure address request) :: %logout - (handle-logout:authentication authenticated request) + (handle-logout:authentication suv request) :: %channel - (handle-request:by-channel secure authenticated address request) + (handle-request:by-channel [suv identity] address request) :: %scry (handle-scry authenticated address request(url suburl)) @@ -910,18 +916,17 @@ :: +subscribe-to-app: subscribe to app and poke it with request data :: ++ subscribe-to-app - |= [app=term =inbound-request:eyre] + |= [=identity app=term =inbound-request:eyre] ^- (list move) - :~ :* duct %pass /watch-response/[eyre-id] - %g %deal [our our] app - %watch /http-response/[eyre-id] - == + :~ %+ deal-as + /watch-response/[eyre-id] + [identity our app %watch /http-response/[eyre-id]] :: - :* duct %pass /run-app-request/[eyre-id] - %g %deal [our our] app - %poke %handle-http-request - !>(`[@ta inbound-request:eyre]`[eyre-id inbound-request]) - == + %+ deal-as + /run-app-request/[eyre-id] + :^ identity our app + :+ %poke %handle-http-request + !>(`[@ta inbound-request:eyre]`[eyre-id inbound-request]) == :: +cancel-request: handles a request being externally aborted :: @@ -940,11 +945,9 @@ %app :_ state :_ ~ - %- (trace 1 |.("leaving subscription to {}")) - :* duct %pass /watch-response/[eyre-id] - %g %deal [our our] app.action.u.connection - %leave ~ - == + =, u.connection + %- (trace 1 |.("leaving subscription to {}")) + (deal-as /watch-response/[eyre-id] identity our app.action %leave ~) :: ?(%authentication %logout %name) [~ state] @@ -987,7 +990,7 @@ |= [secure=? =address =request:http] ^- [(list move) server-state] :: - :: if we received a simple get, redirect if logged in otherwise + :: if we received a simple get: redirect if logged in, otherwise :: show login page :: ?: =('GET' method.request) @@ -1005,7 +1008,7 @@ (login-page redirect our %.n) =/ cookie-line=@t (session-cookie-string u.session-id &) - =/ actual-redirect + =/ actual-redirect ?~ redirect '/' ?:(=(u.redirect '') '/' u.redirect) %- handle-response @@ -1039,105 +1042,60 @@ :: ?. =(u.password code) (return-static-data-on-duct 400 'text/html' (login-page redirect our %.y)) - :: mint a unique session cookie + :: clean up the session they're changing out from :: - =/ session=@uv - |- - =/ candidate=@uv (~(raw og eny) 128) - ?. (~(has by sessions.authentication-state.state) candidate) - candidate - $(eny (shas %try-again candidate)) - :: record cookie and record expiry time + =^ moz state + ?~ sid=(session-id-from-request request) [~ state] + (close-session u.sid |) + :: initialize the new session :: - =/ first-session=? =(~ sessions.authentication-state.state) - =/ expires-at=@da (add now session-timeout) - =. sessions.authentication-state.state - (~(put by sessions.authentication-state.state) session [expires-at ~]) + =^ fex state (start-session %local) + :: associate the new session with the request that caused the login :: - =/ cookie-line=@t - (session-cookie-string session &) + :: if we don't do this here, +handle-response will include the old + :: session's cookie, confusing the client. + :: + =. connections.state + %+ ~(jab by connections.state) duct + |= o=outstanding-connection + o(session-id session.fex) :: =; out=[moves=(list move) server-state] - =. moves.out [give-session-tokens moves.out] - :: if we didn't have any cookies previously, start the expiry timer - :: - ?. first-session out - =- out(moves [- moves.out]) - [duct %pass /sessions/expire %b %wait expires-at] - :: + out(moves [give-session-tokens :(weld moz moves.fex moves.out)]) + ::NOTE that we don't provide a 'set-cookie' header here. + :: +handle-response does that for us. ?~ redirect - %- handle-response - :* %start - :- status-code=204 - ^= headers - :~ ['set-cookie' cookie-line] - == - data=~ - complete=%.y - == - :: + (handle-response %start 204^~ ~ &) =/ actual-redirect ?:(=(u.redirect '') '/' u.redirect) - %- handle-response - :* %start - :- status-code=303 - ^= headers - :~ ['location' actual-redirect] - ['set-cookie' cookie-line] - == - data=~ - complete=%.y - == + (handle-response %start 303^['location' actual-redirect]~ ~ &) :: +handle-logout: handles an http request for logging out :: + ::TODO allow %ours sessions to kill any session on-demand ++ handle-logout - |= [authenticated=? =request:http] + |= [session-id=@uv =request:http] ^- [(list move) server-state] :: whatever we end up doing, we always redirect to the login page :: =/ response=$>(%start http-event:http) :* %start - response-header=[303 ['location' '/~/login']~] + ^= response-header + :- 303 + :~ ['location' '/~/login'] + ['set-cookie' (session-cookie-string session-id |)] + == data=~ complete=%.y == + :: close the session as requested, then send the response :: - =/ session-id=(unit @uv) - (session-id-from-request request) - =? headers.response-header.response ?=(^ session-id) - :_ headers.response-header.response - ['set-cookie' (session-cookie-string u.session-id |)] - ?. &(authenticated ?=(^ session-id)) - (handle-response response) - :: delete the requesting session, or all sessions if so specified - :: - =^ channels=(list @t) sessions.authentication-state.state - =* sessions sessions.authentication-state.state - =/ all=? - ?~ body.request | - =- ?=(^ -) - %+ get-header:http 'all' - (fall (rush q.u.body.request yquy:de-purl:html) ~) - ?. all - :_ (~(del by sessions) u.session-id) - %~ tap in - channels:(~(gut by sessions) u.session-id *session) - :_ ~ - %~ tap in - %+ roll ~(val by sessions) - |= [session all=(set @t)] - (~(uni in all) channels) - :: close all affected channels, then send the response - :: - =| moves=(list move) - |- ^- (quip move server-state) - ?~ channels - =^ moz state - (handle-response response) - [[give-session-tokens (weld moves moz)] state] - %- (trace 1 |.("{(trip i.channels)} discarding channel due to logout")) - =^ moz state - (discard-channel:by-channel i.channels |) - $(moves (weld moves moz), channels t.channels) + =/ all=? + ?~ body.request | + =- ?=(^ -) + %+ get-header:http 'all' + (fall (rush q.u.body.request yquy:de-purl:html) ~) + =^ moz1 state (close-session session-id all) + =^ moz2 state (handle-response response) + [[give-session-tokens (weld moz1 moz2)] state] :: +session-id-from-request: attempt to find a session cookie :: ++ session-id-from-request @@ -1161,12 +1119,22 @@ :: if it's formatted like a valid session cookie, produce it :: `(unit @)`(rush u.urbauth ;~(pfix (jest '0v') viz:ag)) - :: +request-is-logged-in: checks to see if the request is authenticated - :: - :: We are considered logged in if this request has an urbauth - :: Cookie which is not expired. + :: +request-is-logged-in: checks to see if the request has non-guest id :: ++ request-is-logged-in + |= =request:http + ^- ? + ?~ session-id=(session-id-from-request request) + | + ?~ session=(~(get by sessions.authentication-state.state) u.session-id) + | + &(!?=(%fake -.identity.u.session) (lte now expiry-time.u.session)) + :: +request-is-authenticated: checks to see if the request is "us" + :: + :: We are considered authenticated if this request has an urbauth + :: Cookie for the local identity that is not expired. + :: + ++ request-is-authenticated |= =request:http ^- ? :: does the request pass a session cookie? @@ -1177,9 +1145,96 @@ :: ?~ session=(~(get by sessions.authentication-state.state) `@uv`u.session-id) %.n - :: is this session still valid? + :: does this session have our id, and is it still valid? :: - (lte now expiry-time.u.session) + &(?=(%ours -.identity.u.session) (lte now expiry-time.u.session)) + :: +start-session: create a new session with %local or %guest identity + :: + ++ start-session + |= kind=?(%local %guest) + ^- [[session=@uv =identity moves=(list move)] server-state] + =; [key=@uv sid=identity] + :- :+ key sid + :: if no session existed previously, we must kick off the + :: session expiry timer + :: + ?~ sessions.authentication-state.state ~ + [duct %pass /sessions/expire %b %wait (add now session-timeout)]~ + =- state(sessions.authentication-state -) + %+ ~(put by sessions.authentication-state.state) key + [sid (add now session-timeout) ~] + :: create a new session with a fake identity + :: + =/ sik=@uv new-session-key + :- sik + ?: ?=(%local kind) [%ours ~] + :- %fake + :: pre-scramble our ship name into its displayed value, and + :: truncate it to be at most moon-length, so that we can overlay + :: it onto the end of a comet name for visual consistency + :: + =. our (end 3^8 (fein:ob our)) + %^ cat 3 our + %+ rsh [3 (met 3 our)] + (~(raw og (shas %fake-name eny)) 128) + :: +session-for-request: get the session details for the request + :: + :: creates a guest session if the request does not have a valid session. + :: there is no need to call +give-session-tokens after this, because + :: guest session do not make valid "auth session" tokens. + :: + ++ session-for-request + |= =request:http + ^- [[session=@uv =identity moves=(list move)] server-state] + =* new (start-session %guest) + ?~ sid=(session-id-from-request request) + new + ?~ ses=(~(get by sessions.authentication-state.state) u.sid) + new + ?: (gth now expiry-time.u.ses) + new + [[u.sid identity.u.ses ~] state] + :: +close-session: delete a session and its associated channels + :: + :: if :all is true, deletes all sessions that share the same identity. + :: if this closes an %ours session, the caller is responsible for + :: also calling +give-session-tokens afterwards. + :: + ++ close-session + |= [session-id=@uv all=?] + ^- [(list move) server-state] + ?~ ses=(~(get by sessions.authentication-state.state) session-id) + [~ state] + :: delete the session(s) and find the associated channels + :: + =^ channels=(list @t) sessions.authentication-state.state + =* sessions sessions.authentication-state.state + :: either delete just the specific session and its channels, + :: + ?. all + :- ~(tap in channels.u.ses) + (~(del by sessions) session-id) + :: or delete all sessions with the identity from :session-id + :: + :- %~ tap in + %+ roll ~(val by sessions) + |= [session all=(set @t)] + ?. =(identity identity.u.ses) all + (~(uni in all) channels) + %- my + %+ skip ~(tap by sessions) + |= [@uv session] + =(identity identity.u.ses) + :: close all affected channels, then send the response + :: + =| moves=(list move) + |- ^- (quip move server-state) + ?~ channels [moves state] + %- %+ trace 1 + |.("{(trip i.channels)} discarding channel due to closed session") + =^ moz state + (discard-channel:by-channel i.channels |) + $(moves (weld moves moz), channels t.channels) :: +code: returns the same as |code :: ++ code @@ -1213,16 +1268,8 @@ :: +handle-request: handles an http request for the subscription system :: ++ handle-request - |= [secure=? authenticated=? =address =request:http] + |= [[session-id=@uv =identity] =address =request:http] ^- [(list move) server-state] - :: if we're not authenticated error, but don't redirect. - :: - :: We don't redirect because subscription stuff is never the toplevel - :: page; issuing a redirect won't help. - :: - ?. authenticated - %^ return-static-data-on-duct 403 'text/html' - (error-page 403 authenticated url.request "unauthenticated channel usage") :: parse out the path key the subscription is on :: =+ request-line=(parse-request-line url.request) @@ -1230,7 +1277,7 @@ :: url is not of the form '/~/channel/' :: %^ return-static-data-on-duct 400 'text/html' - (error-page 400 authenticated url.request "malformed channel url") + (error-page 400 & url.request "malformed channel url") :: channel-id: unique channel id parsed out of url :: =+ channel-id=i.t.t.site.request-line @@ -1238,13 +1285,13 @@ ?: =('PUT' method.request) :: PUT methods starts/modifies a channel, and returns a result immediately :: - (on-put-request channel-id request) + (on-put-request channel-id identity request) :: ?: =('GET' method.request) - (on-get-request channel-id request) + (on-get-request channel-id [session-id identity] request) ?: =('POST' method.request) :: POST methods are used solely for deleting channels - (on-put-request channel-id request) + (on-put-request channel-id identity request) :: ((trace 0 |.("session not a put")) `state) :: +on-cancel-request: cancels an ongoing subscription @@ -1298,7 +1345,7 @@ :: state. :: ++ update-timeout-timer-for - |= [mode=?(%json %jam) channel-id=@t] + |= [mode=?(%json %jam) =identity channel-id=@t] ^+ ..update-timeout-timer-for :: when our callback should fire :: @@ -1310,7 +1357,7 @@ %_ ..update-timeout-timer-for session.channel-state.state %+ ~(put by session.channel-state.state) channel-id - [mode [%& expiration-time duct] 0 now ~ ~ ~ ~] + [mode identity [%& expiration-time duct] 0 now ~ ~ ~ ~] :: moves [(set-timeout-move channel-id expiration-time) moves] @@ -1362,14 +1409,19 @@ :: client in text/event-stream format. :: ++ on-get-request - |= [channel-id=@t =request:http] + |= [channel-id=@t [session-id=@uv =identity] =request:http] ^- [(list move) server-state] :: if there's no channel-id, we must 404 ::TODO but arm description says otherwise? :: ?~ maybe-channel=(~(get by session.channel-state.state) channel-id) %^ return-static-data-on-duct 404 'text/html' - (error-page 404 %.y url.request ~) + (error-page 404 | url.request ~) + :: find the channel creator's identity, make sure it matches + :: + ?. =(identity identity.u.maybe-channel) + %^ return-static-data-on-duct 403 'text/html' + (error-page 403 | url.request ~) :: find the requested "mode" and make sure it doesn't conflict :: =/ mode=?(%json %jam) @@ -1443,11 +1495,8 @@ :: associate this channel with the session cookie :: =. sessions.authentication-state.state - =/ session-id=(unit @uv) - (session-id-from-request:authentication request) - ?~ session-id sessions.authentication-state.state %+ ~(jab by sessions.authentication-state.state) - u.session-id + session-id |= =session session(channels (~(put in channels.session) channel-id)) :: initialize sse heartbeat @@ -1489,8 +1538,16 @@ :: a set of commands in JSON format in the body of the message. :: ++ on-put-request - |= [channel-id=@t =request:http] + |= [channel-id=@t =identity =request:http] ^- [(list move) server-state] + :: if the channel already exists, and is not of this identity, 403 + :: + :: the creation case happens in the +update-timeout-timer-for below + :: + ?: ?~ c=(~(get by session.channel-state.state) channel-id) | + !=(identity identity.u.c) + %^ return-static-data-on-duct 403 'text/html' + (error-page 403 | url.request ~) :: error when there's no body :: ?~ body.request @@ -1517,7 +1574,7 @@ :: :channel-timeout from now. if we have one which has a timer, update :: that timer. :: - =. ..on-put-request (update-timeout-timer-for mode channel-id) + =. ..on-put-request (update-timeout-timer-for mode identity channel-id) :: for each request, execute the action passed in :: =+ requests=p.maybe-requests @@ -1527,6 +1584,11 @@ :: or other errors cause the entire thing to fail with a 400 and a tang. :: =| gall-moves=(list move) + =/ from=ship + ?- -.identity + %ours our + %fake who.identity + == |- :: ?~ requests @@ -1556,15 +1618,14 @@ =. gall-moves :_ gall-moves ^- move - :^ duct %pass /channel/poke/[channel-id]/(scot %ud request-id.i.requests) - =, i.requests - :* %g %deal `sock`[our ship] app - ^- task:agent:gall - :+ %poke-as mark - ?- -.i.requests - %poke [%noun !>(noun)] - %poke-json [%json !>(json)] - == + %+ deal-as + /channel/poke/[channel-id]/(scot %ud request-id) + :^ from ship app + ^- task:agent:gall + :+ %poke-as mark + ?- -.i.requests + %poke [%noun !>(noun)] + %poke-json [%json !>(json)] == :: $(requests t.requests) @@ -1576,12 +1637,10 @@ =. gall-moves :_ gall-moves ^- move - :^ duct %pass - (subscription-wire channel-id request-id ship app) %- (trace 1 |.("subscribing to {} on {}")) - :* %g %deal [our ship] app - `task:agent:gall`[%watch path] - == + %+ deal-as + (subscription-wire channel-id request-id ship app) + [from ship app %watch path] :: =. session.channel-state.state %+ ~(jab by session.channel-state.state) channel-id @@ -1613,12 +1672,10 @@ :_ gall-moves ^- move =, u.maybe-subscription - :^ duc %pass - (subscription-wire channel-id subscription-id.i.requests ship app) %- (trace 1 |.("leaving subscription to {}")) - :* %g %deal [our ship] app - `task:agent:gall`[%leave ~] - == + %+ deal-as + (subscription-wire channel-id subscription-id ship app) + [from ship app %leave ~] :: =. session.channel-state.state %+ ~(jab by session.channel-state.state) channel-id @@ -1663,9 +1720,10 @@ :_ state :_ ~ ^- move - :^ duct %pass + %+ deal-as (subscription-wire channel-id request-id ship app) - [%g %deal [our ship] app `task:agent:gall`[%leave ~]] + =+ id=identity:(~(got by session.channel-state.state) channel-id) + [id ship app %leave ~] :: +emit-event: records an event occurred, possibly sending to client :: :: When an event occurs, we need to record it, even if we immediately @@ -1766,9 +1824,9 @@ :: - and already checked whether we still have that subscription. =+ (~(got by subscriptions.u.channel) request-id) %- (trace 1 |.("leaving subscription to {}")) - :^ duct %pass + %+ deal-as (subscription-wire channel-id request-id ship app) - [%g %deal [our ship] app %leave ~] + [identity.u.channel ship app %leave ~] :: update channel state to reflect the %kick :: =? u.channel kicking @@ -1977,9 +2035,9 @@ |= [request-id=@ud ship=@p app=term =path duc=^duct] ^- move %- (trace 1 |.("{} leaving subscription to {}")) - :^ duc %pass + %+ deal-as (subscription-wire channel-id request-id ship app) - [%g %deal [our ship] app %leave ~] + [identity.session ship app %leave ~] -- :: +handle-gall-error: a call to +poke-http-response resulted in a %coup :: @@ -1995,11 +2053,9 @@ ?. ?=(%app -.action.connection) ~ :_ ~ - %- (trace 1 |.("leaving subscription to {}")) - :* duct %pass /watch-response/[eyre-id] - %g %deal [our our] app.action.connection - %leave ~ - == + =, connection + %- (trace 1 |.("leaving subscription to {}")) + (deal-as /watch-response/[eyre-id] identity our app.action %leave ~) :: =^ moves-2 state %^ return-static-data-on-duct 500 'text/html' @@ -2032,31 +2088,25 @@ %start ?^ response-header.u.connection-state ((trace 0 |.("{} error multiple start")) error-connection) - :: if request was authenticated, extend the session & cookie's life + :: extend the request's session's + cookie's life :: =^ response-header sessions.authentication-state.state =, authentication - =* sessions sessions.authentication-state.state - =* inbound inbound-request.u.connection-state - =* no-op [response-header.http-event sessions] + =* session-id session-id.u.connection-state + =* sessions sessions.authentication-state.state + =* inbound inbound-request.u.connection-state :: - ?. authenticated.inbound - no-op - ?~ session-id=(session-id-from-request request.inbound) - :: cookies are the only auth method, so this is unexpected - :: - ((trace 0 |.("error authenticated without cookie")) no-op) - ?. (~(has by sessions) u.session-id) + ?. (~(has by sessions) session-id) :: if the session has expired since the request was opened, :: tough luck, we don't create/revive sessions here :: - no-op - :_ %+ ~(jab by sessions) u.session-id + [response-header.http-event sessions] + :_ %+ ~(jab by sessions) session-id |= =session session(expiry-time (add now session-timeout)) =- response-header.http-event(headers -) %^ set-header:http 'set-cookie' - (session-cookie-string u.session-id &) + (session-cookie-string session-id &) headers.response-header.http-event :: =* connection u.connection-state @@ -2137,12 +2187,10 @@ ?. ?=(%app -.action.u.connection-state) ~ :_ ~ + =, u.connection-state %- %+ trace 1 - |.("leaving subscription to {}") - :* duct %pass /watch-response/[eyre-id] - %g %deal [our our] app.action.u.connection-state - %leave ~ - == + |.("leaving subscription to {}") + (deal-as /watch-response/[eyre-id] identity our app.action %leave ~) -- :: +set-response: remember (or update) a cache mapping :: @@ -2252,13 +2300,33 @@ (cury cat 3) ?~ ext.request-line '' (cat 3 '.' u.ext.request-line) - :: +give-session-tokens: send valid session tokens to unix + :: +give-session-tokens: send valid local session tokens to unix :: ++ give-session-tokens ^- move :- outgoing-duct.state - =* ses sessions.authentication-state.state - [%give %sessions (~(run in ~(key by ses)) (cury scot %uv))] + :+ %give %sessions + %- sy + %+ murn ~(tap by sessions.authentication-state.state) + |= [sid=@uv session] + ?. ?=(%ours -.identity) ~ + (some (scot %uv sid)) + :: +new-session-key + :: + ++ new-session-key + |- ^- @uv + =/ candidate=@uv (~(raw og (shas %session-key eny)) 128) + ?. (~(has by sessions.authentication-state.state) candidate) + candidate + $(eny (shas %try-again candidate)) + :: + ++ deal-as + |= [=wire identity=$@(@p identity) =ship =dude:gall =task:agent:gall] + ^- move + =/ from=@p + ?@ identity identity + ?-(-.identity %ours our, %fake who.identity) + [duct %pass wire %g %deal [from ship] dude task] :: ++ trace |= [pri=@ print=(trap tape)] @@ -2461,22 +2529,23 @@ == :: ?: ?=(%code-changed -.task) - ~> %slog.[0 leaf+"eyre: code-changed: throwing away cookies and sessions"] - =. authentication-state.server-state.ax *authentication-state + ~> %slog.[0 leaf+"eyre: code-changed: throwing away local sessions"] + =* event-args [[eny duct now rof] server-state.ax] + =* auth authentication:(per-server-event event-args) + :: find all the %ours sessions, we must close them :: - =/ event-args [[eny duct now rof] server-state.ax] - =* by-channel by-channel:(per-server-event event-args) - =* channel-state channel-state.server-state.ax - :: - =/ channel-ids=(list @t) ~(tap in ~(key by session.channel-state)) + =/ siz=(list @uv) + %+ murn ~(tap by sessions.authentication-state.server-state.ax) + |= [sid=@uv session] + ?:(?=(%ours -.identity) (some sid) ~) =| moves=(list (list move)) |- ^- [(list move) _http-server-gate] - ?~ channel-ids + ?~ siz [(zing (flop moves)) http-server-gate] - :: discard channel state, and cancel any active gall subscriptions + :: discard the session, clean up its channels :: - =^ mov server-state.ax (discard-channel:by-channel i.channel-ids |) - $(moves [mov moves], channel-ids t.channel-ids) + =^ mov server-state.ax (close-session:auth i.siz |) + $(moves [mov moves], siz t.siz) :: :: all other commands operate on a per-server-event :: @@ -2776,14 +2845,15 @@ [date=%~2022.7.26 server-state=server-state-0] [date=%~2023.2.17 server-state=server-state-1] [date=%~2023.3.16 server-state=server-state-2] - [date=%~2023.4.11 =server-state] + [date=%~2023.4.11 server-state-3] + [date=%~2023.5.3 server-state] == :: +$ server-state-0 $: bindings=(list [=binding =duct =action]) =cors-registry - connections=(map duct outstanding-connection) - =authentication-state + connections=(map duct outstanding-connection-3) + authentication-state=authentication-state-3 channel-state=channel-state-2 domains=(set turf) =http-config @@ -2794,8 +2864,8 @@ +$ server-state-1 $: bindings=(list [=binding =duct =action]) =cors-registry - connections=(map duct outstanding-connection) - =authentication-state + connections=(map duct outstanding-connection-3) + authentication-state=authentication-state-3 channel-state=channel-state-2 domains=(set turf) =http-config @@ -2808,8 +2878,8 @@ $: bindings=(list [=binding =duct =action]) cache=(map url=@t [aeon=@ud val=(unit cache-entry)]) :: <- new =cors-registry - connections=(map duct outstanding-connection) - =authentication-state + connections=(map duct outstanding-connection-3) + authentication-state=authentication-state-3 channel-state=channel-state-2 domains=(set turf) =http-config @@ -2836,6 +2906,45 @@ $>(%kick sign:agent:gall) [%fact =mark =noun] == + :: + +$ server-state-3 + $: bindings=(list [=binding =duct =action]) + cache=(map url=@t [aeon=@ud val=(unit cache-entry)]) + =cors-registry + connections=(map duct outstanding-connection-3) + authentication-state=authentication-state-3 + channel-state=channel-state-3 + domains=(set turf) + =http-config + ports=[insecure=@ud secure=(unit @ud)] + outgoing-duct=duct + verb=@ + == + +$ outstanding-connection-3 + $: =action + =inbound-request + response-header=(unit response-header:http) + bytes-sent=@ud + == + +$ authentication-state-3 sessions=(map @uv session-3) + +$ session-3 + $: expiry-time=@da + channels=(set @t) + == + +$ channel-state-3 + $: session=(map @t channel-3) + duct-to-key=(map duct @t) + == + +$ channel-3 + $: mode=?(%json %jam) + state=(each timer duct) + next-id=@ud + last-ack=@da + events=(qeu [id=@ud request-id=@ud =channel-event]) + unacked=(map @ud @ud) + subscriptions=(map @ud [ship=@p app=term =path duc=duct]) + heartbeat=(unit timer) + == -- |= old=axle-any ^+ http-server-gate @@ -2900,8 +3009,34 @@ == == == + :: + :: guarantees & stores a session for each request, and a @p identity for + :: each session and channel :: %~2023.4.11 + %= $ + date.old %~2023.5.3 + :: + connections.old + %- ~(run by connections.old) + |= outstanding-connection-3 + ^- outstanding-connection + [action inbound-request [*@uv [%ours ~]] response-header bytes-sent] + :: + sessions.authentication-state.old + %- ~(run by sessions.authentication-state.old) + |= s=session-3 + ^- session + [[%ours ~] s] + :: + session.channel-state.old + %- ~(run by session.channel-state.old) + |= c=channel-3 + ^- channel + [-.c [%ours ~] +.c] + == + :: + %~2023.5.3 http-server-gate(ax old) == :: +stay: produce current state @@ -2960,7 +3095,7 @@ ?~ cookies=(slaw %t i.t.t.tyl) [~ ~] :^ ~ ~ %noun !> ^- ? - %- =< request-is-logged-in:authentication + %- =< request-is-authenticated:authentication (per-server-event [eny *duct now rof] server-state.ax) %*(. *request:http header-list ['cookie' u.cookies]~) :: From b6e8cd616fe9b706b5050d804def242e5b078195 Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 5 May 2023 22:08:18 +0200 Subject: [PATCH 028/152] eyre: give 400 for invalid channel requests We previously had no mechanism for giving error responses, if a client submitted an invalid request into a channel. Guest access makes this important, because guests cannot interact with remote ships. Attempting to do so will cause a gall crash. Here, we add error handling logic to channel request processing. We catch the invalid cases described above and invalidate the entire batch of channel requests if they occur. We make sure to drop the moves and revert the state we changed, and give a 400 to the client that informally describes the problem(s). --- pkg/arvo/sys/vane/eyre.hoon | 52 +++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/pkg/arvo/sys/vane/eyre.hoon b/pkg/arvo/sys/vane/eyre.hoon index 1a8d826cf9..effe8774ea 100644 --- a/pkg/arvo/sys/vane/eyre.hoon +++ b/pkg/arvo/sys/vane/eyre.hoon @@ -1579,11 +1579,11 @@ :: =+ requests=p.maybe-requests :: gall-moves: put moves here first so we can flop for ordering - :: - :: TODO: Have an error state where any invalid duplicate subscriptions - :: or other errors cause the entire thing to fail with a 400 and a tang. + :: errors: if we accumulate any, discard the gall-moves and revert :: =| gall-moves=(list move) + =| errors=(map @ud @t) + =/ og-state state =/ from=ship ?- -.identity %ours our @@ -1592,17 +1592,30 @@ |- :: ?~ requests - :: this is a PUT request; we must mark it as complete + ?: =(~ errors) + :: everything succeeded, mark the request as completed + :: + =^ http-moves state + %- handle-response + :* %start + [status-code=204 headers=~] + data=~ + complete=%.y + == + :: + [:(weld (flop gall-moves) http-moves moves) state] + :: some things went wrong. revert all operations & give 400 :: + %- (trace 1 |.("{} reverting due to errors")) + =. state og-state =^ http-moves state - %- handle-response - :* %start - [status-code=204 headers=~] - data=~ - complete=%.y - == - :: - [:(weld (flop gall-moves) http-moves moves) state] + %^ return-static-data-on-duct 400 'text/html' + %- as-octs:mimes:html + %+ rap 3 + %+ turn (sort ~(tap by errors) dor) + |= [id=@ud er=@t] + (rap 3 (crip (a-co:co id)) ': ' er '
' ~) + [(weld http-moves moves) state] :: ?- -.i.requests %ack @@ -1614,6 +1627,11 @@ == :: ?(%poke %poke-json) + =, i.requests + :: + ?. |(=(from our) =(ship our)) + =+ [request-id 'non-local operation'] + $(errors (~(put by errors) -), requests t.requests) :: =. gall-moves :_ gall-moves @@ -1631,9 +1649,13 @@ $(requests t.requests) :: %subscribe - :: =, i.requests :: + ?. |(=(from our) =(ship our)) + =+ [request-id 'non-local operation'] + $(errors (~(put by errors) -), requests t.requests) + :: + ::TODO could error if the subscription is a duplicate =. gall-moves :_ gall-moves ^- move @@ -1655,6 +1677,10 @@ %unsubscribe =, i.requests :: + ?. |(=(from our) =(ship our)) + =+ [request-id 'non-local operation'] + $(errors (~(put by errors) -), requests t.requests) + :: =/ usession (~(get by session.channel-state.state) channel-id) ?~ usession $(requests t.requests) From b387235597674e68aba991fb5096abf26a275d02 Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 5 May 2023 23:30:53 +0200 Subject: [PATCH 029/152] eyre: enable host to log out any other session Now that sessions with non-local identities can exist, the host/local identity should be empowered to forcefully log off any session it hosts. Additionally, we augment the logout logic with redirect functionality: it now respects the "redirect" query parameter in the same way the login page does. Still defaults to redirecting to the login page. --- pkg/arvo/sys/vane/eyre.hoon | 47 +++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/pkg/arvo/sys/vane/eyre.hoon b/pkg/arvo/sys/vane/eyre.hoon index effe8774ea..2647ab9904 100644 --- a/pkg/arvo/sys/vane/eyre.hoon +++ b/pkg/arvo/sys/vane/eyre.hoon @@ -793,7 +793,7 @@ (handle-request:authentication secure address request) :: %logout - (handle-logout:authentication suv request) + (handle-logout:authentication [suv identity] request) :: %channel (handle-request:by-channel [suv identity] address request) @@ -1070,30 +1070,47 @@ (handle-response %start 303^['location' actual-redirect]~ ~ &) :: +handle-logout: handles an http request for logging out :: - ::TODO allow %ours sessions to kill any session on-demand ++ handle-logout - |= [session-id=@uv =request:http] + |= [[session-id=@uv =identity] =request:http] ^- [(list move) server-state] - :: whatever we end up doing, we always redirect to the login page + :: whatever we end up doing, we always respond with a redirect :: =/ response=$>(%start http-event:http) + =/ redirect=(unit @t) + %+ get-header:http 'redirect' + args:(parse-request-line url.request) :* %start - ^= response-header - :- 303 - :~ ['location' '/~/login'] - ['set-cookie' (session-cookie-string session-id |)] - == + response-header=[303 ['location' (fall redirect '/~/login')]~] data=~ complete=%.y == + :: read options from the body + :: all: log out all sessions with this identity? + :: sid: which session do we log out? (defaults to requester's) + :: + =/ arg=header-list:http + ?~ body.request ~ + (fall (rush q.u.body.request yquy:de-purl:html) ~) + =/ all=? + ?=(^ (get-header:http 'all' arg)) + =/ sid=(unit @uv) + ?. ?=(%ours -.identity) `session-id + ?~ sid=(get-header:http 'sid' arg) `session-id + :: if you provided the parameter, but it doesn't parse, we just + :: no-op. otherwise, a poorly-implemented frontend might result in + :: accidental log-outs, which would be very annoying. + :: + (slaw %uv u.sid) + ?~ sid + (handle-response response) + :: if the requester is logging themselves out, make them drop the cookie + :: + =? headers.response-header.response =(u.sid session-id) + :_ headers.response-header.response + ['set-cookie' (session-cookie-string session-id |)] :: close the session as requested, then send the response :: - =/ all=? - ?~ body.request | - =- ?=(^ -) - %+ get-header:http 'all' - (fall (rush q.u.body.request yquy:de-purl:html) ~) - =^ moz1 state (close-session session-id all) + =^ moz1 state (close-session u.sid all) =^ moz2 state (handle-response response) [[give-session-tokens (weld moz1 moz2)] state] :: +session-id-from-request: attempt to find a session cookie From d15de3b48ca67451e08c55996ad8211b3d1e8793 Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 5 May 2023 23:38:40 +0200 Subject: [PATCH 030/152] eyre: update %name, add %host endpoint %name now returns the identity of the session associated with the request. %host will always return the @p of the ship *handling* the request. The latter becomes especially important for guest sessions, who can only interact with agents on the local ship, but will still need to specify who that ship is. --- pkg/arvo/sys/lull.hoon | 3 +++ pkg/arvo/sys/vane/eyre.hoon | 42 +++++++++++++++++++++---------------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index b54fd43f7a..aef91d21fb 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -2341,6 +2341,9 @@ :: respond with the @p the requester is authenticated as :: [%name ~] + :: respond with the @p of the ship serving the response + :: + [%host ~] :: respond with the default file not found page :: [%four-oh-four ~] diff --git a/pkg/arvo/sys/vane/eyre.hoon b/pkg/arvo/sys/vane/eyre.hoon index 2647ab9904..d936778fcd 100644 --- a/pkg/arvo/sys/vane/eyre.hoon +++ b/pkg/arvo/sys/vane/eyre.hoon @@ -802,30 +802,30 @@ (handle-scry authenticated address request(url suburl)) :: %name - (handle-name authenticated request) + (handle-name identity request) + :: + %host + %^ return-static-data-on-duct 200 'text/plain' + (as-octs:mimes:html (scot %p our)) :: %four-oh-four %^ return-static-data-on-duct 404 'text/html' (error-page 404 authenticated url.request ~) == - :: +handle-name: respond with our @p or 403 + :: +handle-name: respond with the requester's @p :: ++ handle-name - |= [authenticated=? =request:http] - |^ ^- (quip move server-state) - ?. authenticated - (error-response 403 ~) + |= [=identity =request:http] + ^- (quip move server-state) ?. =(%'GET' method.request) - (error-response 405 "may only GET name") + %^ return-static-data-on-duct 405 'text/html' + (error-page 405 & url.request "may only GET name") %^ return-static-data-on-duct 200 'text/plain' - (as-octs:mimes:html (scot %p our)) - :: - ++ error-response - |= [status=@ud =tape] - ^- (quip move server-state) - %^ return-static-data-on-duct status 'text/html' - (error-page status authenticated url.request tape) - -- + =; nom=@p (as-octs:mimes:html (scot %p nom)) + ?- -.identity + %ours our + %fake who.identity + == :: +handle-cache-req: respond with cached value, 404 or 500 :: ++ handle-cache-req @@ -949,14 +949,14 @@ %- (trace 1 |.("leaving subscription to {}")) (deal-as /watch-response/[eyre-id] identity our app.action %leave ~) :: - ?(%authentication %logout %name) + ?(%authentication %logout) [~ state] :: %channel on-cancel-request:by-channel :: - ?(%scry %four-oh-four) - :: it should be impossible for a scry or 404 page to be asynchronous + ?(%scry %four-oh-four %name %host) + :: it should be impossible for these to be asynchronous :: !! == @@ -2488,6 +2488,7 @@ [[~ /~/channel] duct [%channel ~]] [[~ /~/scry] duct [%scry ~]] [[~ /~/name] duct [%name ~]] + [[~ /~/host] duct [%host ~]] == [~ http-server-gate] :: %trim: in response to memory pressure @@ -3077,6 +3078,11 @@ |= c=channel-3 ^- channel [-.c [%ours ~] +.c] + :: + bindings.old + %+ insert-binding + [[~ /~/host] outgoing-duct.old [%host ~]] + bindings.old == :: %~2023.5.3 From 744dea2267b5bd72bdd71ee2cc01ceafc11ab6be Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 5 May 2023 23:41:05 +0200 Subject: [PATCH 031/152] various: stop asserting =(src our):bowl for http It is no longer guaranteed that the src.bowl for incoming HTTP-related events is equal to our.bowl. Instead, it will reflect the identity associated with the request, our or otherwise. When serving publicly-accessible endpoints, the assertion never made much sense, but with recent changes actively prevents guests from accessing the endpoints. Here, we correct all such cases. --- pkg/arvo/app/azimuth-rpc.hoon | 2 +- pkg/arvo/app/roller-rpc.hoon | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/arvo/app/azimuth-rpc.hoon b/pkg/arvo/app/azimuth-rpc.hoon index 8329712332..9d69d49baa 100644 --- a/pkg/arvo/app/azimuth-rpc.hoon +++ b/pkg/arvo/app/azimuth-rpc.hoon @@ -45,7 +45,6 @@ |= [=mark =vase] ^- (quip card _this) |^ - ?> (team:title our.bowl src.bowl) ?+ mark (on-poke:def mark vase) %handle-http-request =+ !<([id=@ta req=inbound-request:eyre] vase) @@ -53,6 +52,7 @@ (handle-http-request id req) :: %azimuth-action + ?> (team:title our.bowl src.bowl) =+ !<([%disconnect bind=binding:eyre] vase) ~& >>> "disconnecting at {}" :_ this diff --git a/pkg/arvo/app/roller-rpc.hoon b/pkg/arvo/app/roller-rpc.hoon index 4133058c0b..3b49d0eb3c 100644 --- a/pkg/arvo/app/roller-rpc.hoon +++ b/pkg/arvo/app/roller-rpc.hoon @@ -89,7 +89,6 @@ ++ on-watch |= =path ^- (quip card _this) - ?> (team:title our.bowl src.bowl) ?+ path (on-watch:def path) [%http-response *] [~ this] == From f1c839717ecece1488aeeabb437889f52d2ace52 Mon Sep 17 00:00:00 2001 From: fang Date: Fri, 5 May 2023 23:46:30 +0200 Subject: [PATCH 032/152] dbug: handle new eyre identities, fancier logout Include and render identities associated with requests, channels, and login sessions. Provide the ability to kick identities and their sessions, logging them out. --- pkg/arvo/app/dbug.hoon | 13 ++++++++++- pkg/arvo/app/debug/js/index.js | 2 +- pkg/interface/dbug/src/js/views/eyre.js | 30 +++++++++++++++++++------ 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/pkg/arvo/app/dbug.hoon b/pkg/arvo/app/dbug.hoon index 5e8e8e2d78..02ead63dd4 100644 --- a/pkg/arvo/app/dbug.hoon +++ b/pkg/arvo/app/dbug.hoon @@ -368,7 +368,8 @@ (gth expiry-time.a expiry-time.b) |= [cookie=@uv session:eyre] %- pairs - :~ 'cookie'^s+(end [3 4] (rsh [3 2] (scot %x (shax cookie)))) + :~ 'cookie'^s+(scot %uv cookie) + 'identity'^(render-identity:v-eyre identity) 'expiry'^(time expiry-time) 'channels'^(numb ~(wyt in channels)) == @@ -383,6 +384,7 @@ |= [key=@t channel:eyre] %- pairs :~ 'session'^s+key + 'identity'^(render-identity:v-eyre identity) 'connected'^b+!-.state 'expiry'^?-(-.state %& (time date.p.state), %| ~) 'next-id'^(numb next-id) @@ -992,6 +994,15 @@ ++ channel-state (scry ^channel-state %e %channel-state ~) :: + ++ render-identity + |= =identity + ^- json + %- ship:enjs:format + ?- -.identity + %ours our.bowl + %fake who.identity + == + :: ++ render-action |= =action ^- json diff --git a/pkg/arvo/app/debug/js/index.js b/pkg/arvo/app/debug/js/index.js index 776d0a35ac..a831694dea 100644 --- a/pkg/arvo/app/debug/js/index.js +++ b/pkg/arvo/app/debug/js/index.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(require("buffer")):"function"==typeof define&&define.amd?define("index",["buffer"],t):t((e=e||self).buffer)}(this,function(e){"use strict";e=e&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e;var t="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},n=t.performance||{},r=(n.now||n.mozNow||n.msNow||n.oNow||n.webkitNow,"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{});function i(){throw new Error("Dynamic requires are not currently supported by rollup-plugin-commonjs")}function o(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function a(e,t){return e(t={exports:{}},t.exports),t.exports}var s=Object.getOwnPropertySymbols,u=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable;var c=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach(function(e){r[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,r,i=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),o=1;o1?t-1:0),r=1;r1?t-1:0),r=1;r0&&"string"==typeof n[n.length-1]&&0===n[n.length-1].indexOf("\n in"))){var r=A.ReactDebugCurrentFrame.getStackAddendum();""!==r&&(t+="%s",n=n.concat([r]))}var i=n.map(function(e){return""+e});i.unshift("Warning: "+t),Function.prototype.apply.call(console[e],console,i);try{var o=0,a="Warning: "+t.replace(/%s/g,function(){return n[o++]});throw new Error(a)}catch(e){}}e(A,{ReactDebugCurrentFrame:P,ReactComponentTreeHook:{}});var L={};function F(e,t){var n=e.constructor,r=n&&(n.displayName||n.name)||"ReactClass",i=r+"."+t;L[i]||(j("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",t,r),L[i]=!0)}var z={isMounted:function(e){return!1},enqueueForceUpdate:function(e,t,n){F(e,"forceUpdate")},enqueueReplaceState:function(e,t,n,r){F(e,"replaceState")},enqueueSetState:function(e,t,n,r){F(e,"setState")}},W={};function B(e,t,n){this.props=e,this.context=t,this.refs=W,this.updater=n||z}Object.freeze(W),B.prototype.isReactComponent={},B.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},B.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};var Y={isMounted:["isMounted","Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks."],replaceState:["replaceState","Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236)."]},H=function(e,t){Object.defineProperty(B.prototype,e,{get:function(){I("%s(...) is deprecated in plain JavaScript React classes. %s",t[0],t[1])}})};for(var V in Y)Y.hasOwnProperty(V)&&H(V,Y[V]);function $(){}function q(e,t,n){this.props=e,this.context=t,this.refs=W,this.updater=n||z}$.prototype=B.prototype;var G=q.prototype=new $;G.constructor=q,e(G,B.prototype),G.isPureReactComponent=!0;var Q,K,Z,X=Object.prototype.hasOwnProperty,J={key:!0,ref:!0,__self:!0,__source:!0};function ee(e){if(X.call(e,"ref")){var t=Object.getOwnPropertyDescriptor(e,"ref").get;if(t&&t.isReactWarning)return!1}return void 0!==e.ref}function te(e){if(X.call(e,"key")){var t=Object.getOwnPropertyDescriptor(e,"key").get;if(t&&t.isReactWarning)return!1}return void 0!==e.key}Z={};var ne=function(e,t,n,r,o,a,s){var u={$$typeof:i,type:e,key:t,ref:n,props:s,_owner:a,_store:{}};return Object.defineProperty(u._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:!1}),Object.defineProperty(u,"_self",{configurable:!1,enumerable:!1,writable:!1,value:r}),Object.defineProperty(u,"_source",{configurable:!1,enumerable:!1,writable:!1,value:o}),Object.freeze&&(Object.freeze(u.props),Object.freeze(u)),u};function re(e,t,n){var r,i={},o=null,a=null,s=null,u=null;if(null!=t)for(r in ee(t)&&(a=t.ref,function(e){if("string"==typeof e.ref&&C.current&&e.__self&&C.current.stateNode!==e.__self){var t=R(C.current.type);Z[t]||(j('Component "%s" contains the string ref "%s". Support for string refs will be removed in a future major release. This case cannot be automatically converted to an arrow function. We ask you to manually fix this case by using useRef() or createRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref',R(C.current.type),e.ref),Z[t]=!0)}}(t)),te(t)&&(o=""+t.key),s=void 0===t.__self?null:t.__self,u=void 0===t.__source?null:t.__source,t)X.call(t,r)&&!J.hasOwnProperty(r)&&(i[r]=t[r]);var l=arguments.length-2;if(1===l)i.children=n;else if(l>1){for(var c=Array(l),f=0;f.")}return t}(t);if(!xe[n]){xe[n]=!0;var r="";e&&e._owner&&e._owner!==C.current&&(r=" It was passed a child from "+R(e._owner.type)+"."),D(e),j('Each child in a list should have a unique "key" prop.%s%s See https://fb.me/react-warning-keys for more information.',n,r),D(null)}}}function Se(e,t){if("object"==typeof e)if(Array.isArray(e))for(var n=0;n",u=" Did you accidentally export a JSX literal instead of a component?"):l=typeof e,j("React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s",l,u)}var f=re.apply(this,arguments);if(null==f)return f;if(s)for(var d=2;d1){for(var h=Array(d),p=0;p is not supported and will be removed in a future major release. Did you mean to render instead?")),n.Provider},set:function(e){n.Provider=e}},_currentValue:{get:function(){return n._currentValue},set:function(e){n._currentValue=e}},_currentValue2:{get:function(){return n._currentValue2},set:function(e){n._currentValue2=e}},_threadCount:{get:function(){return n._threadCount},set:function(e){n._threadCount=e}},Consumer:{get:function(){return r||(r=!0,j("Rendering is not supported and will be removed in a future major release. Did you mean to render instead?")),n.Consumer}}}),n.Consumer=o,n._currentRenderer=null,n._currentRenderer2=null,n},t.createElement=Oe,t.createFactory=Ae,t.createRef=function(){var e={current:null};return Object.seal(e),e},t.forwardRef=function(e){return null!=e&&e.$$typeof===g?j("forwardRef requires a render function but received a `memo` component. Instead of forwardRef(memo(...)), use memo(forwardRef(...))."):"function"!=typeof e?j("forwardRef requires a render function but was given %s.",null===e?"null":typeof e):0!==e.length&&2!==e.length&&j("forwardRef render functions accept exactly two parameters: props and ref. %s",1===e.length?"Did you forget to use the ref parameter?":"Any additional parameter will be undefined."),null!=e&&(null==e.defaultProps&&null==e.propTypes||j("forwardRef render functions do not support propTypes or defaultProps. Did you accidentally pass a React component?")),{$$typeof:h,render:e}},t.isValidElement=ie,t.lazy=function(e){var t,n,r={$$typeof:v,_ctor:e,_status:-1,_result:null};return Object.defineProperties(r,{defaultProps:{configurable:!0,get:function(){return t},set:function(e){j("React.lazy(...): It is not supported to assign `defaultProps` to a lazy component import. Either specify them where the component is defined, or create a wrapping component around it."),t=e,Object.defineProperty(r,"defaultProps",{enumerable:!0})}},propTypes:{configurable:!0,get:function(){return n},set:function(e){j("React.lazy(...): It is not supported to assign `propTypes` to a lazy component import. Either specify them where the component is defined, or create a wrapping component around it."),n=e,Object.defineProperty(r,"propTypes",{enumerable:!0})}}}),r},t.memo=function(e,t){return _e(e)||j("memo: The first argument must be a component. Instead received: %s",null===e?"null":typeof e),{$$typeof:g,type:e,compare:void 0===t?null:t}},t.useCallback=function(e,t){return we().useCallback(e,t)},t.useContext=function(e,t){var n=we();if(void 0!==t&&j("useContext() second argument is reserved for future use in React. Passing it is not supported. You passed: %s.%s",t,"number"==typeof t&&Array.isArray(arguments[2])?"\n\nDid you call array.map(useContext)? Calling Hooks inside a loop is not supported. Learn more at https://fb.me/rules-of-hooks":""),void 0!==e._context){var r=e._context;r.Consumer===e?j("Calling useContext(Context.Consumer) is not supported, may cause bugs, and will be removed in a future major release. Did you mean to call useContext(Context) instead?"):r.Provider===e&&j("Calling useContext(Context.Provider) is not supported. Did you mean to call useContext(Context) instead?")}return n.useContext(e,t)},t.useDebugValue=function(e,t){return we().useDebugValue(e,t)},t.useEffect=function(e,t){return we().useEffect(e,t)},t.useImperativeHandle=function(e,t,n){return we().useImperativeHandle(e,t,n)},t.useLayoutEffect=function(e,t){return we().useLayoutEffect(e,t)},t.useMemo=function(e,t){return we().useMemo(e,t)},t.useReducer=function(e,t,n){return we().useReducer(e,t,n)},t.useRef=function(e){return we().useRef(e)},t.useState=function(e){return we().useState(e)},t.version="16.14.0"}()}),S=(E.Children,E.Component,E.Fragment,E.Profiler,E.PureComponent,E.StrictMode,E.Suspense,E.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,E.cloneElement,E.createContext,E.createElement,E.createFactory,E.createRef,E.forwardRef,E.isValidElement,E.lazy,E.memo,E.useCallback,E.useContext,E.useDebugValue,E.useEffect,E.useImperativeHandle,E.useLayoutEffect,E.useMemo,E.useReducer,E.useRef,E.useState,E.version,a(function(e){e.exports=E})),T=S.Component,C=S.createRef,N=S.createElement,M=S.useState,R=S.useRef,P=S.useEffect,O=S.Fragment,D=a(function(e,t){var n,r,i,o,a;if("undefined"==typeof window||"function"!=typeof MessageChannel){var s=null,u=null,l=function(){if(null!==s)try{var e=t.unstable_now();s(!0,e),s=null}catch(e){throw setTimeout(l,0),e}},c=Date.now();t.unstable_now=function(){return Date.now()-c},n=function(e){null!==s?setTimeout(n,0,e):(s=e,setTimeout(l,0))},r=function(e,t){u=setTimeout(e,t)},i=function(){clearTimeout(u)},o=function(){return!1},a=t.unstable_forceFrameRate=function(){}}else{var f=window.performance,d=window.Date,h=window.setTimeout,p=window.clearTimeout;if("undefined"!=typeof console){var m=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof m&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof f&&"function"==typeof f.now)t.unstable_now=function(){return f.now()};else{var g=d.now();t.unstable_now=function(){return d.now()-g}}var v=!1,y=null,b=-1,_=5,w=0;o=function(){return t.unstable_now()>=w},a=function(){},t.unstable_forceFrameRate=function(e){0>e||125>>1,i=e[r];if(!(void 0!==i&&0C(a,n))void 0!==u&&0>C(u,a)?(e[r]=u,e[s]=n,r=s):(e[r]=a,e[o]=n,r=o);else{if(!(void 0!==u&&0>C(u,n)))break e;e[r]=u,e[s]=n,r=s}}}return t}return null}function C(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var N=[],M=[],R=1,P=null,O=3,D=!1,A=!1,I=!1;function j(e){for(var t=S(M);null!==t;){if(null===t.callback)T(M);else{if(!(t.startTime<=e))break;T(M),t.sortIndex=t.expirationTime,E(N,t)}t=S(M)}}function U(e){if(I=!1,j(e),!A)if(null!==S(N))A=!0,n(L);else{var t=S(M);null!==t&&r(U,t.startTime-e)}}function L(e,n){A=!1,I&&(I=!1,i()),D=!0;var a=O;try{for(j(n),P=S(N);null!==P&&(!(P.expirationTime>n)||e&&!o());){var s=P.callback;if(null!==s){P.callback=null,O=P.priorityLevel;var u=s(P.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?P.callback=u:P===S(N)&&T(N),j(n)}else T(N);P=S(N)}if(null!==P)var l=!0;else{var c=S(M);null!==c&&r(U,c.startTime-n),l=!1}return l}finally{P=null,O=a,D=!1}}function F(e){switch(e){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var z=a;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){A||D||(A=!0,n(L))},t.unstable_getCurrentPriorityLevel=function(){return O},t.unstable_getFirstCallbackNode=function(){return S(N)},t.unstable_next=function(e){switch(O){case 1:case 2:case 3:var t=3;break;default:t=O}var n=O;O=t;try{return e()}finally{O=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=z,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=O;O=e;try{return t()}finally{O=n}},t.unstable_scheduleCallback=function(e,o,a){var s=t.unstable_now();if("object"==typeof a&&null!==a){var u=a.delay;u="number"==typeof u&&0s?(e.sortIndex=u,E(M,e),null===S(N)&&e===S(M)&&(I?i():I=!0,r(U,u-s))):(e.sortIndex=a,E(N,e),A||D||(A=!0,n(L))),e},t.unstable_shouldYield=function(){var e=t.unstable_now();j(e);var n=S(N);return n!==P&&null!==P&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime=x},o=function(){},t.unstable_forceFrameRate=function(e){e<0||e>125?console.error("forceFrameRate takes a positive int between 0 and 125, forcing framerates higher than 125 fps is not unsupported"):k=e>0?Math.floor(1e3/e):5};var E=new MessageChannel,S=E.port2;E.port1.onmessage=function(){if(null!==_){var e=t.unstable_now();x=e+k;try{_(!0,e)?S.postMessage(null):(b=!1,_=null)}catch(e){throw S.postMessage(null),e}}else b=!1},e=function(e){_=e,b||(b=!0,S.postMessage(null))},n=function(e,n){w=p(function(){e(t.unstable_now())},n)},r=function(){m(w),w=-1}}function T(e,t){var n=e.length;e.push(t),function(e,t,n){var r=n;for(;;){var i=r-1>>>1,o=e[i];if(!(void 0!==o&&M(o,t)>0))return;e[i]=t,e[r]=o,r=i}}(e,t,n)}function C(e){var t=e[0];return void 0===t?null:t}function N(e){var t=e[0];if(void 0!==t){var n=e.pop();return n!==t&&(e[0]=n,function(e,t,n){var r=n,i=e.length;for(;r$){if(($*=2)>V)return console.error("Scheduler Profiling: Event log exceeded maximum size. Don't forget to call `stopLoggingProfilingEvents()`."),void oe();var n=new Int32Array(4*$);n.set(G),q=n.buffer,G=n}G.set(e,t)}}function oe(){var e=q;return $=0,q=null,G=null,Q=0,e}function ae(e,t){F[Y]++,null!==G&&ie([K,1e3*t,e.id,e.priorityLevel])}function se(e,t){F[z]=R,F[W]=0,F[Y]--,null!==G&&ie([Z,1e3*t,e.id])}function ue(e,t){F[z]=R,F[W]=0,F[B]=0,null!==G&&ie([te,1e3*t,e.id,j])}var le=-1,ce=250,fe=5e3,de=1e4,he=1073741823,pe=[],me=[],ge=1,ve=null,ye=D,be=!1,_e=!1,we=!1;function ke(e){for(var t=C(me);null!==t;){if(null===t.callback)N(me);else{if(!(t.startTime<=e))return;N(me),t.sortIndex=t.expirationTime,T(pe,t),ae(t,e),t.isQueued=!0}t=C(me)}}function xe(t){if(we=!1,ke(t),!_e)if(null!==C(pe))_e=!0,e(Ee);else{var r=C(me);null!==r&&n(xe,r.startTime-t)}}function Ee(e,n){var i;i=n,null!==G&&ie([re,1e3*i,U]),_e=!1,we&&(we=!1,r()),be=!0;var o=ye;try{if(!s)return Se(e,n);try{return Se(e,n)}catch(e){if(null!==ve){var a=t.unstable_now();!function(e,t){F[z]=R,F[W]=0,F[Y]--,null!==G&&ie([X,1e3*t,e.id])}(ve,a),ve.isQueued=!1}throw e}}finally{ve=null,ye=o,be=!1,function(e){U++,null!==G&&ie([ne,1e3*e,U])}(t.unstable_now())}}function Se(e,r){var o,s,u=r;for(ke(u),ve=C(pe);null!==ve&&!a&&(!(ve.expirationTime>u)||e&&!i());){var l=ve.callback;if(null!==l){ve.callback=null,ye=ve.priorityLevel;var c=ve.expirationTime<=u;o=ve,s=u,j++,F[z]=o.priorityLevel,F[W]=o.id,F[B]=j,null!==G&&ie([ee,1e3*s,o.id,j]);var f=l(c);u=t.unstable_now(),"function"==typeof f?(ve.callback=f,ue(ve,u)):(se(ve,u),ve.isQueued=!1,ve===C(pe)&&N(pe)),ke(u)}else N(pe);ve=C(pe)}if(null!==ve)return!0;var d=C(me);return null!==d&&n(xe,d.startTime-u),!1}function Te(e){switch(e){case P:return le;case O:return ce;case I:return he;case A:return de;case D:default:return fe}}var Ce=o,Ne={startLoggingProfilingEvents:function(){$=H,q=new ArrayBuffer(4*$),G=new Int32Array(q),Q=0},stopLoggingProfilingEvents:oe,sharedProfilingBuffer:L};t.unstable_IdlePriority=I,t.unstable_ImmediatePriority=P,t.unstable_LowPriority=A,t.unstable_NormalPriority=D,t.unstable_Profiling=Ne,t.unstable_UserBlockingPriority=O,t.unstable_cancelCallback=function(e){e.isQueued&&(function(e,t){F[Y]--,null!==G&&ie([J,1e3*t,e.id])}(e,t.unstable_now()),e.isQueued=!1),e.callback=null},t.unstable_continueExecution=function(){_e||be||(_e=!0,e(Ee))},t.unstable_getCurrentPriorityLevel=function(){return ye},t.unstable_getFirstCallbackNode=function(){return C(pe)},t.unstable_next=function(e){var t;switch(ye){case P:case O:case D:t=D;break;default:t=ye}var n=ye;ye=t;try{return e()}finally{ye=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=Ce,t.unstable_runWithPriority=function(e,t){switch(e){case P:case O:case D:case A:case I:break;default:e=D}var n=ye;ye=e;try{return t()}finally{ye=n}},t.unstable_scheduleCallback=function(i,o,a){var s,u,l=t.unstable_now();if("object"==typeof a&&null!==a){var c=a.delay;s="number"==typeof c&&c>0?l+c:l,u="number"==typeof a.timeout?a.timeout:Te(i)}else u=Te(i),s=l;var f=s+u,d={id:ge++,callback:o,priorityLevel:i,startTime:s,expirationTime:f,sortIndex:-1,isQueued:!1};return s>l?(d.sortIndex=s,T(me,d),null===C(pe)&&d===C(me)&&(we?r():we=!0,n(xe,s-l))):(d.sortIndex=f,T(pe,d),ae(d,l),d.isQueued=!0,_e||be||(_e=!0,e(Ee))),d},t.unstable_shouldYield=function(){var e=t.unstable_now();ke(e);var n=C(pe);return n!==ve&&null!==ve&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime