diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b15a2fa96..4653cc1a4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -34,7 +34,7 @@ jobs: call-vere: uses: ./.github/workflows/vere.yml with: - pace: 'often' + pace: 'edge' # XX s/b once? upload: >- ${{ (github.ref_name == 'next/vere' && github.ref_type == 'branch') diff --git a/.github/workflows/vere.yml b/.github/workflows/vere.yml index 254ba5da9..eb94e8ea9 100644 --- a/.github/workflows/vere.yml +++ b/.github/workflows/vere.yml @@ -12,11 +12,13 @@ on: pace: description: 'release pace' type: string - default: 'often' + default: 'edge' required: false secrets: CACHIX_AUTH_TOKEN: required: false + GCP_CREDENTIALS: + required: false GCS_SERVICE_ACCOUNT_KEY: required: false GCS_PROJECT: @@ -33,7 +35,7 @@ on: description: 'release pace' type: choice options: - - often + - edge - soon - live @@ -48,8 +50,9 @@ jobs: fail-fast: false matrix: include: - - { os: ubuntu-latest } - - { os: macos-latest } + - { os: ubuntu-latest, type: linux } + - { os: macos-latest, type: macos } + - { os: buildjet-4vcpu-ubuntu-2204-arm, type: linux } runs-on: ${{ matrix.os }} @@ -64,7 +67,7 @@ jobs: with: extra_nix_config: | system-features = nixos-test benchmark big-parallel kvm - if: ${{ matrix.os == 'ubuntu-latest' }} + if: ${{ matrix.type == 'linux' }} - uses: cachix/install-nix-action@v16 if: ${{ matrix.os != 'ubuntu-latest' }} @@ -73,6 +76,11 @@ jobs: name: ares authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + # run unit tests early on linux (x-compilation will skip them) + - name: build dynamic binary (and run tests) + if: ${{ matrix.type == 'linux' }} + run: nix-build -A urbit + - name: build static binary run: | nix-build -A urbit \ @@ -84,7 +92,7 @@ jobs: cat ./urbit-derivation - name: confirm binary is mostly static - if: matrix.os == 'macos-latest' + if: matrix.type == 'macos' run: | bin="${{ env.urbit_static }}/bin/urbit" @@ -117,19 +125,20 @@ jobs: echo -n "$version" > ./version-string - name: upload version string artifact - if: matrix.os == 'ubuntu-latest' + if: matrix.type == 'linux' uses: actions/upload-artifact@v3 with: name: version-string path: version-string - - uses: google-github-actions/setup-gcloud@v0.2.0 + - uses: google-github-actions/auth@v1 + with: + credentials_json: ${{ secrets.GCP_CREDENTIALS }} + + - uses: google-github-actions/setup-gcloud@v1 if: inputs.upload with: - version: '290.0.1' - service_account_key: ${{ secrets.GCS_SERVICE_ACCOUNT_KEY }} project_id: ${{ secrets.GCS_PROJECT }} - export_default_credentials: true - name: upload binary to bootstrap.urbit.org if: inputs.upload @@ -174,6 +183,7 @@ jobs: CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} - run: mingw32-make build/urbit + - run: mingw32-make test - run: > build/urbit -l -d -B ../../bin/solid.pill -F bus && curl -f --data '{"source":{"dojo":"+hood/exit"},"sink":{"app":"hood"}}' diff --git a/bin/multi-brass.pill b/bin/multi-brass.pill index debb8ecc8..d95c40bd6 100644 --- a/bin/multi-brass.pill +++ b/bin/multi-brass.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2f46209c31bc7be965b6ba32db92fb0746be15d9613b1c3c8d09ce7fa0e5e157 -size 8280141 +oid sha256:ea8626444e4f0213e39c21ded20607145ee85a947afc592f182f46e7f598ef30 +size 7748671 diff --git a/bin/solid.pill b/bin/solid.pill index 9a13d4769..c8d27030b 100644 --- a/bin/solid.pill +++ b/bin/solid.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b604b45df0496baf94ac38145c3fc8d4fa9429ae02b49b33a7af4e32ad770db4 -size 5896517 +oid sha256:40bc203b8a2d2ebad81723da6fc946ee32d2f8a204884f50f9710177ae257d08 +size 5712264 diff --git a/default.nix b/default.nix index 3161c5363..cde49c475 100644 --- a/default.nix +++ b/default.nix @@ -57,7 +57,10 @@ let if system == "x86_64-linux" && crossSystem == null && enableStatic then "x86_64-unknown-linux-musl" else - crossSystem; + if system == "aarch64-linux" && crossSystem == null && enableStatic then + "aarch64-unknown-linux-musl" + else + crossSystem; }; # Use nixpkgs' top-level/static overlay if enableStatic = true. diff --git a/nix/default.nix b/nix/default.nix index 7819ffbb3..627b3eba7 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -25,6 +25,7 @@ let (import ./overlays/native.nix) # Specific overrides guarded by the host platform. (import ./overlays/musl.nix) + (import ./overlays/arm.nix) ]; }; diff --git a/nix/overlays/arm.nix b/nix/overlays/arm.nix index 62bb1eb0d..be0112296 100644 --- a/nix/overlays/arm.nix +++ b/nix/overlays/arm.nix @@ -3,10 +3,11 @@ final: prev: let isAarch64 = prev.stdenv.hostPlatform.isAarch64; + isDarwin = prev.stdenv.isDarwin; -in prev.lib.optionalAttrs isAarch64 { +in prev.lib.optionalAttrs (isAarch64 && !isDarwin) { libsigsegv = prev.libsigsegv.overrideAttrs (attrs: { - preConfigure = (old.preConfigure or "") + '' + preConfigure = (prev.preConfigure or "") + '' sed -i 's/^CFG_FAULT=$/CFG_FAULT=fault-linux-arm.h/' configure ''; }); diff --git a/pkg/arvo/app/aqua.hoon b/pkg/arvo/app/aqua.hoon index 574f4cd3f..a41f45ba3 100644 --- a/pkg/arvo/app/aqua.hoon +++ b/pkg/arvo/app/aqua.hoon @@ -7,6 +7,7 @@ :: OR :: :aqua &pill +solid :: +:: XX: update these examples :: Then try stuff: :: :aqua [%init ~[~bud ~dev]] :: :aqua [%dojo ~[~bud ~dev] "[our eny (add 3 5)]"] @@ -480,14 +481,15 @@ =^ ms state (poke-pill pil) (emit-cards ms) :: - [%swap-files ~] + [%swap-files @tas] + =/ =desk +.val =. userspace-ova.pil - =/ slim-dirs=(list path) - ~[/app /ted /gen /lib /mar /sur /hoon/sys /arvo/sys /zuse/sys] + :: take all files from a userspace desk + =/ all-dirs=(list path) ~[/] :_ ~ %- unix-event:pill-lib - %- %*(. file-ovum:pill-lib directories slim-dirs) - /(scot %p our.hid)/work/(scot %da now.hid) + %+ %*(. file-ovum:pill-lib directories all-dirs) + desk /(scot %p our.hid)/[desk]/(scot %da now.hid) =^ ms state (poke-pill pil) (emit-cards ms) :: diff --git a/pkg/arvo/app/azimuth.hoon b/pkg/arvo/app/azimuth.hoon index 9b445efb1..54a97be23 100644 --- a/pkg/arvo/app/azimuth.hoon +++ b/pkg/arvo/app/azimuth.hoon @@ -281,7 +281,7 @@ :: restart %eth-watcher :: ~& >> %starting-eth-watcher - =/ rein=[desk rein] [%base %.y [%eth-watcher ~ ~] ~] + =/ rein=[desk rein] [%base [%eth-watcher %&] ~ ~] :_ cards [%pass /rein %agent [our.bowl %hood] %poke kiln-rein+!>(rein)] =. cards diff --git a/pkg/arvo/app/dojo.hoon b/pkg/arvo/app/dojo.hoon index ccae3667b..b24c681da 100644 --- a/pkg/arvo/app/dojo.hoon +++ b/pkg/arvo/app/dojo.hoon @@ -174,8 +174,10 @@ :: ;~ pfix fas ;~ pose - (parse-variable (cold %sur hep) ;~(pfix gap parse-cables)) - (parse-variable (cold %lib lus) ;~(pfix gap parse-cables)) + (parse-variable (cold %sur hep) ;~(pfix gap (parse-cables %sur))) + (parse-variable (cold %lib lus) ;~(pfix gap (parse-cables %lib))) + ;~(pfix tis gap (parse-variable sym ;~(pfix gap parse-path))) + ;~(pfix cen gap (parse-variable sym ;~(pfix gap parse-mark))) == == :: @@ -194,22 +196,17 @@ == :: ++ parse-cables - %+ cook - |= cables=(list cable:clay) - :+ 0 %ex - ^- hoon - :: - :- %clsg - %+ turn cables - |= cable=cable:clay - ^- hoon - :: - :+ %clhp - ?~ face.cable - [%rock %n ~] - [%clhp [%rock %n ~] [%sand %tas u.face.cable]] - [%sand %tas file-path.cable] - (most ;~(plug com gaw) parse-cable) + |= base-path=@ta + %- cook :_ (most ;~(plug com gaw) parse-cable) + |= cables=(list cable:clay) + :+ 0 %tu + :: + %+ turn cables + |= cable=cable:clay + ^- dojo-source + =+ add-face=?~(face.cable "|*(n=* n)" ;:(weld "|*(n=* ^=(" (trip u.face.cable) " n))")) + :^ 0 %do (scan add-face parse-hoon) + :+ 0 %dv [-.dir `path`[base-path file-path.cable ~]] :: ++ parse-cable %+ cook |=(a=cable:clay a) @@ -218,6 +215,16 @@ (cook |=([face=term tis=@ file=term] [`face file]) ;~(plug sym tis sym)) (cook |=(a=term [`a a]) sym) == + :: + ++ parse-mark + %- cook :_ ;~(pfix cen sym) + |= mark=@tas + [0 %dv -.dir `path`[~.mar mark ~]] + :: + ++ parse-path + %+ cook |=(=path [0 %dv -.dir path]) + ;~(pfix fas (more fas sym)) + :: ++ parse-source (stag 0 parse-build) ++ parse-build %+ knee *dojo-build |. ~+ @@ -537,8 +544,6 @@ =. var (~(del by var) p.mad) =< dy-amok ?+ p.mad . - %lib .(lib ~) - %sur .(sur ~) %dir .(dir [[our.hid %base ud+0] /]) == =+ cay=(~(got by rez) p.q.mad) @@ -550,29 +555,19 @@ ~| bad-set+[p.p.mad p.q.cay] =< dy-amok ?+ p.p.mad . - %lib - %_ . - lib - ((dy-cast (list cable:clay) !>(*(list cable:clay))) q.cay) - == - :: - %sur - %_ . - sur - ((dy-cast (list cable:clay) !>(*(list cable:clay))) q.cay) - == - :: - %dir =+ ^= pax ^- path - =+ pax=((dy-cast path !>(*path)) q.cay) - ?: ?=(~ pax) ~[(scot %p our.hid) %base '0'] - ?: ?=([@ ~] pax) ~[i.pax %base '0'] - ?: ?=([@ @ ~] pax) ~[i.pax i.t.pax '0'] - pax - ?: =(~ .^((list path) %ct pax)) - +(..dy (he-diff %tan 'dojo: dir does not exist' ~)) - =. dir (need (de-beam pax)) - =- +>(..dy (he-diff %tan - ~)) - rose+[" " `~]^~[leaf+"=%" (smyt (en-beam he-beak s.dir))] + %dir + =/ bem=beam + %- need %- de-beam + =+ pax=((dy-cast path !>(*path)) q.cay) + ?: ?=(~ pax) ~[(scot %p our.hid) %base '0'] + ?: ?=([@ ~] pax) ~[i.pax %base '0'] + ?: ?=([@ @ ~] pax) ~[i.pax i.t.pax '0'] + pax + ?: =(~ .^((list path) %ct (en-beam he-beam(dir bem)))) + +(..dy (he-diff %tan 'dojo: dir does not exist' ~)) + =. dir bem + =- +>(..dy (he-diff %tan - ~)) + rose+[" " `~]^~[leaf+"=%" (smyt (en-beam he-beak s.dir))] == :: %poke diff --git a/pkg/arvo/app/hood.hoon b/pkg/arvo/app/hood.hoon index d916c1b55..4866ce439 100644 --- a/pkg/arvo/app/hood.hoon +++ b/pkg/arvo/app/hood.hoon @@ -2,8 +2,8 @@ /+ drum=hood-drum, helm=hood-helm, kiln=hood-kiln |% +$ state - $~ [%23 *state:drum *state:helm *state:kiln] - $>(%23 any-state) + $~ [%24 *state:drum *state:helm *state:kiln] + $>(%24 any-state) :: +$ any-state $% [ver=?(%1 %2 %3 %4 %5 %6) lac=(map @tas fin-any-state)] @@ -24,6 +24,7 @@ [%21 drum=state-4:drum helm=state-1:helm kiln=state-8:kiln] [%22 drum=state-4:drum helm=state-1:helm kiln=state-9:kiln] [%23 drum=state-4:drum helm=state-2:helm kiln=state-9:kiln] + [%24 drum=state-4:drum helm=state-2:helm kiln=state-10:kiln] == +$ any-state-tuple $: drum=any-state:drum diff --git a/pkg/arvo/app/spider.hoon b/pkg/arvo/app/spider.hoon index bb1adf7ae..8569e35c9 100644 --- a/pkg/arvo/app/spider.hoon +++ b/pkg/arvo/app/spider.hoon @@ -166,10 +166,10 @@ (on-load on-save) =^ cards state ?+ mark (on-poke:def mark vase) - %spider-input (on-poke-input:sc !<(input vase)) - %spider-start (handle-start-thread:sc !<(start-args:spider vase)) - %spider-stop (handle-stop-thread:sc !<([tid ?] vase)) - :: + %spider-input (on-poke-input:sc !<(input vase)) + %spider-start (handle-start-thread:sc !<(start-args:spider vase)) + %spider-inline (handle-inline-thread:sc !<(inline-args:spider vase)) + %spider-stop (handle-stop-thread:sc !<([tid ?] vase)) %handle-http-request (handle-http-request:sc !<([@ta =inbound-request:eyre] vase)) == @@ -303,12 +303,31 @@ ++ handle-start-thread ~/ %handle-start-thread |= [parent-tid=(unit tid) use=(unit tid) =beak file=term =vase] + (prep-thread parent-tid use beak %| file vase) +:: +++ handle-inline-thread + ~/ %handle-inline-thread + |= [parent-tid=(unit tid) use=(unit tid) =beak =shed:khan] + (prep-thread parent-tid use beak %& shed) +:: +++ prep-thread + |= $: parent-tid=(unit tid) use=(unit tid) =beak + source=(each shed:khan [file=term =vase]) + == ^- (quip card ^state) =/ parent-yarn=yarn ?~ parent-tid / (~(got by tid.state) u.parent-tid) - =/ new-tid (fall use (new-thread-id file)) + =/ new-tid + ?^ use + u.use + %- new-thread-id + ?- -.source + %& (cat 3 'inline-' q.beak) + %| file.p.source + == + :: =/ =yarn (snoc parent-yarn new-tid) :: ?: (~(has of running.state) yarn) @@ -321,16 +340,19 @@ =? serving.state !(~(has by serving.state) new-tid) (~(put by serving.state) new-tid [~ %noun q.beak]) :: - =: starting.state (~(put by starting.state) yarn [%build vase]) - tid.state (~(put by tid.state) new-tid yarn) + =. tid.state (~(put by tid.state) new-tid yarn) + ?- -.source + %& (begin-shed yarn p.source) + %| + =. starting.state (~(put by starting.state) yarn [%build vase.p.source]) + =/ pax=path + ~| no-file-for-thread+file.p.source + (need (get-fit:clay beak %ted file.p.source)) + :_ state + :_ ~ + :+ %pass /build/[new-tid] + [%arvo %c %warp p.beak q.beak ~ %sing %a r.beak pax] == - =/ pax=path - ~| no-file-for-thread+file - (need (get-fit:clay beak %ted file)) - :_ state - :_ ~ - :+ %pass /build/[new-tid] - [%arvo %c %warp p.beak q.beak ~ %sing %a r.beak pax] :: ++ handle-build ~/ %handle-build @@ -349,23 +371,25 @@ =/ maybe-thread (mule |.(!<(thread !<(vase q.r.u.riot)))) ?: ?=(%| -.maybe-thread) (thread-fail-not-running tid %thread-not-thread ~) - (start-thread yarn p.maybe-thread) + (slam-thread yarn p.maybe-thread) :: -++ start-thread - ~/ %start-thread +++ slam-thread + ~/ %slam-thread |= [=yarn =thread] ^- (quip card ^state) =/ =vase vase:(~(got by starting.state) yarn) - ?< (~(has of running.state) yarn) - =/ m (strand ,^vase) =/ res (mule |.((thread vase))) ?: ?=(%| -.res) (thread-fail-not-running (yarn-to-tid yarn) %false-start p.res) - =/ =eval-form:eval:m - (from-form:eval:m p.res) - =: starting.state (~(del by starting.state) yarn) - running.state (~(put of running.state) yarn eval-form) - == + =. starting.state (~(del by starting.state) yarn) + (begin-shed yarn p.res) +:: +++ begin-shed + |= [=yarn =shed:khan] + ?< (~(has of running.state) yarn) + =/ m (strand ,vase) + =/ =eval-form:eval:m (from-form:eval:m shed) + =. running.state (~(put of running.state) yarn eval-form) (take-input yarn ~) :: ++ handle-stop-thread diff --git a/pkg/arvo/gen/hood/breload.hoon b/pkg/arvo/gen/hood/breload.hoon deleted file mode 100644 index 5b9df1d72..000000000 --- a/pkg/arvo/gen/hood/breload.hoon +++ /dev/null @@ -1,14 +0,0 @@ -:: Helm: Reload vane/s from /=base= -:: -:::: /hoon/breload/hood/gen - :: -/? 310 -:: -:::: - :: -:- %say -|= $: [now=@da eny=@uvJ bec=beak] - [arg=(list term) ~] - == -:+ %helm-reload-desk %base -arg diff --git a/pkg/arvo/gen/hood/bump.hoon b/pkg/arvo/gen/hood/bump.hoon index 4811c2f35..cc443c25f 100644 --- a/pkg/arvo/gen/hood/bump.hoon +++ b/pkg/arvo/gen/hood/bump.hoon @@ -1,7 +1,3 @@ :- %say -|= $: [now=@da eny=@uvJ bec=beak] - ~ - force=_| - except=(set desk) - == -[%kiln-bump except force] +|= [[now=@da eny=@uvJ bec=beak] ~ ~] +[%kiln-bump ~] diff --git a/pkg/arvo/gen/hood/new-desk.hoon b/pkg/arvo/gen/hood/new-desk.hoon new file mode 100644 index 000000000..54995a597 --- /dev/null +++ b/pkg/arvo/gen/hood/new-desk.hoon @@ -0,0 +1,50 @@ +:: |new-desk: creates a minimal desk +:: +/+ *generators +:: +:- %ask +|= $: [now=@da eny=@uvJ bek=beak] + [=desk ~] + [from=$~(%base desk) hard=_|] + == +:: +=; make-new-desk + ?. ?& !hard + (~(has in .^((set ^desk) %cd (en-beam bek(q %$) /))) desk) + == + (make-new-desk) + %+ print (rap 3 'the desk %' desk ' already exists. overwrite it?' ~) + %+ prompt [%& %prompt "overwrite? (y/N) "] + |= in=tape + ?. |(=("y" in) =("Y" in) =("yes" in)) + no-product + (make-new-desk) +:: +|. %- produce +:- %helm-pass +%^ new-desk:cloy desk + ~ +%- ~(gas by *(map path page:clay)) +|^ =- (turn - mage) + ^- (list path) + :~ /mar/noun/hoon + /mar/hoon/hoon + /mar/txt/hoon + /mar/kelvin/hoon + /sys/kelvin + == +:: +++ mage + |= =path + :- path + ^- page:clay + :- (rear path) + ~| [%missing-source-file from path] + .^ * + %cx + (scot %p p.bek) + from + (scot %da now) + path + == +-- diff --git a/pkg/arvo/gen/hood/rein.hoon b/pkg/arvo/gen/hood/rein.hoon index ab65645b5..db7d32261 100644 --- a/pkg/arvo/gen/hood/rein.hoon +++ b/pkg/arvo/gen/hood/rein.hoon @@ -8,11 +8,7 @@ == :- %kiln-rein :- desk +=+ .^(=cone:clay %cx /(scot %p p.bec)//(scot %da now)/domes) %+ roll arg -=/ =rein:hood - =< rein.arak - .^(vat:hood %gx /(scot %p p.bec)/hood/(scot %da now)/kiln/vat/[desk]/noun) -|: [*[on=? =dude:gall] rein=rein(liv liv)] -?: on - rein(add (~(put in add.rein) dude)) -rein(sub (~(put in sub.rein) dude)) +|: [*[on=? =dude:gall] rein=ren:(~(got by cone) [p.bec desk])] +(~(put by rein) dude on) diff --git a/pkg/arvo/gen/hood/start.hoon b/pkg/arvo/gen/hood/start.hoon index a44b38b3d..50ef24778 100644 --- a/pkg/arvo/gen/hood/start.hoon +++ b/pkg/arvo/gen/hood/start.hoon @@ -15,4 +15,7 @@ ?@ +.arg [q.bec -.arg] ?> ((sane %tas) +<.arg) [-.arg +<.arg] -[%kiln-rein des & [dap ~ ~] ~] +=+ .^(=cone:clay %cx /(scot %p p.bec)//(scot %da now)/domes) +=/ =foam:clay (~(gut by cone) [p.bec des] *foam:clay) +=+ ((slog ?:(=(%live liv.foam) ~ ['kiln: desk not live' ~])) ~) +[%kiln-rein des (~(put by ren.foam) dap &)] diff --git a/pkg/arvo/gen/hood/tomb.hoon b/pkg/arvo/gen/hood/tomb.hoon index 6d20b5459..6fbb10f61 100644 --- a/pkg/arvo/gen/hood/tomb.hoon +++ b/pkg/arvo/gen/hood/tomb.hoon @@ -13,8 +13,7 @@ =/ =lobe u.fil.arch =+ .^(=rang %cx /(scot %p p.bec)//(scot %da now)/rang) =+ .^(=cone %cx /(scot %p p.bec)//(scot %da now)/domes) -=/ domes=(list [[=ship =desk] =dome tom=(map tako norm) nor=norm]) - ~(tap by cone) +=/ domes=(list [[=ship =desk] foam]) ~(tap by cone) =/ norms |^ |- ^- (set [ship desk tako norm path]) @@ -24,14 +23,14 @@ =/ =aeon 1 %- ~(uni in $(domes t.domes)) |- ^- (set [ship desk tako norm path]) - ?: (lth let.dome.i.domes aeon) + ?: (lth let.i.domes aeon) ~ - =/ =tako (~(got by hit.dome.i.domes) aeon) + =/ =tako (~(got by hit.i.domes) aeon) =/ paths (draw-tako ship.i.domes desk.i.domes +.i.domes tako) (~(uni in paths) $(aeon +(aeon))) :: ++ draw-tako - |= [=ship =desk [dome tom=(map tako norm) nor=norm] =tako] + |= [=ship =desk foam =tako] ^- (set [^ship ^desk ^tako norm path]) ~+ =/ =yaki (~(got by hut.rang) tako) diff --git a/pkg/arvo/gen/hood/track.hoon b/pkg/arvo/gen/hood/track.hoon deleted file mode 100644 index 49c77771f..000000000 --- a/pkg/arvo/gen/hood/track.hoon +++ /dev/null @@ -1,14 +0,0 @@ -:: Kiln: merge each version of remote desk? XX clarify -:: -:::: /hoon/track/hood/gen - :: -/? 310 -:: -:::: - :: -:- %say -|= $: [now=@da eny=@uvJ bec=beak] - [arg=[syd=@tas her=@p sud=@tas ~] ~] - == -:- %kiln-track -[syd her sud]:arg diff --git a/pkg/arvo/gen/norms.hoon b/pkg/arvo/gen/norms.hoon index 81cc3594f..835407b4e 100644 --- a/pkg/arvo/gen/norms.hoon +++ b/pkg/arvo/gen/norms.hoon @@ -8,7 +8,7 @@ %- flop ^- tang %- zing %+ turn ~(tap by cone) -|= [[=ship =desk] dome tom=(map tako norm) nor=norm] +|= [[=ship =desk] foam] :- leaf+"{}/{}:" %+ turn ~(tap of nor) |= [=path keep=?] diff --git a/pkg/arvo/gen/solid.hoon b/pkg/arvo/gen/solid.hoon index d131a7338..cfd54601e 100644 --- a/pkg/arvo/gen/solid.hoon +++ b/pkg/arvo/gen/solid.hoon @@ -77,10 +77,8 @@ ~& %solid-double-loaded =/ whole-formula =< + - .* 0 - :+ %7 - compiler-formula - [%9 2 %10 [6 %1 %noun whole-src] [%0 1]] + .* [%noun whole-src] + [%8 compiler-formula [%9 2 %10 [6 %0 3] [%0 2]]] ~& %solid-double-compiled whole-formula :: @@ -100,24 +98,19 @@ |= [ovo=ovum ken=*] [~ (slum ken [now ovo])] :: -:: kernel-formula +:: boot-two: startup formula :: :: We evaluate :arvo-formula (for jet registration), :: then ignore the result and produce .installed :: -=/ kernel-formula - [%7 arvo-formula %1 installed] -:: -:: boot-two: startup formula -:: =/ boot-two - => [kernel-formula=** main-sequence=**] - != [.*(0 kernel-formula) main-sequence] + => *[arvo-formula=^ installed=^ tale=*] + != =+(.*(0 arvo-formula) [installed tale]) :: :: boot-ova :: =/ boot-ova=(list) - [aeon:eden:part boot-two kernel-formula ~] + [aeon:eden:part boot-two arvo-formula installed ~] :: :: a pill is a 3-tuple of event-lists: [boot kernel userspace] :: diff --git a/pkg/arvo/gen/story-list.hoon b/pkg/arvo/gen/story-list.hoon index bc46a4438..0990ba451 100644 --- a/pkg/arvo/gen/story-list.hoon +++ b/pkg/arvo/gen/story-list.hoon @@ -3,6 +3,8 @@ :::: :: /- *story +/$ story-to-txt %story %txt +:: :- %say |= $: [now=@da eny=@uvJ bec=beak] [[~] =desk ~] @@ -15,9 +17,6 @@ tang+[leaf+"Error: desk {} does not exist." ~] ?: !.^(? %cu pax) tang+['Error: No story file found. Please use |story-init to create one.' ~] -=/ story-to-txt - .^($-(story wain) %cf /(scot %p our)/[desk]/(scot cas)/story/txt) -:: =/ tale .^(story %cx pax) -=/ tale-text (story-to-txt tale) -tang+tale-text \ No newline at end of file +=/ tale-text (flop (story-to-txt tale)) +tang+tale-text diff --git a/pkg/arvo/gen/story-read.hoon b/pkg/arvo/gen/story-read.hoon index dd6e21c1f..73403543d 100644 --- a/pkg/arvo/gen/story-read.hoon +++ b/pkg/arvo/gen/story-read.hoon @@ -48,7 +48,7 @@ ?- reverse-ancestors ~ :: stop here and return the current message - =/ msg=(list cord) (msg-from-commit this-commit tale) + =/ msg=wain (msg-from-commit this-commit tale) [(weld msg result.state) mergebase=~] :: [tako:clay ~] @@ -103,8 +103,7 @@ =/ mainline-commit .^(yaki:clay %cs /(scot %p our)/[syd]/(scot cas)/yaki/(scot %uv mainline)) :: - =/ msg=(list cord) - (msg-from-commit this-commit tale) + =/ msg=wain (msg-from-commit this-commit tale) :: :: 1 - process current commit :: 2 - recur and queue processing on all commits on the sideline @@ -141,14 +140,9 @@ :: ++ msg-from-commit |= [commit=yaki:clay tale=story] - ^- (list cord) - =/ proses (~(get by tale) r.commit) + ^- wain + =/ proses (~(get ju tale) r.commit) ?~ proses ~ %- flop :: fixes formatting reversal in dojo - %- to-wain:format - %- crip - ;: welp - (tako-to-text:lib r.commit) - (proses-to-text:lib u.proses) - == + (chapter-to-text:lib r.commit proses) -- diff --git a/pkg/arvo/gen/vat.hoon b/pkg/arvo/gen/vat.hoon index 703ade563..6534d5e24 100644 --- a/pkg/arvo/gen/vat.hoon +++ b/pkg/arvo/gen/vat.hoon @@ -3,8 +3,4 @@ |= $: [now=@da eny=@uvJ bec=beak] [[=desk ~] ~] == -?: =(desk %kids) [%tang ~[(report-kids p.bec now)]] -=+ .^ =vat %gx - /(scot %p p.bec)/hood/(scot %da now)/kiln/vat/[desk]/noun - == -[%tang ~[(report-vat p.bec now vat)]] +[%tang ~[(report-vat (report-prep p.bec now) p.bec now desk)]] diff --git a/pkg/arvo/lib/hood/kiln.hoon b/pkg/arvo/lib/hood/kiln.hoon index c8edd21d7..d8fac70f7 100644 --- a/pkg/arvo/lib/hood/kiln.hoon +++ b/pkg/arvo/lib/hood/kiln.hoon @@ -1,23 +1,26 @@ /- *hood +/+ strandio =, clay =, space:userlib =, format =* dude dude:gall |% -+$ state state-9 -+$ state-9 [%9 pith-9] -+$ state-8 [%8 pith-9] -+$ state-7 [%7 pith-7] -+$ state-6 [%6 pith-6] -+$ state-5 [%5 pith-5] -+$ state-4 [%4 pith-4] -+$ state-3 [%3 pith-3] -+$ state-2 [%2 pith-2] -+$ state-1 [%1 pith-1] -+$ state-0 [%0 pith-0] ++$ state state-10 ++$ state-10 [%10 pith-10] ++$ state-9 [%9 pith-9] ++$ state-8 [%8 pith-9] ++$ state-7 [%7 pith-7] ++$ state-6 [%6 pith-6] ++$ state-5 [%5 pith-5] ++$ state-4 [%4 pith-4] ++$ state-3 [%3 pith-3] ++$ state-2 [%2 pith-2] ++$ state-1 [%1 pith-1] ++$ state-0 [%0 pith-0] +$ any-state $~ *state - $% state-9 + $% state-10 + state-9 state-8 state-7 state-6 @@ -29,12 +32,11 @@ state-0 == :: -+$ pith-9 - $: wef=(unit weft) - rem=(map desk per-desk) :: - syn=(map kiln-sync let=@ud) :: - ark=(map desk arak) :: - commit-timer=[way=wire nex=@da tim=@dr mon=term] :: ++$ pith-10 + $: rem=(map desk per-desk) + nyz=@ud + zyn=(map kiln-sync sync-state) + commit-timer=[way=wire nex=@da tim=@dr mon=term] :: map desk to the currently ongoing fuse request :: and the latest version numbers for beaks to fus=(map desk per-fuse) @@ -45,12 +47,12 @@ hxs=(map desk @ud) == :: -+$ pith-7 ++$ pith-9 $: wef=(unit weft) - rem=(map desk per-desk) :: - syn=(map kiln-sync let=@ud) :: - ark=(map desk arak-7) :: - commit-timer=[way=wire nex=@da tim=@dr mon=term] :: + rem=(map desk per-desk) + syn=(map kiln-sync let=@ud) + ark=(map desk arak-9) + commit-timer=[way=wire nex=@da tim=@dr mon=term] :: map desk to the currently ongoing fuse request :: and the latest version numbers for beaks to fus=(map desk per-fuse) @@ -59,10 +61,53 @@ :: ensure they're unique even when the same :: request is made multiple times. hxs=(map desk @ud) - == :: + == +:: +:: $rein-9: diff from desk manifest +:: +:: .liv: suspended? if suspended, no agents should run +:: .add: agents not in manifest that should be running +:: .sub: agents in manifest that should not be running +:: ++$ rein-9 + $: liv=_& + add=(set dude) + sub=(set dude) + == +:: ++$ pith-7 + $: wef=(unit weft) + rem=(map desk per-desk) + syn=(map kiln-sync let=@ud) + ark=(map desk arak-7) + commit-timer=[way=wire nex=@da tim=@dr mon=term] + :: map desk to the currently ongoing fuse request + :: and the latest version numbers for beaks to + fus=(map desk per-fuse) + :: used for fuses - every time we get a fuse we + :: bump this. used when calculating hashes to + :: ensure they're unique even when the same + :: request is made multiple times. + hxs=(map desk @ud) + == +:: ++$ arak-9 + $: rail=(unit rail-9) + rein=rein-9 + == +:: +++ rail-9 + $: publisher=(unit ship) + paused=? + =ship + =desk + =aeon + next=(list rung) + == +:: +$ arak-7 $: rail=(unit rail-7) - =rein + rein=rein-9 == :: +$ rail-7 @@ -89,7 +134,7 @@ hxs=(map desk @ud) == :: :: -+$ arak-6 [rail=rail-6 next=(list rung) =rein] ++$ arak-6 [rail=rail-6 next=(list rung) rein=rein-9] +$ rail-6 [paused=? =ship =desk =aeon] :: +$ pith-5 @@ -126,7 +171,7 @@ =desk =aeon next=(list rung) - =rein + rein=rein-9 == +$ pith-3 :: $: rem=(map desk per-desk) :: @@ -262,9 +307,20 @@ [%0 %leaf (weld "kiln: " mes)] :: ++ render - |= [mez=tape sud=desk who=ship syd=desk] + |= [mez=tape sud=desk who=ship syd=desk kid=(unit desk)] :^ %palm [" " ~ ~ ~] leaf+(weld "kiln: " mez) - ~[leaf+"from {}" leaf+"on {}" leaf+"to {}"] + :^ leaf+"from {}" leaf+"on {}" leaf+"to {}" + ?~ kid ~ + [leaf+"then {}" ~] +:: +++ sources + =/ zyns=(list [[syd=desk her=ship sud=desk] *]) ~(tap by zyn) + =| sources=(map desk [ship desk]) + |- ^+ sources + ?~ zyns + sources + =. sources (~(put by sources) -.i.zyns) + $(zyns t.zyns) :: ++ on-init =< abet @@ -277,26 +333,22 @@ =/ sop=ship (sein:title our now our) :: set up base desk :: - =. ..on-init abet:(install-local:vats %base) =? ..on-init ?=(?(%earl %duke %king) (clan:title our)) - abet:(install:vats %base sop %kids) - :: - :: watch for gall reloading - =. ..on-init abet:gall-lyv:vats + abet:init:(apex:(sync %base sop %kids) `%kids) :: install other desks and make them public :: =/ dez=(list desk) ~(tap in desks) |- ^+ ..on-init ?~ dez ..on-init =. ..on-init - abet:(install-local:vats i.dez) + (emit %pass /kiln/init-zest %arvo %c %zest i.dez %live) =. ..on-init %- emit :^ %pass /kiln/permission %arvo [%c %perm i.dez / %r `[%black ~]] =/ src (get-publisher our i.dez now) =? ..on-init &(?=(^ src) !=(our u.src)) - abet:(install:vats i.dez u.src i.dez) + abet:init:(sync i.dez u.src i.dez) $(dez t.dez) :: ++ on-load @@ -373,10 +425,10 @@ =? old ?=(%7 -.old) :- %8 =- +.old(ark -) - %- ~(gas by *(map desk arak)) + %- ~(gas by *(map desk arak-9)) %+ turn ~(tap by ark.old) |= [d=desk a=arak-7] - ^- [desk arak] + ^- [desk arak-9] :- d :_ rein.a ?~ rail.a ~ @@ -385,665 +437,86 @@ =? old ?=(%8 -.old) [%9 +.old] :: - ?> ?=(%9 -.old) + =^ cards-9=(list card:agent:gall) old + ?. ?=(%9 -.old) + `old + =/ syn=(set kiln-sync) + %- ~(gas in ~(key by syn.old)) + %+ murn ~(tap by ark.old) + |= [=desk =arak-9] + ?~ rail.arak-9 + ~ + ?: paused.u.rail.arak-9 + ~ + `u=[desk ship.u.rail.arak-9 desk.u.rail.arak-9] + =/ zet=(list [desk zest]) + %+ murn ~(tap by ark.old) + |= [=desk =arak-9] + ^- (unit [^desk zest]) + ?: liv.rein.arak-9 + `[desk %held] + ?~ rail.arak-9 + ~ + ?: paused.u.rail.arak-9 + ~ + `[desk %held] + :: + :_ [%10 |1.+.old(syn 0, ark ~)] + ;: weld + %+ turn zet + |= [=desk =zest] + [%pass /kiln/load-zest %arvo %c %zest desk zest] + :: + %+ turn ~(tap in syn) + |= k=kiln-sync + [%pass /kiln/load-sync %agent [our %hood] %poke %kiln-sync !>(k)] + :: + =/ ks ~(tap in syn) + |- ^- (list card:agent:gall) + ?~ ks + ~ + ?: =(%base syd.i.ks) + :_ ~ + :* %pass /kiln/load-kids %agent [our %hood] + %poke %kiln-kids !>([i.ks `%kids]) + == + $(ks t.ks) + == + :: + ?> ?=(%10 -.old) =. state old - :: - =? kiln (lth old-version %7) - abet:(install:vats %base our %base) - =? kiln ?=(^ old-ota) - abet:(install:vats %base [her sud]:u.old-ota) - =? kiln (lth old-version %7) - abet:gall-lyv:vats - :: kiln %7 had a bug where it failed to properly emit a +listen - :: due to an unexpected crash. here we detect the cause of the crash - :: (not-yet-installed desks) and emit the +listen anew to make sure we - :: stay aware of commits to base. - :: - =? kiln - ?& =(%8 old-version) - :: - %+ lien ~(tap by ark.old) - |= [d=desk *] - =- =(0 rev) - .^([rev=@ud @da] %cw /(scot %p our)/[d]/(scot %da now)) - == - take-commit:(abed:vats %base) - =. wef ~ - abet:kiln + abet:(emil cards-9) :: ++ on-peek |= =path ^- (unit (unit cage)) ?+ path [~ ~] - [%x %kiln %lag ~] ``loob+!>(.^(? //(scot %p our)//(scot %da now)/zen/lag)) + [%x %kiln %our ~] ``noun+!>(our) + [%x %kiln %lag ~] + ``loob+!>(.^(? //(scot %p our)//(scot %da now)/zen/lag)) :: - [%x %kiln %vat @ ~] - =* loc i.t.t.t.path - =/ ego (scot %p our) - =/ wen (scot %da now) - =/ rak=(unit arak) (~(get by ark) loc) - ?~ rak [~ ~] - =/ hog .^(@uv cz+~[ego loc wen]) - =/ cas .^(cass cw+~[ego loc wen]) - :^ ~ ~ %noun - !> ^- vat - [loc hog cas u.rak] - :: - [%x %kiln %vats ~] - :^ ~ ~ %kiln-vats - !> ^- (list vat) - =/ ego (scot %p our) - =/ wen (scot %da now) - %+ turn ~(tap by ark) - |= [loc=desk rak=arak] - =/ hog .^(@uv cz+~[ego loc wen]) - =/ cas .^(cass cw+~[ego loc wen]) - [loc hog cas rak] - :: - [%x %kiln %ark ~] ``noun+!>(ark) - [%x %kiln %our ~] ``noun+!>(our) [%x %kiln %base-hash ~] - =/ ver (mergebase-hashes our %base now (~(got by ark) %base)) + =/ ver (mergebase-hashes our %base now (~(got by sources) %base)) ``noun+!>(?~(ver 0v0 i.ver)) + :: + [%x %kiln %syncs ~] ``noun+!>(zyn) + [%x %kiln %sources ~] ``noun+!>(sources) + [%x %kiln %pikes ~] + =+ .^(=rock:tire %cx /(scot %p our)//(scot %da now)/tire) + :^ ~ ~ %kiln-pikes + !> ^- pikes + %- ~(rut by rock) + |= [=desk =zest wic=(set weft)] + ^- pike + =+ .^(hash=@uv %cz /(scot %p our)/[desk]/(scot %da now)) + =/ sync (~(get by sources) desk) + [sync hash zest wic] == :: -++ vats - |_ [loc=desk rak=arak] - ++ ral (need rail.rak) - ++ vats . - ++ abet - ~| [%uninitialized-desk loc] - ?< =(%$ loc) - kiln(ark (~(put by ark) loc rak)) - ++ abed - |= lac=desk - ~_ leaf/"kiln: {} not installed" - vats(loc lac, rak (~(got by ark) lac)) - :: - ++ here ?~ rail.rak "{} (local)" - "{} from {<[ship desk]:ral>}" - ++ make-wire |=(step=@tas /kiln/vats/[loc]/[step]) - ++ from-wire - |= =wire - ~| wire - ?> ?=([@ @ *] wire) - (abed i.wire) - :: - ++ emit |=(card:agent:gall vats(kiln (^emit +<))) - ++ emil |=((list card:agent:gall) vats(kiln (^emil +<))) - ++ give - |% - ++ snap [%give %fact ~[/kiln/vats] %kiln-vats-snap-0 !>(ark)] - ++ diff |=(d=^diff [%give %fact ~[/kiln/vats] %kiln-vats-diff-0 !>(d)]) - -- - ++ pass - |% - ++ pyre |=(=tang [%pass /kiln/vats %pyre tang]) - ++ find (warp %find [%sing %y ud+1 /]) - ++ sync-da (warp %sync [%sing %w da+now /]) - ++ sync-ud (warp %sync [%sing %w ud+aeon:ral /]) - ++ download (warp %download [%sing %v ud+aeon:ral /]) - ++ gall-lyv - =/ paths=(set [care:clay path]) - %- sy - :~ [%z /sys/hoon/hoon] - [%z /sys/arvo/hoon] - [%z /sys/lull/hoon] - [%z /sys/zuse/hoon] - [%z /sys/vane/gall/hoon] - == - %+ clay-card %gall-lyv - [%warp our %base ~ %mult da+now paths] - :: - ++ warp - |= [s=term r=rave] - (clay-card s %warp ship:ral desk:ral `r) - ++ merge-main - =/ germ (get-germ loc) - =/ =aeon (dec aeon:ral) - %+ clay-card %merge-main - [%merg loc ship:ral desk:ral ud+aeon germ] - ++ merge-kids - =/ germ (get-germ %kids) - =/ =aeon (dec aeon:ral) - %+ clay-card %merge-kids - [%merg %kids ship:ral desk:ral ud+aeon germ] - ++ listen - (clay-card %listen %warp our loc `[%next %z da+now /]) - ++ clay-card - |= [step=@tas =task:clay] - ^- card:agent:gall - [%pass (make-wire step) %arvo %c task] - ++ start-dude - |= =dude - ^- card:agent:gall - [%pass /kiln/vats/[loc]/jolt/[dude] %arvo %g %jolt loc dude] - ++ stop-dude - |= =dude - ^- card:agent:gall - [%pass /kiln/vats/[loc]/uninstall %arvo %g %idle dude] - -- - :: +uninstall: stop tracking apps on desk, and suspend apps - :: - ++ uninstall - |= lac=desk - ^+ kiln - ?: =(%base lac) - =- (^emit (pyre:pass leaf/- ~)) - "kiln: |uninstall: %base cannot be uninstalled" - ?. (~(has by ark) lac) - ~> %slog.(fmt "|uninstall: {} not installed, ignoring") - kiln - =. vats (abed lac) - ~> %slog.(fmt "uninstalling {here}") - =. vats stop-agents - kiln(ark (~(del by ark) lac)) - :: +install: set up desk sync to .lac to install all apps from [her rem] - :: - ++ install - |= [lac=desk her=ship rem=desk] - ^+ vats - =. loc lac - ?: =([her rem] [our lac]) - (install-local lac) - =/ got (~(get by ark) lac) - ?: =(`[her rem] got) - =. rak (need got) - ~> %slog.(fmt "already tracking {here:(abed lac)}, ignoring") - vats - =. rak [`[~ paused=| her rem *aeon next=~] rein:(fall got *arak)] - ~> %slog.(fmt "beginning install into {here}") - (emil find:pass listen:pass ~) - :: +install-local: install from a local desk, with no remote - :: - :: Also notify clients that the desk was installed. - :: - ++ install-local - |= lac=desk - ^+ vats - |^ ^+ vats - ?. (~(has by ark) lac) - go - =. vats (abed lac) - ?^ rail.rak - go - ~> %slog.(fmt "{} already installed locally, refreshing") - update-running-dudes - :: - ++ go - =. loc lac - =. rak *arak - ~> %slog.(fmt "installing {} locally") - =. vats update-running-dudes - (emil listen:pass (diff:give %commit lac rak) ~) - -- - :: +reset: resync after failure - :: - :: TODO: instead of jumping all the way back to find:pass, - :: which will end up skipping all the way until the latest - :: remote commit, increment the aeon so we skip only the problematic - :: commit and try the commit immediately after it. - :: - ++ reset - ^+ vats - ~> %slog.(fmt "resetting tracking for {here}") - =/ cad (diff:give %reset loc rak) - =/ rel ral - =. rail.rak `rel(aeon 0, next ~) - (emil find:pass cad ~) - :: +pause: stop syncing from upstream - :: - ++ pause - |= lac=desk - ^+ vats - =. vats (abed lac) - ?. is-tracking - ~> %slog.(fmt "{} already paused, ignoring") - vats - ~> %slog.(fmt "{} pausing updates") - =/ rel ral - =. rail.rak `rel(paused &, aeon 0, next ~) - vats - :: - :: +gall-lyv: watch gall source for reloading - ++ gall-lyv - =. vats (abed %base) - (emit gall-lyv:pass) - :: +remove-upstream: stop listening to an upstream for changes - :: - ++ remove-upstream - |= lac=desk - ^+ vats - =. vats (abed lac) - =. rail.rak ~ - vats - :: +resume: restart tracking from upstream - :: - :: TODO: check whether kelvin is legit - :: - ++ resume - |= lac=desk - ^+ vats - =. vats (abed lac) - ~> %slog. %- fmt - ?. paused:ral - "{} already tracking, ignoring" - "{} resuming updates" - =/ rel ral - =. rail.rak `rel(paused |) - reset - :: +suspend: shut down all agents, keep syncing - :: - ++ suspend - |= lac=desk - ^+ vats - =/ got (~(get by ark) lac) - ?: =(%base lac) - =- (emit (pyre:pass leaf/- ~)) - "kiln: suspend: %base cannot be suspended" - ?. (~(has by ark) lac) - ~> %slog.(fmt "suspend: {} not installed, ignoring") - vats - =. vats (abed lac) - =. liv.rein.rak | - =. vats stop-agents - (emit (diff:give %suspend loc rak)) - :: +revive: restart agents on a suspended desk - :: - ++ revive - |= lac=desk - ^+ vats - =. vats (abed lac) - =. liv.rein.rak & - =. vats update-running-dudes - (emit (diff:give %revive loc rak)) - :: +set-rein: adjust which agents are forced on or off - :: - ++ set-rein - |= [lac=desk new=rein] - ^+ vats - =. vats (abed lac) - =^ old rein.rak [rein.rak new] - ?+ [liv.old liv.new] !! - [%| %|] vats - [%| %&] (revive lac) - [%& %|] (suspend lac) - [%& %&] update-running-dudes - == - :: +bump: try to apply kernel kelvin upgrade - :: - :: Apply merges to revive faded agents on all desks. - :: If .force, suspends stale agents. Else, any stale desk - :: will cause a crash. - :: - ++ bump - |= [kel=weft except=(set desk) force=?] - ^+ kiln - =/ ded (find-blocked kel except) - =? kiln force (suspend-many ded) - ?: |(force =(~ ded)) - ?: !=(zuse+zuse kel) - (bump-one kel %base) - (bump-many (all-desks-but (~(uni in except) ded))) - =- (^emit (pyre:pass leaf/- ~)) - "kiln: desks blocked upgrade to {}: {}" - :: - ++ all-desks-but |=(not=(set desk) (~(dif in ~(key by ark)) not)) - :: - ++ find-blocked - |= [kel=weft except=(set desk)] - ^- (set desk) - (~(dif in (get-blockers kel)) (~(put in except) %base)) - :: - ++ suspend-many - |= dead=(set desk) - ^+ kiln - =/ ded ~(tap in dead) - |- ^+ kiln - ?~ ded kiln - $(ded t.ded, kiln abet:(suspend i.ded)) - :: - ++ bump-many - |= live=(set desk) - ^+ kiln - :: ensure %base is always reloaded first - :: - =/ liv - %+ sort ~(tap in live) - |= [a=desk b=desk] - ^- ? - ?: =(%base a) & - ?: =(%base b) | - (lte `@`a `@`b) - :: - |- ^+ kiln - ?~ liv kiln - $(liv t.liv, kiln (bump-one zuse+zuse i.liv)) - :: - ++ bump-one - |= [kel=weft =desk] - ^+ kiln - ~> %slog.(fmt "bump {} to {<[lal num]:kel>}") - =< abet ^+ vats - =. vats (abed desk) - =/ kul (read-kelvin-local our desk now) - ?~ kul - ~> %slog.(fmt "{here} not yet installed") - vats - ?: =(kel u.kul) - ~> %slog.(fmt "{here} already at {<[lal num]:kel>}") - update-running-dudes - =^ tem rail.rak (crank-next kel) - ?^ tem - (emit merge-main:pass) - =- (emit (pyre:pass leaf/- ~)) - "kiln: {here} killed upgrade to {<[lal num]:kel>}" - :: +stop-agents: internal helper to suspend agents on .loc - :: - :: Will not shut down %hood or %dojo. - :: - ++ stop-agents - ^+ vats - =/ ded (get-apps-live our loc now) - =. ded (skip ded |=(d=dude ?=(?(%hood %dojo) d))) - (stop-dudes ded) - :: - ++ take - |= [=wire syn=sign-arvo] - ^+ kiln - ?> ?=([@ @ *] wire) - ?: ?=(%jolt i.t.wire) - (take-onto wire syn) - ?: ?=(%listen i.t.wire) - (take-listen wire syn) - =< abet - =. vats (from-wire wire) - ?+ i.t.wire - ~> %slog.(fmt "vats-bad-take {}") - vats - %find (take-find syn) - %sync (take-sync syn) - %download (take-download syn) - %merge-main (take-merge-main syn) - %merge-kids (take-merge-kids syn) - %gall-lyv (take-gall-lyv syn) - == - :: - ++ take-find - |= syn=sign-arvo - ^+ vats - ?> ?=(%writ +<.syn) - ?. is-tracking - vats - ?~ p.syn - ~> %slog.(fmt "cancelled (1) install into {here}, aborting") - vats(ark (~(del by ark) loc)) - ~> %slog.(fmt "activated install into {here}") - (emit sync-da:pass) - :: - ++ take-sync - |= syn=sign-arvo - ^+ vats - ?> ?=(%writ +<.syn) - =* rit u.p.syn - ?. is-tracking - vats - ?~ p.syn - ~> %slog.(fmt "cancelled (1) install into {here}, retrying") - reset - =? rail.rak ?=(%w p.p.rit) `%*(. ral aeon ud:;;(cass:clay q.q.r.rit)) - ~> %slog.(fmt "downloading update for {here}") - (emit download:pass) - :: - ++ take-download - |= syn=sign-arvo - ^+ vats - ?> ?=(%writ +<.syn) - ?. is-tracking - vats - ?~ p.syn - ~> %slog.(fmt "cancelled (2) install into {here}, retrying") - reset - ~> %slog.(fmt "finished downloading update for {here}") - ?. (get-remote-diff our loc now [ship desk aeon]:ral) - ~> %slog.(fmt "remote is identical to {here}, skipping") - =. rail.rak `%*(. ral aeon +(aeon:ral)) - =. vats update-running-dudes - (emil sync-ud:pass (diff:give %commit loc rak) ~) - =/ old-weft `weft`[%zuse zuse] - =/ new-weft - ?: =(our ship:ral) - (need (read-kelvin-local our desk:ral now)) :: TODO error handling - (read-kelvin-foreign [ship desk aeon]:ral) - :: don't try to read from the local desk's bill file if - :: there are no commits to the local desk (aeon 0) - :: - =/ yon =<(ud .^(cass cw+/(scot %p our)/[loc]/(scot %da now))) - =? vats &(liv.rein.rak !=(0 yon)) - %- stop-dudes - =< idle - (adjust-dudes [our loc now] rein.rak) - =. rail.rak `%*(. ral aeon +(aeon:ral)) - |^ ^+ vats - ?: =(%base loc) - do-base - ?: (gth num.new-weft num.old-weft) - kelvin-retreat - ?: =(num.new-weft num.old-weft) - kelvin-same - kelvin-advance - :: - ++ kelvin-retreat - ^+ vats - ~> %slog.(fmt "cannot install {here}, old kelvin {}") - ~> %slog.(fmt "will retry at foreign kelvin {}") - =/ =diff [%block loc rak new-weft blockers=(sy %base ~)] - (emil sync-ud:pass (diff:give diff) ~) - :: - ++ kelvin-advance - ^+ vats - ~> %slog.(fmt "future version {}, enqueueing") - :: retry upgrade if not blocked anymore - =. rail.rak `%*(. ral next (snoc next:ral [(dec aeon:ral) new-weft])) - =. ark (~(put by ark) loc rak) - =/ =diff [%block loc rak new-weft blockers=(sy %base ~)] - =. vats (emil sync-ud:pass (diff:give diff) ~) - =/ base=arak (~(got by ark) %base) - ?~ rail.base - vats - =/ rel u.rail.base - ?. &(?=(^ next.rel) =(~ (get-blockers weft.i.next.rel))) - vats - ~> %slog.(fmt "unblocked system update, updating") - =. kiln (bump-one weft.i.next.rel %base) - vats - :: - ++ kelvin-same - ^+ vats - ~> %slog.(fmt "merging into {here}") - ?> ?=(^ rail.rak) - =. next.u.rail.rak ~ - (emil ~[merge-main sync-ud]:pass) - :: - ++ do-base - ^+ vats - =/ blockers - ?: =(new-weft old-weft) - ~ - (get-blockers new-weft) - :: - ?. =(~ blockers) - ~> %slog.(fmt "OTA blocked on {}") - =. rail.rak - `%*(. ral next (snoc next:ral [(dec aeon:ral) new-weft])) - =/ =diff [%block loc rak new-weft blockers] - (emil sync-ud:pass (diff:give diff) ~) - ~> %slog.(fmt "applying OTA to {here}, kelvin: {}") - ?> ?=(^ rail.rak) - =. next.u.rail.rak ~ - =. wef - ?: =(old-weft new-weft) ~ - `new-weft - (emil ~[merge-main sync-ud]:pass) - -- - :: - ++ take-listen - |= [=wire syn=sign-arvo] - ^+ kiln - ?> ?=([@ %writ ~ *] syn) - =/ lac=desk (head wire) - :: ignore spurious updates from clay on desks we've uninstalled - :: - ?. (~(has by ark) lac) - kiln - =. vats (from-wire wire) - take-commit - :: - ++ take-commit - ^+ kiln - =. kiln - =< abet - ~> %slog.(fmt "commit detected at {here}") - =. rail.rak - ?~ rail.rak ~ - `[(get-publisher our loc now) +.u.rail.rak] - =. vats (emil listen:pass (diff:give %commit loc rak) ~) - ?. liv.rein.rak - ~> %slog.(fmt "{} not running") - vats - update-running-dudes - ?. =(%base loc) - kiln - (bump-many (all-desks-but (get-unblockers ark))) - :: - ++ take-merge-main - |= syn=sign-arvo - ^+ vats - ?> ?=(%mere +<.syn) - ?: ?=([%| %ali-unavailable *] p.syn) - =+ "kiln: merge into {here} failed, maybe because sunk; restarting" - %- (slog leaf/- p.p.syn) - =. vats (emit (diff:give %merge-sunk loc rak p.p.syn)) - reset - ?: ?=(%| -.p.syn) - =+ "kiln: merge into {here} failed, waiting for next revision" - %- (slog leaf/- p.p.syn) - =. vats (emit (diff:give %merge-fail loc rak p.p.syn)) - vats - ~> %slog.(fmt "merge into {} succeeded") - ?. =(%base loc) - vats - ~> %slog.(fmt "merging %base into %kids") - (emit merge-kids:pass) - :: - ++ take-merge-kids - |= syn=sign-arvo - ^+ vats - ?> ?=(%mere +<.syn) - ?: ?=([%| %ali-unavailable *] p.syn) - ~> %slog.(fmt "OTA to %kids failed, maybe peer sunk; restarting") - =. vats (emit (diff:give %merge-sunk %kids rak p.p.syn)) - reset - ?- -.p.syn - %& ~> %slog.(fmt "OTA to %kids succeeded") - (emit (diff:give %commit %kids rak)) - %| ~> %slog.(fmt "OTA to %kids failed {}") - (emit (diff:give %merge-fail %kids rak p.p.syn)) - == - :: - ++ take-gall-lyv - |= syn=sign-arvo - ^+ vats - =. vats gall-lyv - =/ vets ~(tap in ~(key by ark)) - |- - ?~ vets vats - =. vats (abed i.vets) - =. vats update-running-dudes - $(vets t.vets) - :: - ++ take-onto - |= [=wire syn=sign-arvo] - ^+ kiln - =/ onto ?>(?=([%gall %onto *] syn) p.syn) - ?- -.onto - %& kiln - %| (mean p.onto) - == - :: - ++ update-running-dudes - ^+ vats - =/ local [our loc now] - =/ dif (adjust-dudes local rein.rak) - =. vats (start-dudes jolt.dif) - =. vats (stop-dudes idle.dif) - vats - :: - ++ start-dudes - |= daz=(list dude) - (emil (turn daz start-dude:pass)) - :: - ++ stop-dudes - |= daz=(list dude) - (emil (turn daz stop-dude:pass)) - :: +crank-next: pop stale items from .next until one matches - :: - ++ crank-next - |= new=weft - ^+ [match=*(unit rung) rail.rak] - ?~ rail.rak - ~| [%no-rail-for desk=loc] - !! - =/ rog next.u.rail.rak - =- [match `u.rail.rak(next next)] - |- ^- [match=(unit rung) next=(list rung)] - ?~ rog [~ next.u.rail.rak] - ?: =(new weft.i.rog) - [`i.rog t.rog] - $(rog t.rog) - :: - ++ is-tracking - ^- ? - ?~ rail.rak | - !paused.u.rail.rak - -- -:: +get-blockers: find desks that would block a kernel update -:: -++ get-blockers - |= kel=weft - ^- (set desk) - %- ~(gas in *(set desk)) - %+ murn ~(tap by ark) - |= [=desk =arak] - ?: =(%base desk) - ~ - ?. liv.rein.arak - ~ - ?: =(`kel (read-kelvin-local our desk now)) - ~ - ?~ rail.arak - `desk - ?: (lien next.u.rail.arak |=([* k=weft] =(k kel))) - ~ - `desk -:: +get-unblockers: find desks which shouldn't block a kernel upgrade -:: -++ get-unblockers - |= ark=(map desk arak) - =/ base=(set desk) (sy %base %kids ~) - %- ~(gas in base) - %+ murn ~(tap by ark) - |= [loc=desk ark=arak] - ^- (unit desk) - ?. liv.rein.ark `loc - ?~ rail.ark `loc - ?: paused.u.rail.ark `loc - ~ :: +get-germ: select merge strategy into local desk :: -:: If destination desk doesn't exist, need a %init merge. If this is -:: its first revision, it probably doesn't have a mergebase yet, so -:: use %take-that. +:: If destination desk doesn't exist, need a %init merge. Otherwise, +:: we just want what the remote has, so we use %only-that. :: ++ get-germ |= =desk @@ -1066,13 +539,13 @@ %kiln-gall-sear =;(f (f !<(_+<.f vase)) poke-gall-sear) %kiln-info =;(f (f !<(_+<.f vase)) poke-info) %kiln-install =;(f (f !<(_+<.f vase)) poke-install) + %kiln-kids =;(f (f !<(_+<.f vase)) poke-kids) %kiln-label =;(f (f !<(_+<.f vase)) poke-label) %kiln-merge =;(f (f !<(_+<.f vase)) poke-merge) %kiln-mount =;(f (f !<(_+<.f vase)) poke-mount) %kiln-nuke =;(f (f !<(_+<.f vase)) poke-nuke) %kiln-pause =;(f (f !<(_+<.f vase)) poke-pause) %kiln-permission =;(f (f !<(_+<.f vase)) poke-permission) - %kiln-resume =;(f (f !<(_+<.f vase)) poke-resume) %kiln-revive =;(f (f !<(_+<.f vase)) poke-revive) %kiln-rein =;(f (f !<(_+<.f vase)) poke-rein) %kiln-rm =;(f (f !<(_+<.f vase)) poke-rm) @@ -1080,7 +553,6 @@ %kiln-suspend =;(f (f !<(_+<.f vase)) poke-suspend) %kiln-sync =;(f (f !<(_+<.f vase)) poke-sync) %kiln-syncs =;(f (f !<(_+<.f vase)) poke-syncs) - %kiln-track =;(f (f !<(_+<.f vase)) poke-track) %kiln-uninstall =;(f (f !<(_+<.f vase)) poke-uninstall) %kiln-unmount =;(f (f !<(_+<.f vase)) poke-unmount) %kiln-unsync =;(f (f !<(_+<.f vase)) poke-unsync) @@ -1098,14 +570,28 @@ (emit %pass way.commit-timer %arvo %b [%wait nex.commit-timer]) :: ++ poke-bump - |= [except=(set desk) force=?] - =/ =arak - (~(got by ark) %base) - =/ kel=weft - ?~ rail.arak zuse+zuse - ?~ next.u.rail.arak zuse+zuse - weft.i.next.u.rail.arak - abet:(bump:vats kel except force) + |= ~ + =< abet + =+ .^(=rock:tire %cx /(scot %p our)//(scot %da now)/tire) + =/ wic + %+ sort ~(tap by wic:(~(got by rock) %base)) + |= [[* a=@ud] [* b=@ud]] + (gth a b) + =. wic (skip wic |=([* a=@ud] (gte a zuse))) + ?~ wic + %- (slog 'kiln: %base already up-to-date' ~) + ..abet + =/ kel i.wic + %- emil + =/ cards + %+ murn ~(tap by rock) + |= [=desk =zest wic=(set weft)] + ?: |(=(%base desk) !?=(%live zest) (~(has in wic) kel)) + ~ + `u=[%pass /kiln/bump/[desk] %arvo %c %zest desk %held] + ?~ cards + [%pass /kiln/bump/wick %arvo %c %wick ~]~ + cards :: ++ poke-cancel |= a=@tas @@ -1202,7 +688,31 @@ :: ++ poke-install |= [loc=desk her=ship rem=desk] - abet:abet:(install:vats +<) + =+ .^(=rock:tire %cx /(scot %p our)//(scot %da now)/tire) + =/ =zest + ?~ got=(~(get by rock) loc) + %dead + zest.u.got + =. zyn + ?~ got=(~(get by sources) loc) + zyn + (~(del by zyn) loc u.got) + =? ..abet ?=(%dead zest) + (emit %pass /kiln/install %arvo %c %zest loc ?:(=(our her) %live %held)) + ?: (~(has by zyn) loc her rem) + abet:(spam (render "already syncing" loc her rem ~) ~) + ?: =([our loc] [her rem]) + abet + =/ sun (sync loc her rem) + ~> %slog.(fmt "beginning install into {here:sun}") + =< abet:abet:init + ?: =(%base loc) + (apex:sun `%kids) + sun +:: +++ poke-kids + |= [hos=kiln-sync nex=(unit desk)] + abet:abet:(apex:(sync hos) nex) :: ++ poke-label |= [syd=desk lab=@tas aey=(unit aeon)] @@ -1233,7 +743,9 @@ :: ++ poke-pause |= =desk - abet:abet:(pause:vats desk) + ?~ got=(~(get by sources) desk) + abet:(spam leaf+"desk not installed: {}" ~) + (poke-unsync desk u.got) :: ++ poke-permission |= [syd=desk pax=path pub=?] @@ -1244,15 +756,11 @@ :: ++ poke-rein |= [=desk =rein] - abet:abet:(set-rein:vats +<) -:: -++ poke-resume - |= =desk - abet:abet:(resume:vats desk) + abet:(emit %pass /kiln/rein %arvo %c %rein desk rein) :: ++ poke-revive |= =desk - abet:abet:(revive:vats desk) + abet:(emit %pass /kiln/revive %arvo %c %zest desk %live) :: ++ poke-rm |= a=path @@ -1271,31 +779,30 @@ :: ++ poke-suspend |= =desk - abet:abet:(suspend:vats desk) + abet:(emit %pass /kiln/suspend %arvo %c %zest desk %dead) :: ++ poke-sync |= hos=kiln-sync - ?: (~(has by syn) hos) - abet:(spam (render "already syncing" [sud her syd]:hos) ~) - abet:abet:start-sync:(auto hos) + ?: (~(has by zyn) hos) + abet:(spam (render "already syncing" [sud her syd ~]:hos) ~) + ~> %slog.(fmt "beginning sync into {} from {}/{}") + abet:abet:init:(sync hos) :: ++ poke-syncs :: print sync config |= ~ =< abet %- spam - ?: =(0 ~(wyt by syn)) + ?: =(0 ~(wyt by zyn)) [%leaf "no syncs configured"]~ - %+ turn ~(tap in ~(key by syn)) - |=(a=kiln-sync (render "sync configured" [sud her syd]:a)) -:: -++ poke-track - |= hos=kiln-sync - ?: (~(has by syn) hos) - abet:(spam (render "already tracking" [sud her syd]:hos) ~) - abet:abet:start-track:(auto hos) + %+ turn ~(tap by zyn) + |= [kiln-sync sync-state] + (render "sync configured" sud her syd kid) :: ++ poke-uninstall |= loc=desk - abet:(uninstall:vats +<) + ?~ got=(~(get by sources) loc) + abet:(spam leaf+"desk not installed: {}" ~) + =. ..on-init (emit %pass /kiln/uninstall %arvo %c %zest loc %dead) + (poke-unsync loc u.got) :: ++ poke-unmount |= mon=kiln-unmount @@ -1307,26 +814,33 @@ abet:(emit %pass /unmount-beam %arvo %c [%ogre [[p q r] s]:u.bem]) abet:(emit %pass /unmount-point %arvo %c [%ogre mon]) :: +:: Don't need to cancel anything because new syncs will get a new nonce +:: ++ poke-unsync |= hus=kiln-unsync - ?. (~(has by syn) hus) - abet:(spam (render "not syncing" [sud her syd]:hus) ~) - %* . abet:abet:stop:(auto hus) - syn (~(del by syn) hus) - == + ?~ got=(~(get by zyn) hus) + abet:(spam (render "not syncing" [sud her syd ~]:hus) ~) + =. zyn (~(del by zyn) hus) + abet:(spam (render "cancelling sync" sud.hus her.hus syd.hus kid.u.got) ~) :: +peer: handle %watch :: ++ peer |= =path ?> (team:title our src) + ?: =(0 1) abet :: avoid mint-vain ?+ path ~|(kiln-path/path !!) [%vats ~] - abet(moz :_(moz [%give %fact ~ %kiln-vats-snap-0 !>(ark)])) + (mean leaf+"kiln: old subscription to /kiln/vats failed" ~) == :: ++ take-agent |= [=wire =sign:agent:gall] - ?+ wire ~|([%kiln-bad-take-agent wire -.sign] !!) + ?+ wire + ?: ?=(%poke-ack -.sign) + ~? ?=(^ p.sign) [%kiln-poke-nack u.p.sign] + abet + ~|([%kiln-bad-take-agent wire -.sign] !!) + :: [%fancy *] ?> ?=(%poke-ack -.sign) (take-coup-fancy t.wire p.sign) @@ -1343,16 +857,15 @@ :: ++ take-arvo |= [=wire =sign-arvo] + ^+ abet ?- wire - [%sync %merg *] %+ take-mere-sync t.t.wire - ?>(?=(%mere +<.sign-arvo) +>.sign-arvo) - [%find-ship *] %+ take-writ-find-ship t.wire - ?>(?=(%writ +<.sign-arvo) +>.sign-arvo) - [%sync *] %+ take-writ-sync t.wire - ?>(?=(%writ +<.sign-arvo) +>.sign-arvo) + [%sync %merg *] abet + [%find-ship *] abet + [%sync *] abet + [%zinc *] (take-sync t.wire sign-arvo) [%autocommit *] %+ take-wake-autocommit t.wire ?>(?=(%wake +<.sign-arvo) +>.sign-arvo) - [%vats *] abet:(take:vats t.wire sign-arvo) + [%vats *] abet [%fuse-request @tas *] =/ f (fuzz i.t.wire now) ?~ f @@ -1371,10 +884,8 @@ * ?+ +<.sign-arvo ((slog leaf+"kiln: strange card {<+<.sign-arvo wire>}" ~) abet) - %done %+ done wire - ?>(?=(%done +<.sign-arvo) +>.sign-arvo) - %mere %+ take-mere wire - ?>(?=(%mere +<.sign-arvo) +>.sign-arvo) + %done (done wire +>.sign-arvo) + %mere (take-mere wire +>.sign-arvo) == == ++ take |=(way=wire ?>(?=([@ ~] way) (work i.way))) :: general handler @@ -1398,42 +909,6 @@ ~? ?=(^ saw) [%kiln-spam-lame u.saw] abet :: -++ take-mere-sync :: - |= [way=wire mes=(each (set path) (pair term tang))] - ?> ?=([@ @ @ *] way) - =/ hos=kiln-sync - :* syd=(slav %tas i.way) - her=(slav %p i.t.way) - sud=(slav %tas i.t.t.way) - == - ?. (~(has by syn) hos) - abet - abet:abet:(mere:(auto hos) mes) -:: -++ take-writ-find-ship :: - |= [way=wire rot=riot] - ?> ?=([@ @ @ *] way) - =/ hos=kiln-sync - :* syd=(slav %tas i.way) - her=(slav %p i.t.way) - sud=(slav %tas i.t.t.way) - == - ?. (~(has by syn) hos) - abet - abet:abet:(take-find-ship:(auto hos) rot) -:: -++ take-writ-sync :: - |= [way=wire rot=riot] - ?> ?=([@ @ @ *] way) - =/ hos=kiln-sync - :* syd=(slav %tas i.way) - her=(slav %p i.t.way) - sud=(slav %tas i.t.t.way) - == - ?. (~(has by syn) hos) - abet - abet:abet:(writ:(auto hos) rot) -:: ++ take-wake-autocommit |= [way=wire error=(unit tang)] ?^ error @@ -1568,112 +1043,165 @@ u.let -- :: -++ auto +++ take-sync + |= [=wire =sign-arvo] + ?> ?=([@ @ @ *] wire) + =* syd i.wire + =/ her (slav %p i.t.wire) + =* sud i.t.t.wire + ?. (~(has by zyn) syd her sud) + abet + abet:abet:(take:(sync syd her sud) t.t.t.wire sign-arvo) +:: +++ sync |= kiln-sync - =+ (~(gut by syn) [syd her sud] let=*@ud) + =/ got (~(get by zyn) syd her sud) + =+ `sync-state`(fall got [(scot %uv nyz) ~ *@ud]) + =? nyz ?=(~ got) +(nyz) |% - ++ abet - ..auto(syn (~(put by syn) [syd her sud] let)) + ++ abet ..sync(zyn (~(put by zyn) [syd her sud] nun kid let)) + ++ apex |=(nex=(unit desk) ..abet(kid nex)) + ++ emit |=(card:agent:gall ..abet(kiln (^emit +<))) + ++ emil |=((list card:agent:gall) ..abet(kiln (^emil +<))) + ++ here "{} from {}/{}" + ++ ware + |= =wire + [%kiln %zinc syd (scot %p her) sud nun wire] + ++ lard + |= [=wire =shed:khan] + (emit %pass (ware wire) %arvo %k %lard %base shed) + ++ merg + |= [=wire =desk] + %: emit + %pass (ware wire) %arvo %c + %merg desk her sud + ud+(dec let) (get-germ desk) + == :: - ++ blab - |= new=(list card:agent:gall) - ^+ +> - +>.$(moz (welp new moz)) + :: (re)Start a sync from scratch by finding what version the source + :: desk is at :: - ++ warp - |= [=wire =ship =riff] - (blab [%pass wire %arvo %c [%warp ship riff]] ~) + ++ init + ^+ ..abet + =. let 0 + %+ lard /init + =/ m (strand:rand ,vase) + ;< =riot:clay bind:m (warp:strandio her sud ~ %sing %y ud+1 /) + ~> %slog.(fmt "activated install into {here}") + ;< now=@da bind:m get-time:strandio + ;< =riot:clay bind:m (warp:strandio her sud ~ %sing %w da+now /) + ?> ?=(^ riot) + =+ !<(=cass:clay q.r.u.riot) + (pure:m !>(ud.cass)) :: - ++ spam |*(* %_(+> ..auto (^spam +<))) - ++ stop - => (spam (render "ended autosync" sud her syd) ~) - =/ =wire /kiln/sync/[syd]/(scot %p her)/[sud] - (warp wire her sud ~) - :: XX duplicate of start-sync? see |track + :: Listen for the next revision, and download it :: - ++ start-track - => (spam (render "activated track" sud her syd) ~) - =. let 1 - =/ =wire /kiln/sync/[syd]/(scot %p her)/[sud] - (warp wire her sud `[%sing %y ud+let /]) + ++ next + ^+ ..abet + %+ lard /next + =/ m (strand:rand ,vase) + ;< =riot:clay bind:m (warp:strandio her sud ~ %sing %w ud+let /) + ~> %slog.(fmt "downloading update for {here}") + ;< =riot:clay bind:m (warp:strandio her sud ~ %sing %v ud+let /) + ?> ?=(^ riot) + (pure:m !>(%done)) :: - ++ start-sync - => (spam (render "finding ship and desk" sud her syd) ~) - =/ =wire /kiln/find-ship/[syd]/(scot %p her)/[sud] - (warp wire her sud `[%sing %y ud+1 /]) + :: Main control router :: - ++ take-find-ship - |= rot=riot - => (spam (render "activated sync" sud her syd) ~) - =/ =wire /kiln/sync/[syd]/(scot %p her)/[sud] - (warp wire her sud `[%sing %w [%da now] /]) + :: NB: %next, %main, and %kids are conceptually a single state with a + :: single error handling mechanism (move on to the next version). We + :: cannot combine them into a single lard because when you update + :: main you may update spider, and in that case all active threads + :: are killed, which would stop us from continuing that thread. + :: Instead, we do the merges to syd and kid explicitly. :: - ++ writ - |= rot=riot - ?~ rot - =. +>.$ - %^ spam - leaf+"sync cancelled, retrying" - (render "on sync" sud her syd) - ~ - start-sync - =. let ?. ?=(%w p.p.u.rot) let ud:;;(cass:clay q.q.r.u.rot) - =/ =wire /kiln/sync/merg/[syd]/(scot %p her)/[sud] - :: germ: merge mode for sync merges - :: - :: Initial merges from any source must use the %init germ. - :: Subsequent merges may use any germ, but if the source is - :: a remote ship with which we have not yet merged, we won't - :: share a merge-base commit and all germs but %only-that will - :: fail. - :: - :: We want to always use %only-that for the first remote merge. - :: But we also want local syncs (%base to %base or %kids) to - :: succeed after that first remote sync. To accomplish both we - :: simply use %only-that for the first three sync merges. (The - :: first two are from the pill.) - :: - =/ =germ - =/ =cass - .^(cass:clay %cw /(scot %p our)/[syd]/(scot %da now)) - ?: =(0 ud.cass) + ++ take + |= [=wire =sign-arvo] + ^+ ..abet + ?> ?=([@ @ *] wire) + ?. =(nun i.wire) + ..abet + ?+ i.t.wire + ~> %slog.(fmt "sync-bad-take {}") + ..abet %init - ?:((gth 2 ud.cass) %only-that %mate) - =< %- spam - ?: =(our her) ~ - [(render "beginning sync" sud her syd) ~] - (blab [%pass wire %arvo %c [%merg syd her sud ud+let germ]] ~) - :: - ++ mere - |= mes=(each (set path) (pair term tang)) - ?: ?=([%| %ali-unavailable *] mes) - =. +>.$ - %^ spam - leaf+"merge cancelled, maybe because sunk; restarting" - (render "on sync" sud her syd) - ~ - start-sync:stop - =. let +(let) - =. +>.$ - %- spam - ?: ?=(%& -.mes) - [(render "sync succeeded" sud her syd) ~] - ?+ p.p.mes - :* (render "sync failed" sud her syd) - leaf+"please manually merge the desks with" - leaf+"|merge %{(trip syd)} {(scow %p her)} %{(trip sud)}" - leaf+"" - leaf+"error code: {}" - q.p.mes - == + ?. =(0 let) + ~> %slog.(fmt "sync-bad-stage {} {}") + ..abet + ?> ?=(%arow +<.sign-arvo) + ?: ?=(%| -.p.sign-arvo) + ~> %slog.(fmt "activation failed into {here}; retrying sync") + %- (slog p.p.sign-arvo) + init + :: Now that we know the revision, start main download loop :: - %no-ali-disc - :~ (render "sync activated" sud her syd) - leaf+"note: blank desk {} on {}" - == + =. let !<(@ud q.p.p.sign-arvo) + next + :: + %next + ?> ?=(%arow +<.sign-arvo) + ?: ?=(%| -.p.sign-arvo) + :: ~> %slog.(fmt "download failed into {here}; retrying sync") + :: %- (slog p.p.sign-arvo) + init + :: + ~> %slog.(fmt "finished downloading update for {here}") + =. let +(let) + :: If nothing changed, just advance + :: + ?. (get-remote-diff our syd now [her sud (dec let)]) + ~> %slog.(fmt "remote is identical to {here}, skipping") + next + :: Else start merging, but also immediately start listening to + :: the next revision. Now, all errors should no-op -- we're + :: already waiting for the next revision. + :: + =. ..abet (merg /main syd) + next + :: + %main + ?> ?=(%mere +<.sign-arvo) + :: This case is maintained by superstition. If you remove it, + :: carefully test that if the source ship is breached, we + :: correctly reset let to 0 + :: + ?: ?=([%| %ali-unavailable *] p.sign-arvo) + =+ "kiln: merge into {here} failed, maybe because sunk; restarting" + %- (slog leaf/- p.p.sign-arvo) + init + ?: ?=(%| -.p.sign-arvo) + =+ "kiln: merge into {here} failed, waiting for next revision" + %- (slog leaf/- p.p.sign-arvo) + ..abet + ~> %slog.(fmt "merge into {} succeeded") + :: If we have a kids desk parameter, merge into that + :: + ?~ kid + ..abet + ~> %slog.(fmt "kids merge into {}") + (merg /kids u.kid) + :: + %kids + ?> ?=(%mere +<.sign-arvo) + ?~ kid + ..abet + :: See %main for this case + :: + ?: ?=([%| %ali-unavailable *] p.sign-arvo) + =+ "kids merge to {} failed, maybe peer sunk; restarting" + ~> %slog.(fmt -) + init + :: Just notify; we've already started listening for the next + :: version + :: + ?- -.p.sign-arvo + %& ~> %slog.(fmt "kids merge to {} succeeded") + ..abet + %| ~> %slog.(fmt "kids merge to {} failed") + %- (slog p.p.sign-arvo) + ..abet == - =/ =wire /kiln/sync/[syd]/(scot %p her)/[sud] - (warp wire her sud `[%sing %y ud+let /]) + == -- :: ++ work :: state machine diff --git a/pkg/arvo/mar/kiln/bump.hoon b/pkg/arvo/mar/kiln/bump.hoon index 766454277..5954006e9 100644 --- a/pkg/arvo/mar/kiln/bump.hoon +++ b/pkg/arvo/mar/kiln/bump.hoon @@ -1,23 +1,13 @@ -|% -+$ bump [except=(set desk) force=_|] --- -|_ b=bump +|_ ~ ++ grad %noun ++ grab |% - ++ noun bump - ++ json - ^- $-(^json bump) - =, dejs:format - %- ot - :~ except+(as so) - force+bo - == + ++ noun ,~ + ++ json ul:dejs:format -- ++ grow |% - ++ noun b + ++ noun ~ + ++ json ~ -- --- - - +-- \ No newline at end of file diff --git a/pkg/arvo/mar/kiln/pikes.hoon b/pkg/arvo/mar/kiln/pikes.hoon new file mode 100644 index 000000000..3d709aea3 --- /dev/null +++ b/pkg/arvo/mar/kiln/pikes.hoon @@ -0,0 +1,24 @@ +/- h=hood +|_ =pikes:h +++ grad %noun +++ grow + |% + ++ noun pikes + ++ json + =, enjs:format + %- pairs + %+ turn ~(tap by pikes) + |= [=desk =pike:h] + :- desk + %- pairs + :~ sync/?~(sync.pike ~ =,(u.sync.pike (pairs ship/s/(scot %p ship) desk/s/desk ~))) + hash/s/(scot %uv hash.pike) + zest/s/zest.pike + wefts/a/(turn ~(tap in wic.pike) weft:enjs:h) + == + -- +++ grab + |% + ++ noun pikes:h + -- +-- diff --git a/pkg/arvo/mar/kiln/sync.hoon b/pkg/arvo/mar/kiln/sync.hoon new file mode 100644 index 000000000..7731a13d7 --- /dev/null +++ b/pkg/arvo/mar/kiln/sync.hoon @@ -0,0 +1,29 @@ +|% ++$ sync + [local=term =ship =desk] +-- +|_ s=sync +++ grad %noun +++ grow + |% + ++ noun s + ++ json + %- pairs:enjs:format + :~ local+s+local.s + desk+s+desk.s + ship+s+(scot %p ship.s) + == + -- +++ grab + |% + ++ noun sync + ++ json + ^- $-(^json sync) + =, dejs:format + %- ot + :~ local+so + ship+(su ;~(pfix sig fed:ag)) + desk+so + == + -- +-- diff --git a/pkg/arvo/mar/kiln/unsync.hoon b/pkg/arvo/mar/kiln/unsync.hoon new file mode 100644 index 000000000..fa203eda8 --- /dev/null +++ b/pkg/arvo/mar/kiln/unsync.hoon @@ -0,0 +1,29 @@ +|% ++$ unsync + [local=term =ship =desk] +-- +|_ usyc=unsync +++ grad %noun +++ grow + |% + ++ noun usyc + ++ json + %- pairs:enjs:format + :~ local+s+local.usyc + desk+s+desk.usyc + ship+s+(scot %p ship.usyc) + == + -- +++ grab + |% + ++ noun unsync + ++ json + ^- $-(^json unsync) + =, dejs:format + %- ot + :~ local+so + ship+(su ;~(pfix sig fed:ag)) + desk+so + == + -- +-- diff --git a/pkg/arvo/mar/kiln/vats-diff-0.hoon b/pkg/arvo/mar/kiln/vats-diff-0.hoon deleted file mode 100644 index cc98e8656..000000000 --- a/pkg/arvo/mar/kiln/vats-diff-0.hoon +++ /dev/null @@ -1,54 +0,0 @@ -/- hood -|_ =diff:hood -++ grad %noun -++ grow - |% - ++ noun diff - ++ json - =, enjs:format - |^ - %+ frond -.diff - ?- -.diff - %block (block +.diff) - ?(%merge-sunk %merge-fail) (desk-arak-err +.diff) - ?(%reset %commit %suspend %revive) (desk-arak +.diff) - == - :: - ++ block - |= [=desk =arak:hood =weft:hood blockers=(set desk)] - %+ merge (desk-arak desk arak) - %- pairs - :~ weft+(weft:enjs:hood weft) - blockers+a+(turn ~(tap in blockers) (lead %s)) - == - :: - ++ desk-arak - |= [=desk =arak:hood] - %- pairs - :~ desk+s+desk - arak+(arak:enjs:hood arak) - == - :: - ++ desk-arak-err - |= [=desk =arak:hood =tang] - %+ merge (desk-arak desk arak) - %+ frond %tang - a+(turn tang tank) - :: - ++ merge - |= [a=^json b=^json] - ^- ^json - ?> &(?=(%o -.a) ?=(%o -.b)) - o+(~(uni by p.a) p.b) - -- - -- -++ grab - |% - ++ noun diff:hood - -- --- - - - - - diff --git a/pkg/arvo/mar/kiln/vats-snap-0.hoon b/pkg/arvo/mar/kiln/vats-snap-0.hoon deleted file mode 100644 index 955229e1a..000000000 --- a/pkg/arvo/mar/kiln/vats-snap-0.hoon +++ /dev/null @@ -1,20 +0,0 @@ -/- hood -!: -|_ ark=(map desk arak:hood) -++ grad %noun -++ grow - |% - ++ noun ark - ++ json - =, enjs:format - %- pairs - %+ turn ~(tap by ark) - |= [=desk =arak:hood] - [desk (arak:enjs:hood arak)] - -- -:: -++ grab - |% - ++ noun (map desk arak:hood) - -- --- diff --git a/pkg/arvo/mar/kiln/vats.hoon b/pkg/arvo/mar/kiln/vats.hoon deleted file mode 100644 index 2a2ec8660..000000000 --- a/pkg/arvo/mar/kiln/vats.hoon +++ /dev/null @@ -1,21 +0,0 @@ -/- *hood -|_ vats=(list vat) -++ grad %noun -++ grow - |% - ++ noun vats - ++ json (vats:enjs vats) - -- -++ grab - |% - ++ noun (list vat) - -- --- - - - - - - - - diff --git a/pkg/arvo/sys.kelvin b/pkg/arvo/sys.kelvin index e77a3de08..b7bcb9ecd 100644 --- a/pkg/arvo/sys.kelvin +++ b/pkg/arvo/sys.kelvin @@ -1 +1 @@ -[%zuse 418] +[%zuse 417] diff --git a/pkg/arvo/sys/arvo.hoon b/pkg/arvo/sys/arvo.hoon index e80424264..7dbbb0a23 100644 --- a/pkg/arvo/sys/arvo.hoon +++ b/pkg/arvo/sys/arvo.hoon @@ -738,7 +738,7 @@ ?@ epic arvo %= $ epic +.epic - arvo .*(arvo [%9 2 %10 [6 %1 -.epic] %0 1]) + arvo .*([arvo -.epic] [%9 2 %10 [6 %0 3] %0 2]) == :: :: +boot: event 2: bootstrap a kernel from source @@ -773,7 +773,7 @@ :: ~> %slog.[0 leaf+"1-c (compiling compiler, wait a few minutes)"] =/ compiler-tool - .*(compiler-gate [%9 2 %10 [6 %1 noun/hoon.log] %0 1]) + .*([compiler-gate noun/hoon.log] [%9 2 %10 [6 %0 3] %0 2]) :: :: switch to the second-generation compiler. we want to be :: able to generate matching reflection nouns even if the @@ -781,7 +781,7 @@ :: generate last-generation spans for `!>`, etc. :: ~> %slog.[0 leaf+"1-d"] - =. compiler-gate .*(0 +:compiler-tool) + =. compiler-gate .*(0 +.compiler-tool) :: :: get the span (type) of the kernel core, which is the context :: of the compiler gate. we just compiled the compiler, @@ -791,18 +791,18 @@ :: ~> %slog.[0 leaf+"1-e"] =/ kernel-span - -:.*(compiler-gate [%9 2 %10 [6 %1 [-.compiler-tool '+>']] %0 1]) + -:.*([compiler-gate -.compiler-tool '+>'] [%9 2 %10 [6 %0 3] %0 2]) :: :: compile the arvo source against the kernel core. :: ~> %slog.[0 leaf+"1-f"] =/ kernel-tool - .*(compiler-gate [%9 2 %10 [6 %1 [kernel-span arvo.log]] %0 1]) + .*([compiler-gate kernel-span arvo.log] [%9 2 %10 [6 %0 3] %0 2]) :: :: create the arvo kernel, whose subject is the kernel core. :: ~> %slog.[0 leaf+"1-g"] - [.*(+>:compiler-gate +:kernel-tool) epic.log] + [.*(+>.compiler-gate +.kernel-tool) epic.log] -- :: :: |adapt @@ -1570,7 +1570,7 @@ :: %crud =? lag.zen ?& ?=(%exit mote.goof.buz) ?=(^ tang.goof.buz) - ?=(%leaf -.i.tang.goof.buz) :: XX ?@ + ?=([%leaf *] i.tang.goof.buz) ?=(%wyrd (crip p.i.tang.goof.buz)) == ~&(%lagging &) diff --git a/pkg/arvo/sys/hoon.hoon b/pkg/arvo/sys/hoon.hoon index 43fee2f55..24c746d8a 100644 --- a/pkg/arvo/sys/hoon.hoon +++ b/pkg/arvo/sys/hoon.hoon @@ -6245,14 +6245,14 @@ ++ mure |= tap=(trap) ^- (unit) - =/ ton (mink [tap %9 2 %0 1] |=((pair) ``.*(~ [%12 1+p 1+q]))) + =/ ton (mink [tap %9 2 %0 1] |=(a=^ ``.*(a [%12 [%0 2] %0 3]))) ?.(?=(%0 -.ton) ~ `product.ton) :: +mute: untyped virtual :: ++ mute |= tap=(trap) ^- (each * (list tank)) - =/ ton (mock [tap %9 2 %0 1] |=((pair) ``.*(~ [%12 1+p 1+q]))) + =/ ton (mock [tap %9 2 %0 1] |=(a=^ ``.*(a [%12 [%0 2] %0 3]))) ?- -.ton %0 [%& p.ton] :: @@ -6265,9 +6265,8 @@ :: ++ slum ~/ %slum - |= [gat=* sam=*] - ^- * - .*(gat [%9 2 %10 [6 %1 sam] %0 1]) + |= sub=[gat=* sam=*] + .*(sub [%9 2 %10 [6 %0 3] %0 2]) :: +soft: virtual clam :: ++ soft @@ -11411,13 +11410,12 @@ == :: ++ slew :: get axis in vase - |= [axe=@ vax=vase] ^- (unit vase) - ?. |- ^- ? - ?: =(1 axe) & - ?. ?=(^ q.vax) | - $(axe (mas axe), q.vax .*(q.vax [0 (cap axe)])) - ~ - `[(~(peek ut p.vax) %free axe) .*(q.vax [0 axe])] + |= [axe=@ vax=vase] + =/ typ |. (~(peek ut p.vax) %free axe) + |- ^- (unit vase) + ?: =(1 axe) `[$:typ q.vax] + ?@ q.vax ~ + $(axe (mas axe), q.vax ?-((cap axe) %2 -.q.vax, %3 +.q.vax)) :: ++ slim :: identical to seer? |= old=vise ^- vase diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 4d657f989..0936cdd58 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1,9 +1,9 @@ :: /sys/lull :: %lull: arvo structures -:: +!: => ..part |% -++ lull %329 +++ lull %328 :: :: :: :::: :: :: (1) models :: :: :: @@ -755,6 +755,7 @@ [%note p=@tD q=tank] :: debug message [%ogre p=@tas] :: delete mount point [%rule red=dict wit=dict] :: node r+w permissions + [%tire p=(each rock:tire wave:tire)] :: app state [%writ p=riot] :: response [%wris p=[%da p=@da] q=(set (pair care path))] :: many changes == :: @@ -784,12 +785,16 @@ [%park des=desk yok=yoki ran=rang] :: synchronous commit [%perm des=desk pax=path rit=rite] :: change permissions [%pork ~] :: resume commit + [%rein des=desk ren=rein] :: extra apps [%stir arg=*] :: debug + [%tire p=(unit ~)] :: app state subscribe [%tomb =clue] :: tombstone specific $>(%trim vane-task) :: trim state $>(%vega vane-task) :: report upgrade [%warp wer=ship rif=riff] :: internal file req [%werp who=ship wer=ship rif=riff-any] :: external file req + [%wick ~] :: try upgrade + [%zest des=desk liv=zest] :: live $>(%plea vane-task) :: ames request == :: :: :: @@ -822,9 +827,14 @@ [%worn =ship =desk =tako =norm] :: set commit norm [%seek =ship =desk =cash] :: fetch source blobs == :: - +$ cone :: domes - %+ map [ship desk] :: - [dome tom=(map tako norm) nor=norm] :: + +$ cone (map [ship desk] foam) :: domes + +$ foam :: + $: dome :: + tom=(map tako norm) :: + nor=norm :: + liv=zest :: + ren=(map dude:gall ?) :: + == :: +$ crew (set ship) :: permissions group +$ dict [src=path rul=real] :: effective permission +$ dome :: project state @@ -894,6 +904,7 @@ who=(pair (set ship) (map @ta crew)) :: == :: +$ regs (map path rule) :: rules for paths + +$ rein (map dude:gall ?) :: extra apps +$ riff [p=desk q=(unit rave)] :: request+desist +$ riff-any :: $% [%1 =riff] :: @@ -917,6 +928,9 @@ [%| p=(list a) q=(list a)] :: p -> q[chunk] == :: ++ urge |*(a=mold (list (unce a))) :: list change + +$ waft :: kelvin range + $^ [[%1 ~] p=(set weft)] :: + weft :: +$ whom (each ship @ta) :: ship or named crew +$ yoki (each yuki yaki) :: commit +$ yuki :: proto-commit @@ -929,11 +943,111 @@ r=tako :: self-reference t=@da :: date == :: + +$ zest $~(%dead ?(%dead %live %held)) :: how live + :: :: + ++ tire :: app state + |% :: + +$ rock (map desk [=zest wic=(set weft)]) :: + +$ wave :: + $% [%wait =desk =weft] :: blocked + [%warp =desk =weft] :: unblocked + [%zest =desk =zest] :: running + == :: + :: + ++ wash :: patch + |= [=rock =wave] + ^+ rock + ?- -.wave + %wait + =/ got=[=zest wic=(set weft)] + (~(gut by rock) desk.wave *zest ~) + (~(put by rock) desk.wave got(wic (~(put in wic.got) weft.wave))) + :: + %warp + %- ~(run by rock) + |= [=zest wic=(set weft)] + [zest (~(del in wic) weft.wave)] + :: + %zest + ?: ?=(%dead zest.wave) + (~(del by rock) desk.wave) + =/ got=[=zest wic=(set weft)] + (~(gut by rock) desk.wave *zest ~) + (~(put by rock) desk.wave got(zest zest.wave)) + == + :: + ++ walk :: diff + |= [a=rock b=rock] + ^- (list wave) + =/ adds (~(dif by b) a) + =/ dels (~(dif by a) b) + =/ bots (~(int by a) b) + ;: welp + ^- (list wave) + %- zing + %+ turn ~(tap by adds) + |= [=desk =zest wic=(set weft)] + ^- (list wave) + :- [%zest desk zest] + %+ turn ~(tap in wic) + |= =weft + [%wait desk weft] + :: + ^- (list wave) + %+ turn ~(tap by dels) + |= [=desk =zest wic=(set weft)] + ^- wave + [%zest desk %dead] + :: + ^- (list wave) + %- zing + %+ turn ~(tap by bots) + |= [=desk * *] + ^- (list wave) + =/ aa (~(got by a) desk) + =/ bb (~(got by b) desk) + =/ wadds (~(dif in wic.bb) wic.aa) + =/ wdels (~(dif in wic.aa) wic.bb) + ;: welp + ?: =(zest.aa zest.bb) + ~ + [%zest desk zest.bb]~ + :: + %+ turn ~(tap by wadds) + |= =weft + ^- wave + [%wait desk weft] + :: + %+ turn ~(tap by wdels) + |= =weft + ^- wave + [%warp desk weft] + == + == + -- :: :: +page-to-lobe: hash a page to get a lobe. :: ++ page-to-lobe |=(page (shax (jam +<))) :: + ++ cord-to-waft + |= =cord + ^- waft + =/ wefts=(list weft) + %+ turn (rash cord (star (ifix [gay gay] tall:vast))) + |= =hoon + !<(weft (slap !>(~) hoon)) + ?: ?=([* ~] wefts) + i.wefts + [[%1 ~] (sy wefts)] + :: + ++ waft-to-wefts + |= kal=waft + ^- (set weft) + ?^ -.kal + p.kal + [kal ~ ~] + :: :: +make-yaki: make commit out of a list of parents, content, and date. :: ++ make-yaki @@ -1658,6 +1772,7 @@ [%sear =ship] :: clear pending queues [%jolt =desk =dude] :: (re)start agent [%idle =dude] :: suspend agent + [%load =load] :: load agent [%nuke =dude] :: delete agent [%doff dude=(unit dude) ship=(unit ship)] :: kill subscriptions [%rake dude=(unit dude) all=?] :: reclaim old subs @@ -1686,6 +1801,7 @@ == == :: +$ dude term :: server identity +$ gill (pair ship term) :: general contact + +$ load (list [=dude =beak =agent]) :: loadout +$ scar :: opaque duct $: p=@ud :: bone sequence q=(map duct bone) :: by duct @@ -2126,10 +2242,11 @@ $~ [%vega ~] :: $% $>(%born vane-task) :: new unix process [%done ~] :: socket closed - :: XX mark ignored - :: + :: TODO mark ignored :: + :: :: [%fard p=(fyrd cage)] :: in-arvo thread [%fyrd p=(fyrd cast)] :: external thread + [%lard =bear =shed] :: inline thread $>(%trim vane-task) :: trim state $>(%vega vane-task) :: report upgrade == :: @@ -2138,8 +2255,200 @@ +$ bear $@(desk beak) :: partial $beak +$ cast (pair mark page) :: output mark + input ++ fyrd |$ [a] [=bear name=term args=a] :: thread run request + :: :: + +$ shed _*form:(strand:rand ,vase) :: compute vase -- ::khan :: +++ rand :: computation + |% + +$ card card:agent:gall + +$ input + $% [%poke =cage] + [%sign =wire =sign-arvo] + [%agent =wire =sign:agent:gall] + [%watch =path] + == + +$ strand-input [=bowl in=(unit input)] + +$ tid @tatid + +$ bowl + $: our=ship + src=ship + tid=tid + mom=(unit tid) + wex=boat:gall + sup=bitt:gall + eny=@uvJ + now=@da + byk=beak + == + :: + :: cards: cards to send immediately. These will go out even if a + :: later stage of the computation fails, so they shouldn't have + :: any semantic effect on the rest of the system. + :: Alternately, they may record an entry in contracts with + :: enough information to undo the effect if the computation + :: fails. + :: wait: don't move on, stay here. The next sign should come back + :: to this same callback. + :: skip: didn't expect this input; drop it down to be handled + :: elsewhere + :: cont: continue computation with new callback. + :: fail: abort computation; don't send effects + :: done: finish computation; send effects + :: + ++ strand-output-raw + |* a=mold + $~ [~ %done *a] + $: cards=(list card) + $= next + $% [%wait ~] + [%skip ~] + [%cont self=(strand-form-raw a)] + [%fail err=(pair term tang)] + [%done value=a] + == + == + :: + ++ strand-form-raw + |* a=mold + $-(strand-input (strand-output-raw a)) + :: + :: Abort strand computation with error message + :: + ++ strand-fail + |= err=(pair term tang) + |= strand-input + [~ %fail err] + :: + :: Asynchronous transcaction monad. + :: + :: Combo of four monads: + :: - Reader on input + :: - Writer on card + :: - Continuation + :: - Exception + :: + ++ strand + |* a=mold + |% + ++ output (strand-output-raw a) + :: + :: Type of an strand computation. + :: + ++ form (strand-form-raw a) + :: + :: Monadic pure. Identity computation for bind. + :: + ++ pure + |= arg=a + ^- form + |= strand-input + [~ %done arg] + :: + :: Monadic bind. Combines two computations, associatively. + :: + ++ bind + |* b=mold + |= [m-b=(strand-form-raw b) fun=$-(b form)] + ^- form + |= input=strand-input + =/ b-res=(strand-output-raw b) + (m-b input) + ^- output + :- cards.b-res + ?- -.next.b-res + %wait [%wait ~] + %skip [%skip ~] + %cont [%cont ..$(m-b self.next.b-res)] + %fail [%fail err.next.b-res] + %done [%cont (fun value.next.b-res)] + == + :: + :: The strand monad must be evaluted in a particular way to maintain + :: its monadic character. +take:eval implements this. + :: + ++ eval + |% + :: Indelible state of a strand + :: + +$ eval-form + $: =form + == + :: + :: Convert initial form to eval-form + :: + ++ from-form + |= =form + ^- eval-form + form + :: + :: The cases of results of +take + :: + +$ eval-result + $% [%next ~] + [%fail err=(pair term tang)] + [%done value=a] + == + :: + ++ validate-mark + |= [in=* =mark =bowl] + ^- cage + =+ .^ =dais:clay %cb + /(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/[mark] + == + =/ res (mule |.((vale.dais in))) + ?: ?=(%| -.res) + ~| %spider-mark-fail + (mean leaf+"spider: ames vale fail {}" p.res) + [mark p.res] + :: + :: Take a new sign and run the strand against it + :: + ++ take + :: cards: accumulate throughout recursion the cards to be + :: produced now + =| cards=(list card) + |= [=eval-form =strand-input] + ^- [[(list card) =eval-result] _eval-form] + =* take-loop $ + =. in.strand-input + ?~ in.strand-input ~ + =/ in u.in.strand-input + ?. ?=(%agent -.in) `in + ?. ?=(%fact -.sign.in) `in + :: + :- ~ + :^ %agent wire.in %fact + (validate-mark q.q.cage.sign.in p.cage.sign.in bowl.strand-input) + :: run the strand callback + :: + =/ =output (form.eval-form strand-input) + :: add cards to cards + :: + =. cards + %+ welp + cards + :: XX add tag to wires? + cards.output + :: case-wise handle next steps + :: + ?- -.next.output + %wait [[cards %next ~] eval-form] + %skip [[cards %next ~] eval-form] + %fail [[cards %fail err.next.output] eval-form] + %done [[cards %done value.next.output] eval-form] + %cont + :: recurse to run continuation with initialization input + :: + %_ take-loop + form.eval-form self.next.output + strand-input [bowl.strand-input ~] + == + == + -- + -- + -- ::strand +:: +$ gift-arvo :: out result <-$ $~ [%doze ~] $% gift:ames diff --git a/pkg/arvo/sys/vane/ames.hoon b/pkg/arvo/sys/vane/ames.hoon index 780eaadc0..f6f1f9a58 100644 --- a/pkg/arvo/sys/vane/ames.hoon +++ b/pkg/arvo/sys/vane/ames.hoon @@ -1280,9 +1280,11 @@ [%forward-lane ~] :: :: this duplicates the routing hack from +send-blob:event-core - :: so long as neither the peer nor the peer's sponsoring galaxy is us: + :: so long as neither the peer nor the peer's sponsoring galaxy is us, + :: and the peer has been reached recently: :: - :: - no route to the peer: send to the peer's sponsoring galaxy + :: - no route to the peer, or peer has not been contacted recently: + :: send to the peer's sponsoring galaxy :: - direct route to the peer: use that :: - indirect route to the peer: send to both that route and the :: the peer's sponsoring galaxy @@ -1294,6 +1296,8 @@ == ~ =; zar=(trap (list lane)) + ?: (lth last-contact.qos.u.peer (sub now ~h1)) + $:zar ?~ route.u.peer $:zar =* rot u.route.u.peer ?:(direct.rot [lane.rot ~] [lane.rot $:zar]) @@ -2229,6 +2233,10 @@ ?: for event-core (try-next-sponsor sponsor.peer-state) + :: if forwarding, route must not be stale + :: + ?: &(for (lth last-contact.qos.peer-state (sub now ~h1))) + (try-next-sponsor sponsor.peer-state) :: ?~ route=route.peer-state %- (trace rot.veb final-ship |.("no route to: {}")) diff --git a/pkg/arvo/sys/vane/clay.hoon b/pkg/arvo/sys/vane/clay.hoon index ab938a078..ff2ccaf89 100644 --- a/pkg/arvo/sys/vane/clay.hoon +++ b/pkg/arvo/sys/vane/clay.hoon @@ -1,5 +1,5 @@ :: clay (4c), revision control -!: +:: :: The way to understand Clay is to take it section-by-section: :: :: - Data structures. You *must* start here; make sure you understand @@ -32,8 +32,56 @@ :: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: -:: Here are the structures. `++raft` is the formal arvo state. It's also -:: worth noting that many of the clay-related structures are defined in lull. +:: We use a system of "invariant footnotes", where nonlocal invariants +:: are tagged with notes to construct a distributed argument that the +:: invariant is maintained. For example, see [wake]. +:: +:: Each one should be described somewhere, and then it should be +:: referenced any time it's touched. For example, any code which might +:: fill a subscription should be tagged with [wake], and if +wake is +:: not called by the end of that function, the function itself should +:: be tagged with [wake]. +:: +:: The tagged code should constitute an argument that the invariant is +:: maintained everywhere. While this is vulnerable to omission ("I +:: forgot that X could fill a subscription", it provides a good minimum +:: bar. +:: +:: Tag the specific line of code which affects the invariant. You do +:: not need to tag every function in a call stack if the invariant is +:: guaranteed to be maintained by the time the function returns. +:: +:: Some invariant references get tagged with whether they "open" or +:: "close" the invariant. For example, adding a commit to the dome +:: "opens" the [wake] invariant, while calling +wake closes it. When +:: an invariant opens, you should be able to scan down and find why it +:: closes in each possible flow of control. For wake, these are +:: labeled like this: +:: +:: open: [wake] < +:: close: [wake] > +:: open and almost immediately close: [wake] <> +:: +:: This system is best used for nonlocal invariants and is not +:: necessary when a function can guarantee its own invariants. For +:: example, consider a set alongside a @ud representing its size. +:: There is an invariant that any time you add or remove an item from +:: the set you must update its size. If you're operating on these +:: directly, it could be beneficial to tag each line of code which +:: might modify the set and make it clear where the size is modified. +:: +:: Sometimes code can be restructured so that many fewer tags are +:: needed. In the above example, if the set is modified in many +:: places, it may be worth factoring out set+size into a data structure +:: with its own arms for put, del, uni, int, etc. Then the invariant +:: only needs to be maintained within that data structure, and call +:: sites do not need to be tagged. +:: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: +:: Here are the structures. `++raft` is the formal arvo state. It's +:: also worth noting that many of the clay-related structures are +:: defined in lull. :: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: =/ bud @@ -124,23 +172,9 @@ nor=norm :: default policy mim=(map path mime) :: mime cache fod=flue :: ford cache - == :: -:: -:: Commit state. -:: -:: -- `del` is the paths we're deleting. -:: -- `ink` is the insertions of hoon files (short-circuited for -:: bootstrapping). -:: -- `ins` is all the other insertions. -:: -- `dif` is the diffs in `dig` applied to their files. -:: -- `mut` is the diffs between `muc` and the original files. -:: -+$ dork :: diff work - $: del=(list path) :: deletes - ink=(list (pair path cage)) :: hoon inserts - ins=(list (pair path cage)) :: inserts - dif=(list (trel path lobe cage)) :: changes - mut=(list (trel path lobe cage)) :: mutations + wic=(map weft yoki) :: commit-in-waiting + liv=zest :: running agents + ren=rein :: force agents on/off == :: :: :: Over-the-wire backfill request/response @@ -265,6 +299,8 @@ mon=(map term beam) :: mount points hez=(unit duct) :: sync duct cez=(map @ta crew) :: permission groups + tyr=(set duct) :: app subs + tur=rock:tire :: last tire pud=(unit [=desk =yoki]) :: pending update bug=[veb=@ mas=@] :: verbosity == :: @@ -318,6 +354,8 @@ haw=(map mood (unit cage)) :: simple cache == :: :: ++$ bill (list dude:gall) +:: :: Active downloads :: +$ update-state @@ -399,6 +437,7 @@ $: %g :: to %gall $> $? %deal %jolt + %load == task:gall == :: @@ -571,6 +610,7 @@ $(vaz t.vaz) :: ++ ford + !. => |% +$ state $: cache=flow @@ -840,7 +880,7 @@ (page-to-cage page) =^ [mark vax=vase] nub (page-to-cage page) =^ =tube nub (build-tube p.page mak) - :_(nub [mak (road |.((tube vax)))]) + :_(nub [mak (tube vax)]) :: ++ page-to-cage |= =page @@ -862,7 +902,7 @@ [cag nub] =^ =tube nub (build-tube mok mak) ~| error-running-cast+[path mok mak] - :_(nub [mak (road |.((tube q.cag)))]) + :_(nub [mak (tube q.cag)]) :: ++ run-pact |= [old=page diff=page] @@ -908,7 +948,7 @@ %+ gain-leak file+path |= nob=state =. nub nob - =/ res=vase (road |.((slap sut hoon.pile))) + =/ res=vase (slap sut hoon.pile) [[%vase res] nub] :: ++ build-file @@ -1324,25 +1364,9 @@ :: NB: ruf=raft crashes in the compiler :: =* ruf |3.+6.^$ - :: - =/ [mow=(list move) hun=(unit duct) rede] - ?. =(our her) - :: no duct, foreign +rede or default - :: - :+ ?: (~(has by hoy.ruf) her) - ~ - [hun.rom.ruf %pass /sinks %j %public-keys (silt her ~)]~ - ~ - =/ rus rus:(~(gut by hoy.ruf) her *rung) - %+ ~(gut by rus) syd - [lim=~2000.1.1 ref=`*rind qyx=~ dom=*dome per=~ pew=~ fiz=*melt] - :: administrative duct, domestic +rede - :: - :+ ~ `hun.rom.ruf - =/ jod (~(gut by dos.rom.ruf) syd *dojo) - [lim=now ref=~ [qyx dom per pew fiz]:jod] - :: + =| [mow=(list move) hun=(unit duct) rede] =* red=rede ->+ + =< apex |% ++ abet :: resolve ^- [(list move) raft] @@ -1360,6 +1384,30 @@ dos.rom (~(put by dos.rom.ruf) syd [qyx dom per pew fiz]:red) == :: + ++ apex + ^+ ..park + ?. =(our her) + :: no duct, foreign +rede or default + :: + =. mow + ?: (~(has by hoy.ruf) her) + ~ + [hun.rom.ruf %pass /sinks %j %public-keys (silt her ~)]~ + =. hun ~ + =. |2.+6.park + =/ rus rus:(~(gut by hoy.ruf) her *rung) + %+ ~(gut by rus) syd + [lim=~2000.1.1 ref=`*rind qyx=~ dom=*dome per=~ pew=~ fiz=*melt] + ..park + :: administrative duct, domestic +rede + :: + =. mow ~ + =. hun `hun.rom.ruf + =. |2.+6.park + =/ jod (~(gut by dos.rom.ruf) syd *dojo) + [lim=now ref=*(unit rind) [qyx dom per pew fiz]:jod] + ..park + :: :: Handle `%sing` requests :: ++ aver @@ -1518,6 +1566,30 @@ (~(has in ^~((silt `(list ^care)`~[%u %w %x %y %z]))) care) -- :: + :: Build and send agents to gall + :: + :: Must be called at the end of a commit, but only while Clay is in a + :: fully-consistent state (eg not in the middle of a kelvin upgrade). + :: + ++ goad + ^+ ..park + =^ moves-1 ruf abet + =^ moves-2 ruf abet:goad:(lu now rof hen ruf) + =. ..park apex + (emil (weld moves-1 moves-2)) + :: + :: Notify subscribers of changes to tire + :: + :: Must be called any time tire could have changed, unless you called + :: goad (which calls tare internally). + :: + ++ tare + ^+ ..park + =^ moves-1 ruf abet + =^ moves-2 ruf abet:tare:(lu now rof hen ruf) + =. ..park apex + (emil (weld moves-1 moves-2)) + :: :: Create a request that cannot be filled immediately. :: :: If it's a local request, we just put in in `qyx`, setting a timer if it's @@ -1531,6 +1603,8 @@ =. wov (dedupe wov) =. qyx (~(put ju qyx) wov hen) ?~ ref + :: [wake] at @da must check if subscription was fulfilled + :: (run-if-future rove.wov |=(@da (bait hen +<))) |- ^+ +>+.$ =/ =rave (rove-to-rave rove.wov) @@ -1647,8 +1721,8 @@ :: no existing aeon is bound to this label :: ?~ yen - =. lab.dom (~(put by lab.dom) bel yon) - ..park + =. lab.dom (~(put by lab.dom) bel yon) :: [wake] <> + wake :: an aeon is bound to this label, :: but it is the same as the existing one, so we no-op :: @@ -1672,7 +1746,7 @@ ?> ?=(~ deletes) =/ data=(map path (each page lobe)) (~(run by changes) |=(=cage &+[p q.q]:cage)) - (park | &+[~ data] *rang) + (park | & &+[~ data] *rang) :: =/ parent-tako=tako (aeon-to-tako:ze let.dom) =/ data=(map path (each page lobe)) @@ -1687,7 +1761,7 @@ (~(run by changes) |=(=cage &+[p q.q]:cage)) :: =/ =yuki [~[parent-tako] data] - (park | &+yuki *rang) + (park | & &+yuki *rang) :: :: Unix commit :: @@ -1716,12 +1790,22 @@ :: :: Guaranteed to finish in one event. :: + :: updated: whether we've already completed sys upgrade + :: goat: whether we should call +goad at the end. Only false + :: during kelvin upgrade so that all commits can happen before + :: the +goad. + :: yoki: new commit + :: rang: any additional objects referenced + :: + :: [goad] < if goat is false, then the caller is responsible to + :: call +goad. + :: :: TODO: needs to check tako in rang :: ++ park =/ check-sane | |^ - |= [updated=? =yoki =rang] + |= [updated=? goat=? =yoki =rang] ^+ ..park =: hut.ran (~(uni by hut.rang) hut.ran) lat.ran (~(uni by lat.rang) lat.ran) @@ -1735,18 +1819,47 @@ |= [=path tum=(each page lobe)] ?: |(?=(%& -.tum) (~(has by lat.ran) p.tum)) & - (mean leaf/"clay: commit failed, file tombstoned: {} {<`@uv`p.tum>}" ~) + =- (mean leaf/- ~) + "clay: commit failed, file tombstoned: {} {<`@uv`p.tum>}" !! :: find desk kelvin :: - =/ kel=weft (get-kelvin yoki) - ?. |(=(%base syd) =(kel [%zuse zuse])) - ~>(%mean.|.(leaf/"clay: bad-kelvin, {<[need=zuse/zuse have=kel]>}") !!) + =/ kel=(set weft) (waft-to-wefts (get-kelvin yoki)) + ?. ?| (~(has in kel) zuse+zuse) :: kelvin match + ?& !=(%base syd) :: best-effort compat + %- ~(any in kel) + |= =weft + &(=(%zuse lal.weft) (gth num.weft zuse)) + == + ?& =(%base syd) :: ready to upgrade + %+ levy ~(tap by tore:(lu now rof hen ruf)) + |= [=desk =zest wic=(set weft)] + ?| =(%base desk) + !?=(%live zest) + !=(~ (~(int in wic) kel)) + == + == + == + ?: (~(all in kel) |=(=weft (gth num.weft zuse))) + %- (slog leaf+"clay: old-kelvin, {<[need=zuse/zuse have=kel]>}" ~) + ..park + =. wic.dom :: [tare] < + %+ roll ~(tap in kel) + |: [weft=*weft wic=wic.dom] + (~(put by wic) weft yoki) + =? ..park !?=(%base syd) wick :: [wick] + %- (slog leaf+"clay: wait-for-kelvin, {<[need=zuse/zuse have=kel]>}" ~) + tare :: [tare] > + =. wic.dom (~(del by wic.dom) zuse+zuse) :: =/ old-yaki ?: =(0 let.dom) *yaki (aeon-to-yaki:ze let.dom) + =/ old-kel=(set weft) + ?: =(0 let.dom) + [zuse+zuse ~ ~] + (waft-to-wefts (get-kelvin %| old-yaki)) =/ [deletes=(set path) changes=(map path (each page lobe))] (get-changes q.old-yaki new-data) ~| [from=let.dom deletes=deletes changes=~(key by changes)] @@ -1755,8 +1868,36 @@ :: promote and fill in mime cache :: =/ invalid (~(uni in deletes) ~(key by changes)) + :: if /sys updated in %base, defer to arvo and return early + :: ?: &(=(%base syd) !updated (~(any in invalid) is-kernel-path)) (sys-update yoki new-data) + :: after this point, there must be no early return except if it's a + :: complete no-op. any error conditions must crash. since we're + :: changing state, we may need to call +wake, +goad, etc, which + :: happens at the end of the function. + :: + :: [wick] if this commit added compatibility to a future kelvin, + :: then we might have unblocked a kelvin upgrade. + :: + :: or, if *this* is a kelvin upgrade, it's possible that another + :: kelvin upgrade will immediately be ready. for example, this + :: could be the case if all desks but one are ready for the next + :: two kelvins, and then that desk is suspended or receives a + :: commit with compatiblity with both kelvins. + :: + :: in any of these cases, we finish the current commit but call + :: +wick so that we try to execute the kelvin upgrade afterward. + :: we want this commit to persist even if the subsequent kelvin + :: upgrade fails. + :: + =. ..park wick + =. wic.dom :: [tare] < + %+ roll ~(tap in kel) + |: [weft=*weft wic=wic.dom] + ?: (gte num.weft zuse) + wic + (~(put by wic) weft yoki) :: =+ ?. (did-kernel-update invalid) ~ ((slog 'clay: kernel updated' ~) ~) @@ -1797,9 +1938,10 @@ == :: if we didn't change the data and it's not a merge commit, abort :: - :: very important to keep all permanent changes below this point - :: ?: &(=([r.old-yaki ~] p.p.yoki) =(data q.old-yaki)) + :: [tare] > if no changes, then commits-in-waiting could not have + :: changed. + :: ..park =/ =yaki ?- -.yoki @@ -1807,6 +1949,8 @@ %| ?> =(data q.p.yoki) p.yoki == + :: [wake] < [ergo] < [goad] < + :: =: let.dom +(let.dom) hit.dom (~(put by hit.dom) +(let.dom) r.yaki) hut.ran (~(put by hut.ran) r.yaki yaki) @@ -1825,7 +1969,45 @@ =. fod.dom [spill sprig]:args =. fad cache.args =. ..park (emil (print q.old-yaki data)) - wake:?:(mem (ergo 0 mum.res) ..park) + :: if upgrading kelvin and there's a commit-in-waiting, use that + :: + =? ..park &(=(%base syd) !=(old-kel kel)) + =/ desks=(list [=desk =dojo]) ~(tap by dos.rom) + =^ moves-1 ruf abet + =| moves-2=(list move) + |- ^+ ..park + ?~ desks + =. ..park apex + (emil (weld moves-1 moves-2)) + ?. ?=(%live liv.dom.dojo.i.desks) + $(desks t.desks) + ?: ?=(%base desk.i.desks) + $(desks t.desks) + ?~ wat=(~(get by wic.dom.dojo.i.desks) zuse+zuse) + (mean (cat 3 'clay: missing commit-in-waiting on ' desk.i.desks) ~) + =/ den ((de now rof hen ruf) our desk.i.desks) + :: [goad] < call without goading so that we apply all the commits + :: before trying to compile all desks to send to gall. + :: + =^ moves-3 ruf abet:(park:den | | u.wat *^rang) + =. moves-2 (weld moves-2 moves-3) + $(desks t.desks) + :: tell gall to try to run agents if %held + :: + :: [goad] > if goat or desk not running. %held uses park-held to + :: defer the goad into a new event, to attempt to revive the desk. + :: Note that %base will always be %live. + :: + =. ..park + ?- liv.dom + %held (emit hen %pass /park-held/[syd] %b %wait now) + %dead ..park + %live ?:(goat goad ..park) + == + :: notify unix and subscribers + :: + =? ..park mem (ergo 0 mum.res) :: [ergo] > + wake:tare :: [wake] > [tare] > :: :: +is-kernel-path: should changing .pax cause a kernel or vane reload? :: @@ -1837,14 +2019,15 @@ | %- ~(any in invalid) |=(p=path &((is-kernel-path p) !?=([%sys %vane *] p))) + :: :: +get-kelvin: read the desk's kernel version from /sys/kelvin :: ++ get-kelvin |= =yoki - ^- weft + ^- waft |^ ?- -.yoki %| - %- lobe-to-weft + %- lobe-to-waft ~> %mean.(cat 3 'clay: missing /sys/kelvin on ' syd) ~| ~(key by q.p.yoki) (~(got by q.p.yoki) /sys/kelvin) @@ -1855,26 +2038,24 @@ ~| ~(key by q.p.yoki) (~(got by q.p.yoki) /sys/kelvin) ?- -.fil - %& (page-to-weft p.fil) - %| (lobe-to-weft p.fil) + %& (page-to-waft p.fil) + %| (lobe-to-waft p.fil) == == :: - ++ lobe-to-weft + ++ lobe-to-waft |= =lobe - ^- weft + ^- waft =/ peg=(unit page) (~(get by lat.ran) lobe) ?~ peg ~|([%sys-kelvin-tombstoned syd] !!) - (page-to-weft u.peg) + (page-to-waft u.peg) :: - ++ page-to-weft + ++ page-to-waft |= =page - ^- weft + ^- waft ?+ p.page ~|(clay-bad-kelvin-mark/p.page !!) - %kelvin ;;(weft q.page) - %mime - =+ ;;(=mime q.page) - !<(weft (slap !>(~) (ream q.q.mime))) + %kelvin ;;(waft q.page) + %mime (cord-to-waft q.q:;;(mime q.page)) == -- :: @@ -2118,6 +2299,16 @@ -- -- :: + :: [goad] Try to revive desk, but if it fails crash the event. + :: + ++ take-park-held + |= err=(unit tang) + ^+ ..park + ?^ err + ((slog leaf+"clay: desk {} failed to unsuspend" u.err) ..park) + =. liv.dom %live + goad + :: :: We always say we're merging from 'ali' to 'bob'. The basic steps, :: not all of which are always needed, are: :: @@ -2208,7 +2399,7 @@ ^+ ..take-fuse ?~ merges =. ..take-fuse (done-fuse clean-state %& ~) - (park | [%| next-yaki(p (flop parents))] rag) + (park | & [%| next-yaki(p (flop parents))] rag) =/ [bec=beak g=germ] i.merges =/ ali-dom=dome:clay (need (~(got by sto.fiz) bec)) =/ result (merge-helper p.bec q.bec g ali-dom `next-yaki) @@ -2289,7 +2480,7 @@ ?~ mr (done %& ~) =. ..merge (done %& conflicts.u.mr) - (park | new.u.mr ~ lat.u.mr) + (park | & new.u.mr ~ lat.u.mr) == :: +$ merge-result [conflicts=(set path) new=yoki lat=(map lobe page)] @@ -2860,6 +3051,11 @@ :: :: Emit update to unix sync :: + :: [ergo] Must be called any time the set of files changes that must + :: be mirrored to unix. +want-mime may optionally be used to cheaply + :: check if a version of a desk is mirrored to unix (and so +ergo + :: must be called). + :: ++ ergo |= [yon=aeon mim=(map path (unit mime))] ^+ ..park @@ -2901,7 +3097,7 @@ %- (slog >%unknown-case< >[her syd case spur]< ~) ..mount =/ for-yon ?:(=(let.dom u.yon) 0 u.yon) - =. mon + =. mon :: [ergo] (~(put by mon) pot [her syd ud+for-yon] spur) =/ =yaki (~(got by hut.ran) (~(got by hit.dom) u.yon)) =/ files (~(run by q.yaki) |=(=lobe |+lobe)) @@ -2918,7 +3114,7 @@ |= [pot=term =case =spur] ^+ ..unmount ?> ?=(^ hez.ruf) - =. mon (~(del by mon) pot) + =. mon (~(del by mon) pot) :: [ergo] =? mim.dom !(want-mime 0) ~ (emit u.hez.ruf %give %ogre pot) :: @@ -2954,7 +3150,7 @@ . (emit hen %give %done ~) :: - ?- -.rit + ?- -.rit :: [wake] <> %r wake(per (put-perm per pax red.rit)) %w wake(pew (put-perm pew pax wit.rit)) %rw wake(per (put-perm per pax red.rit), pew (put-perm pew pax wit.rit)) @@ -2967,9 +3163,11 @@ :: :: Remove a group from all rules. :: + :: [wake] < + :: ++ forget-crew |= nom=@ta - %= +> + %= +> :: [wake] < +call per (forget-crew-in nom per) pew (forget-crew-in nom pew) == @@ -2980,6 +3178,60 @@ |= r=rule r(who (~(del in who.r) |+nom)) :: + ++ set-rein :: [goad] < + |= [ren=(map dude:gall ?)] + ^+ ..park + ..park(ren.dom ren) + :: + ++ set-zest :: [goad] < + |= liv=zest + =? liv =(%base syd) %live + ..park(liv.dom liv) + :: + ++ rise :: [goad] < + |= [=dude:gall on=(unit ?)] + ?< =(%base syd) + %_ ..park + ren.dom + ?~ on + (~(del by ren.dom) dude) + (~(put by ren.dom) dude u.on) + == + :: + ++ stay + |= ver=(unit weft) + ^+ ..park + =. wic.dom :: [tare] <> + ?~ ver + ~ + (~(del by wic.dom) u.ver) + tare + :: + :: Try to apply highest-versioned %base commit-in-waiting + :: + :: [wick] Must be called whenever we might have unblocked a kelvin + :: upgrade. This is move-order agnostic because it defers the + :: upgrade into a new event. + :: + ++ wick + ^+ ..park + (emit hen %pass /wick %b %wait now) + :: + ++ take-wick + |= err=(unit tang) + ^+ ..park + ?^ err + ((slog leaf+"clay: failed to upgrade kelvin (wick)" u.err) ..park) + ?> ?=(%base syd) + =/ wis=(list [weft =yoki]) + %+ sort ~(tap by wic.dom) + |= [a=[weft yoki] b=[weft yoki]] + (gth num.a num.b) + =. wis (skip wis |=([[* a=@ud] *] (gte a zuse))) + ?~ wis :: Every commit bottoms out here ? + ..park + (park | & yoki.i.wis *rang) + :: :: Cancel a request. :: :: For local requests, we just remove it from `qyx`. For foreign requests, @@ -3038,7 +3290,7 @@ :: responses. For %x, we call ++validate-x to validate the type of :: the response. For %y, we coerce the result to an arch. :: - ++ take-foreign-answer :: external change + ++ take-foreign-answer :: external change |= [inx=@ud rut=(unit rand)] ^+ +> ?> ?=(^ ref) @@ -3050,7 +3302,7 @@ ?~ rut :: nothing here, so cache that :: - %_ wake + %_ wake :: [wake] <> haw.u.ref ?. ?=(%sing -.rav) haw.u.ref (~(put by haw.u.ref) mood.rav ~) @@ -3058,7 +3310,7 @@ |^ =/ result=(unit cage) (validate u.rut) =/ =mood [p.p q.p q]:u.rut - =: haw.u.ref (~(put by haw.u.ref) mood result) + =: haw.u.ref (~(put by haw.u.ref) mood result) :: [wake] <> bom.u.ref (~(del by bom.u.ref) inx) fod.u.ref (~(del by fod.u.ref) hen) == @@ -3254,7 +3506,7 @@ ?~ next ..abet(done &) =. ..abet =>((apply-foreign-update u.next) ?>(?=(~ need.sat) .)) - =. ..foreign-update =<(?>(?=(^ ref) .) wake) + =. ..foreign-update =<(?>(?=(^ ref) .) wake) :: [wake] > $ :: This used to be what always removed an item from `need`. Now, :: we remove in +take-backfill, but in the meantime we could have @@ -3285,6 +3537,8 @@ :: store, then we update the map of aeons to commits and the latest :: aeon. :: + :: [wake] < + :: ++ apply-foreign-update |= =nako ^+ ..abet @@ -3316,7 +3570,15 @@ :: =/ =rave rave:(~(got by bom.u.ref) inx) ?> ?=(%many -.rave) - =: let.dom (max let.nako let.dom) + :: [ergo] We do not call +ergo here, but if we wanted to support + :: keeping a foreign mounted desk up-to-date, this would open + :: that invariant. + :: + :: [goad] Same for +goad -- if we supported running agents off + :: foreign desks at an up-to-date revision, we would need to call + :: +goad here. + :: + =: let.dom (max let.nako let.dom) :: [wake] < +work hit.dom hit hut.ran hut :: Is this correct? Seeems like it should only go to `to` if @@ -3389,7 +3651,7 @@ :: ++ send-cards |= [cards=(list card) ducts=(set duct)] - ^+ ..wake + ^+ ..park %- emil %- zing %+ turn cards @@ -3401,6 +3663,18 @@ :: Loop through open subscriptions and check if we can fill any of :: them. :: + :: [wake] This must be called any time something might have changed + :: which fills a subscription or changes the set of subscriptions. + :: + :: It is safe to call this multiple times, because it updates the + :: subscription state to reflect that it's responded. Usually this + :: means deleting the subscription, but %many can respond multiple + :: times. + :: + :: One way of describing this invariant is that if you called +wake + :: on every desk at the end of every +call/+take, it would always + :: no-op. + :: ++ wake ^+ . =/ subs=(list [=wove ducts=(set duct)]) ~(tap by qyx) @@ -3815,7 +4089,7 @@ (build-cast:(aeon-ford aeon) [i i.t]:path) :_(..park [~ ~ %cast vase]) :: - :: XX move to +read-buc + :: TODO move to +read-buc :: ++ read-d !. @@ -3976,7 +4250,7 @@ %late !! :: handled in +aver %case !! :: handled in +aver %base-tako - :: XX this ignores the given beak + :: TODO this ignores the given beak :: maybe move to +aver? ?> ?=(^ t.t.pax) :^ ~ ~ %uvs !> @@ -4170,7 +4444,6 @@ [~ ..park] :: virtualize to catch and produce deterministic failures :: - !: |^ =/ res (mule |.(read)) ?: ?=(%& -.res) p.res %. [[~ ~] ..park] @@ -4199,6 +4472,246 @@ -- -- -- +:: userspace agent management +:: +++ lu + |= [now=@da rof=roof hen=duct raft] + =* ruf |3.+<.$ + =| mow=(list move) + |% + ++ abet + ^- [(list move) raft] + [(flop mow) ruf] + :: + ++ emit + |= mof=move + %_(+> mow [mof mow]) + :: + ++ emil + |= mof=(list move) + %_(+> mow (weld (flop mof) mow)) + :: +ford: init ford + :: + ++ ford + |= [her=ship syd=desk yon=(unit aeon)] + =/ den ((de now rof hen ruf) her syd) + (aeon-ford:den ?~(yon let.dom:den u.yon)) + :: +wrap: save ford cache + :: + ++ wrap + |* [her=ship syd=desk yon=(unit aeon) res=* =state:ford:fusion] + =^ moves ruf + =/ den ((de now rof hen ruf) her syd) + abet:+:(aeon-flow:den ?~(yon let.dom:den u.yon) res cache.state &2.state) + [res (emil moves)] + :: + ++ trace + |= [pri=@ print=(trap tape)] + ?: (lth veb.bug pri) + same + (slog leaf+"goad: {(print)}" ~) + :: +goad: emit %load move for all desks, applying $rein's + :: + :: [goad] Must be called any time the set of running agents changes. + :: This is whenever an agent is started, stopped, or updated. + :: + :: This is not move-order agnostic -- you must be careful of + :: reentrancy as long as arvo's move order is depth-first. + :: + :: [tare] > + :: + ++ goad + ^+ ..abet + =^ sat=(list [=desk =bill]) ..abet + =/ desks=(list desk) ~(tap in ~(key by dos.rom)) + |- ^- [(list [desk bill]) _..abet] + ?~ desks + [~ ..abet] + =/ den ((de now rof hen ruf) our i.desks) + ?. =(%live liv.dom.den) + %- (trace 2 |.("{} is not live")) + $(desks t.desks) + =^ res den (aver:den ~ %x da+now /desk/bill) + =. ruf +:abet:den + ?. ?=([~ ~ *] res) + $(desks t.desks) + =/ bill ~| [%building-bill i.desks] !<(bill q.u.u.res) + =/ rid (override bill ren.dom.den) + %- %+ trace 2 |. + "{} has bill {} and rein {}, so {}" + =^ sats ..abet $(desks t.desks) + [[[i.desks rid] sats] ..abet] + :: + =. sat (apply-precedence sat) + =+ ?: (lth veb.bug 1) ~ + %. ~ %- slog + %+ turn sat + |= [=desk =bill] + leaf+"goad: output: {}: {}" + =^ agents ..abet (build-agents sat) + :: TODO: enable if we can reduce memory usage + :: + :: =. ..abet + :: (build-marks (turn (skip sat |=([desk =bill] =(bill ~))) head)) + :: + =. ..abet tare :: [tare] > + (emit hen %pass /lu/load %g %load agents) + :: +override: apply rein to bill + :: + ++ override + |= [duz=bill ren=(map dude:gall ?)] + ^- bill + =. duz + %+ skip duz + |= =dude:gall + =(`| (~(get by ren) dude)) + :: + =/ dus (sy duz) + =. duz + %+ weld duz + %+ murn ~(tap by ren) + |= [=dude:gall on=?] + ?: &(?=(%& on) !(~(has in dus) dude)) + `u=dude + ~ + duz + :: +apply-precedence: resolve conflicts between $bill's + :: + :: policy is to crash if multiple desks are trying to run the same + :: agent. + :: + ++ apply-precedence + |= sat=(list [=desk =bill]) + ^+ sat + :: sort desks in alphabetical order with %base first + :: + =. sat (sort sat sort-desks) + :: for each desk + :: + =| done=(set dude:gall) + |- ^+ sat + ?~ sat + ~ + :: for each agent + :: + =/ bil bill.i.sat + =^ this done + |- ^- [bill (set dude:gall)] + ?~ bil + [~ done] + :: + ?: (~(has in done) i.bil) + ~> %mean.(cat 3 'clay: cannot run app from two desks: %' i.bil) + !! + =. done (~(put in done) i.bil) + =^ next done $(bil t.bil) + [[i.bil next] done] + [[desk.i.sat this] $(sat t.sat)] + :: + ++ sort-desks + |= [a=[=desk *] b=[=desk *]] + ^- ? + ?: =(%base desk.a) & + ?: =(%base desk.b) | + (aor desk.a desk.b) + :: build-file for each dude + :: + ++ build-agents + |= sat=(list [=desk =bill]) + ^- [load:gall _..abet] + =| lad=load:gall + |- ^- [load:gall _..abet] + ?~ sat + [lad ..abet] + =/ f (ford our desk.i.sat ~) + =^ new=load:gall ..abet + %- wrap :^ our desk.i.sat ~ + |- ^- [load:gall state:ford:fusion] + ?~ bill.i.sat + [~ nub.f] + =^ =vase nub.f (build-file:f /app/[i.bill.i.sat]/hoon) + =/ agent ~| [%building-app bill.i.sat] !<(agent:gall vase) + =^ lid nub.f $(bill.i.sat t.bill.i.sat) + [[[i.bill.i.sat [our desk.i.sat da+now] agent] lid] nub.f] + =. lad (weld lad new) + $(sat t.sat) + :: build-dais for each mark + :: + ++ build-marks + |= desks=(list desk) + ^+ ..abet + ?~ desks + ..abet + =/ f (ford our i.desks ~) + =^ null ..abet + %- wrap :^ our i.desks ~ + =^ marks=(list mark) nub.f + =/ pax=path / + |- ^- [(list mark) _nub.f] + =/ den ((de now rof hen ruf) our i.desks) + =^ res den (aver:den ~ %y da+now mar+pax) + ?. ?=([~ ~ *] res) + [~ nub.f] + =/ arch ~| [%building-arch i.desks] !<(arch q.u.u.res) + =/ m1=(list mark) + ?. ?& ?=(^ fil.arch) + ?=(^ pax) + =(/hoon (slag (dec (lent pax)) `path`pax)) + == + ~ + :_ ~ + ?~ t.pax + '' + |- ^- mark + ?~ t.t.pax + i.pax + (rap 3 i.pax '-' $(pax t.pax) ~) + :: + =^ m2 nub.f + |- ^- [(list mark) _nub.f] + ?~ dir.arch + [~ nub.f] + =^ n1 nub.f ^$(pax (weld pax /[p.n.dir.arch])) + =^ n2 nub.f $(dir.arch l.dir.arch) + =^ n3 nub.f $(dir.arch r.dir.arch) + [:(weld n1 n2 n3) nub.f] + [(weld m1 m2) nub.f] + :: + |- ^- [~ state:ford:fusion] + ?~ marks + [~ nub.f] + =^ =dais nub.f (build-dais:f i.marks) + $(marks t.marks) + $(desks t.desks) + :: + ++ tore + ^- rock:tire + %- ~(run by dos.rom) + |= =dojo + [liv.dom.dojo ~(key by wic.dom.dojo)] + :: + :: [tare] Must be called any time the zest or commits-in-waiting + :: might have changed for a desk. +goad calls this uncondtionally, + :: but if you're not calling +goad, you may need to call this. + :: + ++ tare + ?: =(~ tyr) + ..abet + =/ tor tore + =/ waves=(list wave:tire) (walk:tire tur tor) + ?~ waves + ..abet + =. tur tor + %- emil + %- zing + %+ turn ~(tap in tyr) + |= =duct + ^- (list move) + %+ turn waves + |= =wave:tire + ^- move + [duct %give %tire %| wave] + -- -- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: section 4cA, filesystem vane @@ -4214,7 +4727,7 @@ :: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: =| :: instrument state - $: ver=%12 :: vane version + $: ver=%13 :: vane version ruf=raft :: revision tree == :: |= [now=@da eny=@uvJ rof=roof] :: current invocation @@ -4251,7 +4764,7 @@ ?~ des [[[hen %give %done ~] mos] ..^^$] =/ den ((de now rof hen ruf) our i.des) =^ mor ruf - =< abet:wake + =< abet:wake :: [wake] > ?: ?=(^ cew.req) den (forget-crew:den nom.req) $(des t.des, mos (weld mos mor)) @@ -4387,7 +4900,7 @@ %park =^ mos ruf =/ den ((de now rof hen ruf) our des.req) - abet:(park:den | [yok ran]:req) + abet:(park:den | & [yok ran]:req) [mos ..^$] :: %pork @@ -4395,7 +4908,7 @@ =. pud.ruf ~ =^ mos ruf =/ den ((de now rof hen ruf) our syd) - abet:(park:den & yoki *rang) + abet:(park:den & & yoki *rang) [mos ..^$] :: %perm @@ -4403,33 +4916,65 @@ =/ den ((de now rof hen ruf) our des.req) abet:(perm:den pax.req rit.req) [mos ..^$] + :: + %rein + =^ m1 ruf + =/ den ((de now rof hen ruf) our des.req) + abet:(set-rein:den ren.req) + =^ m2 ruf abet:goad:(lu now rof hen ruf) :: [goad] > + [(weld m1 m2) ..^$] :: %stir - ?+ arg.req ~|(%strange-stir !!) - [%verb @] [~ ..^$(veb.bug.ruf +.arg.req)] - [%mass @] [~ ..^$(mas.bug.ruf +.arg.req)] + ?+ arg.req ~|(%strange-stir !!) + [%verb @] [~ ..^$(veb.bug.ruf +.arg.req)] + [%mass @] [~ ..^$(mas.bug.ruf +.arg.req)] + [%goad ~] + =^ mos ruf abet:goad:(lu now rof hen ruf) + [mos ..^$] + :: + [%rise =desk =dude:gall on=(unit ?)] + =^ m1 ruf + =/ den ((de now rof hen ruf) our desk.arg.req) + abet:(rise:den dude.arg.req on.arg.req) + =^ m2 ruf abet:goad:(lu now rof hen ruf) :: [goad] < + [(weld m1 m2) ..^$] + :: + [%stay =desk ver=(unit weft)] + =^ moves ruf + =/ den ((de now rof hen ruf) our desk.arg.req) + abet:(stay:den ver.arg.req) + [moves ..^$] + :: + [%trim ~] + =: fad.ruf *flow + dos.rom.ruf + %- ~(run by dos.rom.ruf) + |= =dojo + dojo(fod.dom *flue) + :: + hoy.ruf + %- ~(run by hoy.ruf) + |= =rung + %= rung + rus + %- ~(run by rus.rung) + |= =rede + rede(fod.dom *flue) + == + == + [~ ..^$] == :: - %tomb (tomb-clue:tomb hen clue.req) - %trim - =: fad.ruf *flow - dos.rom.ruf - %- ~(run by dos.rom.ruf) - |= =dojo - dojo(fod.dom *flue) - :: - hoy.ruf - %- ~(run by hoy.ruf) - |= =rung - %= rung - rus - %- ~(run by rus.rung) - |= =rede - rede(fod.dom *flue) - == - == - [~ ..^$] + %tire + ?~ p.req + =. tyr.ruf (~(del in tyr.ruf) hen) + `..^$ + =. tyr.ruf (~(put in tyr.ruf) hen) + :_ ..^$ + [hen %give %tire %& tore:(lu now rof hen ruf)]~ :: + %tomb (tomb-clue:tomb hen clue.req) + %trim [~ ..^$] %vega :: wake all desks, then send pending notifications :: @@ -4472,6 +5017,21 @@ cancel-request:den (start-request:den for u.q.rif) [mos ..^$] + :: + %wick + =^ mos ruf + =/ den ((de now rof hen ruf) our %base) + abet:wick:den :: [wick] + [mos ..^$] + :: + %zest + =^ m1 ruf + =/ den ((de now rof hen ruf) our des.req) + :: [wick] could be suspending the last blocking desk + :: + abet:wick:(set-zest:den liv.req) + =^ m2 ruf abet:goad:(lu now rof hen ruf) + [(weld m1 m2) ..^$] :: %plea =* her ship.req @@ -4497,7 +5057,8 @@ ++ load => |% +$ raft-any - $% [%12 raft-12] + $% [%13 raft-13] + [%12 raft-12] [%11 raft-11] [%10 raft-10] [%9 raft-9] @@ -4505,16 +5066,59 @@ [%7 raft-7] [%6 raft-6] == - +$ raft-12 raft - +$ raft-11 - $: rom=room - hoy=(map ship rung) + +$ raft-13 raft + +$ raft-12 + $: rom=room-11 + hoy=(map ship rung-11) ran=rang fad=flow mon=(map term beam) hez=(unit duct) cez=(map @ta crew) pud=(unit [=desk =yoki]) + bug=[veb=@ mas=@] + == + +$ raft-11 + $: rom=room-11 + hoy=(map ship rung-11) + ran=rang + fad=flow + mon=(map term beam) + hez=(unit duct) + cez=(map @ta crew) + pud=(unit [=desk =yoki]) + == + +$ room-11 + $: hun=duct + dos=(map desk dojo-11) + == + +$ dojo-11 + $: qyx=cult + dom=dome-11 + per=regs + pew=regs + fiz=melt + == + +$ dome-11 + $: let=aeon + hit=(map aeon tako) + lab=(map @tas aeon) + tom=(map tako norm) + nor=norm + mim=(map path mime) + fod=flue + == + +$ rung-11 + $: rus=(map desk rede-11) + == + +$ rede-11 + $: lim=@da + ref=(unit rind) + qyx=cult + dom=dome-11 + per=regs + pew=regs + fiz=melt == +$ raft-10 $: rom=room-10 @@ -4734,7 +5338,8 @@ =? old ?=(%9 -.old) 10+(raft-9-to-10 +.old) =? old ?=(%10 -.old) 11+(raft-10-to-11 +.old) =? old ?=(%11 -.old) 12+(raft-11-to-12 +.old) - ?> ?=(%12 -.old) + =? old ?=(%12 -.old) 13+(raft-12-to-13 +.old) + ?> ?=(%13 -.old) ..^^$(ruf +.old) :: +raft-6-to-7: delete stale ford caches (they could all be invalid) :: @@ -4825,7 +5430,7 @@ dos.rom %- ~(run by dos.rom.raf) |= =dojo-10 - ^- dojo + ^- dojo-11 %= dojo-10 fiz *melt qyx (cult-10-to-cult qyx.dojo-10) @@ -4846,7 +5451,7 @@ |= =rung-10 %- ~(run by rus.rung-10) |= =rede-10 - ^- rede + ^- rede-11 %= rede-10 fiz *melt qyx (cult-10-to-cult qyx.rede-10) @@ -4951,6 +5556,46 @@ |= raf=raft-11 ^- raft-12 raf(pud [pud.raf 0 0]) + :: +raft-12-to-13: + :: + :: add .liv and .ren to $dome's + :: add .tyr and .tur to $raft + :: + ++ raft-12-to-13 + |= raf=raft-12 + |^ ^- raft-13 + :: turn on %base desk :: TODO handle other desks somehow + :: :: maybe have kiln send one-time list of desks + :: + =; rof + rof(dos.rom (~(jab by dos.rom.rof) %base |=(d=dojo d(liv.dom %live)))) + ^- raft-13 + %= raf + dos.rom (~(run by dos.rom.raf) dojo-11-to-13) + hoy (~(run by hoy.raf) rung-11-to-13) + |6 [&7.raf ~ ~ |7.raf] + == + :: + ++ dojo-11-to-13 + |= doj=dojo-11 + ^- dojo + doj(dom (dome-11-to-13 dom.doj)) + :: + ++ rung-11-to-13 + |= rug=rung-11 + ^- rung + rug(rus (~(run by rus.rug) rede-11-to-13)) + :: + ++ rede-11-to-13 + |= red=rede-11 + ^- rede + red(dom (dome-11-to-13 dom.red)) + :: + ++ dome-11-to-13 + |= dom=dome-11 + ^- dome + dom(fod [fod.dom ~ liv=%dead ren=~]) + -- -- :: ++ scry :: inspect @@ -5000,6 +5645,8 @@ %rang ``[%rang !>(ran.ruf)] %tomb ``[%flag !>((tomb t.path))] %domes domes + %tire ``[%tire !>(tore:(lu now rof *duct ruf))] + %tyre ``[%tyre !>(tyr.ruf)] == :: ++ domes @@ -5007,19 +5654,19 @@ %- ~(gas by *cone) %+ turn ~(tap by dos.rom.ruf) |= [=desk =dojo] - [[our desk] [[let hit lab] tom nor]:dom.dojo] + [[our desk] [[let hit lab] tom nor liv ren]:dom.dojo] =. domes %- ~(uni by domes) %- ~(gas by *cone) - ^- (list [[ship desk] dome:clay (map tako norm) norm]) + ^- (list [[ship desk] foam]) %- zing - ^- (list (list [[ship desk] dome:clay (map tako norm) norm])) + ^- (list (list [[ship desk] foam])) %+ turn ~(tap by hoy.ruf) |= [=ship =rung] - ^- (list [[^ship desk] dome:clay (map tako norm) norm]) + ^- (list [[^ship desk] foam]) %+ turn ~(tap by rus.rung) |= [=desk =rede] - [[ship desk] [[let hit lab] tom nor]:dom.rede] + [[ship desk] [[let hit lab] tom nor liv ren]:dom.rede] ``[%domes !>(`cone`domes)] :: :: True if file is accessible @@ -5090,19 +5737,24 @@ `u=[need have leak] -- :: -:: We clear the ford cache by replacing it with its bunt as a literal. -:: This nests within +flow without reference to +type, +hoon, or -:: anything else in the sample of cache objects. Otherwise we would be -:: contravariant in the those types, which makes them harder to change. +:: We clear the ford cache by replacing it with its bunt as a literal, +:: with its singleton type. This nests within +flow and +flue without +:: reference to +type, +hoon, or anything else in the sample of cache +:: objects. Otherwise we would be contravariant in those types, which +:: makes them harder to change. :: ++ stay + =/ flu [~ ~] + =+ `flue`flu + =/ flo ~ + =+ `flow`flo :- ver %= ruf - fad ~ + fad flo dos.rom %- ~(run by dos.rom.ruf) |= =dojo - dojo(fod.dom `flue`[~ ~]) + dojo(fod.dom flu) :: hoy %- ~(run by hoy.ruf) @@ -5111,7 +5763,7 @@ rus %- ~(run by rus.rung) |= =rede - rede(fod.dom `flue`[~ ~]) + rede(fod.dom flu) == == :: @@ -5121,14 +5773,14 @@ ^+ [*(list move) ..^$] ?^ dud ~|(%clay-take-dud (mean tang.u.dud)) - ?: ?=([%dist *] tea) + ?: ?=([%lu %load *] tea) ?: ?=(%onto +<.hin) [~ ..^$] ?> ?=(%unto +<.hin) ?> ?=(%poke-ack -.p.hin) ?~ p.p.hin [~ ..^$] - =+ ((slog 'clay: dist migration failed' u.p.p.hin) ~) + =+ ((slog 'clay: reloading agents failed' u.p.p.hin) ~) !! :: ?: ?=([%merge @ @ @ @ ~] tea) @@ -5138,7 +5790,7 @@ =* ali-desk i.t.t.t.tea =/ germ (germ i.t.t.t.t.tea) =^ mos ruf - =/ den ((de now rof hen ruf) our i.t.tea) + =/ den ((de now rof hen ruf) our syd) abet:(merge:den ali-ship ali-desk germ p.hin) [mos ..^$] :: @@ -5150,10 +5802,25 @@ =/ ali-case (rash i.t.t.t.t.tea nuck:so) ?> ?=([%$ *] ali-case) =^ mos ruf - =/ den ((de now rof hen ruf) our i.t.tea) + =/ den ((de now rof hen ruf) our syd) abet:(take-fuse:den [ali-ship ali-desk (case +.ali-case)] p.hin) [mos ..^$] :: + ?: ?=([%park-held @ ~] tea) + ?> ?=(%wake +<.hin) + =* syd i.t.tea + =^ mos ruf + =/ den ((de now rof hen ruf) our syd) + abet:(take-park-held:den error.hin) + [mos ..^$] + :: + ?: ?=([%wick ~] tea) + ?> ?=(%wake +<.hin) + =^ mos ruf + =/ den ((de now rof hen ruf) our %base) + abet:(take-wick:den error.hin) + [mos ..^$] + :: ?: ?=([%foreign-warp *] tea) ?> ?=(%writ +<.hin) :_ ..^$ @@ -5293,6 +5960,8 @@ ?. ?=([%tyme @ @ ~] tea) ~& [%clay-strange-timer tea] [~ ..^$] + :: [wake] when requested time passes, call +wake + :: =/ her (slav %p i.t.tea) =/ syd (slav %tas i.t.t.tea) =^ mos ruf diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index b5e2df90a..ab9f77af6 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -40,6 +40,7 @@ $> $? %merg :: merge desks %perm :: change permissions %warp :: wait for clay hack + %zest :: == :: task:clay :: == :: @@ -52,10 +53,7 @@ task:dill :: == :: $: %g :: - $> $? %jolt :: - %deal :: - == :: - task:gall :: + $>(%deal task:gall) :: == :: $: %j :: $> $? %dawn :: @@ -221,7 +219,7 @@ ^+ . =/ myt (flop (fall tem ~)) =. tem ~ - =. ..mere (pass / %g %jolt %base ram) + =. ..mere (pass /zest %c %zest %base %live) =. ..mere (show-desk %kids) =. ..mere drum-watch |- ^+ ..mere @@ -247,14 +245,6 @@ |= des=desk (pass /show [%c %perm des / r+`[%black ~]]) :: - ++ kiln-install - |= [loc=desk =ship rem=desk] - (deal /install %poke %kiln-install !>([loc ship rem])) - :: - ++ kiln-sync - |= [loc=desk =ship rem=desk] - (deal /sync %poke %kiln-sync !>([loc ship rem])) - :: ++ take :: receive |= [tea=wire sih=sign] ^+ +> diff --git a/pkg/arvo/sys/vane/eyre.hoon b/pkg/arvo/sys/vane/eyre.hoon index 9ca69c537..24354a128 100644 --- a/pkg/arvo/sys/vane/eyre.hoon +++ b/pkg/arvo/sys/vane/eyre.hoon @@ -551,6 +551,18 @@ (easy ~) == == +:: +host-sans-port: strip the : from a host string +:: +++ host-sans-port + ;~ sfix + %+ cook crip + %- star + ;~ less + ;~(plug col (punt dem) ;~(less next (easy ~))) + next + == + (star next) + == :: +per-server-event: per-event server core :: ++ per-server-event @@ -602,6 +614,31 @@ [action [authenticated secure address request] ~ 0] =. connections.state (~(put by connections.state) duct connection) + :: redirect to https if insecure, redirects enabled + :: and secure port live + :: + ?: ?& !secure + redirect.http-config.state + ?=(^ secure.ports.state) + == + =/ location=@t + %+ rap 3 + :~ 'https://' + (rash (fall host '') host-sans-port) + ?: =(443 u.secure.ports.state) + '' + (crip ":{(a-co:co u.secure.ports.state)}") + ?: ?=([[~ ~] ~] (parse-request-line url.request)) + '/' + url.request + == + %- handle-response + :* %start + :- status-code=301 + headers=['location' location]~ + data=~ + complete=%.y + == :: figure out whether this is a cors request, :: whether the origin is approved or not, :: and maybe add it to the "pending approval" set @@ -1228,7 +1265,7 @@ :: the request may include a 'Last-Event-Id' header :: =/ maybe-last-event-id=(unit @ud) - ?~ maybe-raw-header=(get-header:http 'Last-Event-ID' header-list.request) + ?~ maybe-raw-header=(get-header:http 'last-event-id' header-list.request) ~ (rush u.maybe-raw-header dum:ag) :: flush events older than the passed in 'Last-Event-ID' @@ -2272,6 +2309,10 @@ :: %live =. ports.server-state.ax +.task + :: enable http redirects if https port live and cert set + :: + =. redirect.http-config.server-state.ax + &(?=(^ secure.task) ?=(^ secure.http-config.server-state.ax)) [~ http-server-gate] :: %rule: updates our http configuration :: @@ -2284,6 +2325,10 @@ ?: =(secure.config cert.http-rule.task) [~ http-server-gate] =. secure.config cert.http-rule.task + =. redirect.config + ?& ?=(^ secure.ports.server-state.ax) + ?=(^ cert.http-rule.task) + == :_ http-server-gate =* out-duct outgoing-duct.server-state.ax ?~ out-duct ~ @@ -2534,6 +2579,12 @@ ++ load |= old=axle ^+ ..^$ + :: enable https redirects if certificate configured + :: + =. redirect.http-config.server-state.old + ?& ?=(^ secure.ports.server-state.old) + ?=(^ secure.http-config.server-state.old) + == ..^$(ax old) :: +stay: produce current state :: diff --git a/pkg/arvo/sys/vane/gall.hoon b/pkg/arvo/sys/vane/gall.hoon index 7bd8553db..842d9d356 100644 --- a/pkg/arvo/sys/vane/gall.hoon +++ b/pkg/arvo/sys/vane/gall.hoon @@ -42,9 +42,9 @@ :: $move: Arvo-level move :: +$ move [=duct move=(wind note-arvo gift-arvo)] -:: $state-10: overall gall state, versioned +:: $state-11: overall gall state, versioned :: -+$ state-10 [%10 state] ++$ state-11 [%11 state] :: $state: overall gall state :: :: system-duct: TODO document @@ -73,11 +73,11 @@ :: control-duct: TODO document :: run-nonce: unique for each rebuild :: sub-nonce: app-wide global %watch nonce -:: live: is this agent running? TODO document boarer :: stats: TODO document :: bitt: incoming subscriptions :: boat: outgoing subscriptions :: boar: and their nonces +:: code: most recently loaded code :: agent: agent core :: beak: compilation source :: marks: mark conversion requests @@ -86,11 +86,11 @@ $: control-duct=duct run-nonce=@t sub-nonce=_1 - live=? =stats =bitt =boat =boar + code=* agent=(each agent vase) =beak marks=(map duct mark) @@ -149,7 +149,7 @@ :: $spore: structures for update, produced by +stay :: +$ spore - $: %10 + $: %11 system-duct=duct outstanding=(map [wire duct] (qeu remote-request)) contacts=(set ship) @@ -163,223 +163,21 @@ $: control-duct=duct run-nonce=@t sub-nonce=@ - live=? =stats =bitt =boat =boar - old-state=(each vase vase) + code=~ + old-state=[%| vase] =beak marks=(map duct mark) == -- -:: pupal gall core, on upgrade -:: -=< =* adult-gate . - =| spore-tag=@ud - =| =spore - |= [now=@da eny=@uvJ rof=roof] - =* pupal-gate . - =* adult-core (adult-gate +<) - =< |% - ++ call ^call - ++ load ^load - ++ scry ^scry - ++ stay ^stay - ++ take ^take - -- - |% - ++ molt - |= [=duct fec=(unit move)] - ^- [(list move) _adult-gate] - ~> %slog.[0 leaf+"gall: molting"] - ~< %slog.[0 leaf+"gall: molted"] - :: +molt should never notify its client about agent changes - :: - =- :_ -> - %+ welp - (skip -< |=(move ?=([* %give %onto *] +<))) - [^duct %pass /whiz/gall %$ %whiz ~]~ - =/ adult adult-core - =. state.adult - [%10 system-duct outstanding contacts yokes=~ blocked bug]:spore - =/ mo-core (mo-abed:mo:adult system-duct.state.adult) - =/ apps=(list [dap=term =egg]) ~(tap by eggs.spore) - :: upgrade %base apps and suspend others - :: - =. mo-core - |- ^+ mo-core - ?~ apps mo-core - ?. =(%base q.beak.egg.i.apps) - ~> %slog.[0 leaf+"gall: suspending {}"] - =. old-state.egg.i.apps - =/ old old-state.egg.i.apps - |/?-(-.old %| p.old, %& p.old) - =/ ap-core (ap-abut:ap:mo-core i.apps) - $(apps t.apps, mo-core ap-abet:ap-core) - ~> %slog.[0 leaf+"gall: upgrading {}"] - =/ ap-core (ap-abut:ap:mo-core i.apps) - =? ap-core ?=(%& -.old-state.egg.i.apps) - =^ tan ap-core (ap-install:ap-core `p.old-state.egg.i.apps) - ?^ tan - (mean u.tan) - ap-core - $(apps t.apps, mo-core ap-abet:ap-core) - =. mo-core (mo-subscribe-to-agent-builds:mo-core now) - =^ moves adult-gate mo-abet:mo-core - =? moves ?=(^ fec) (weld moves [u.fec]~) - [moves adult-gate] - :: - ++ call - |= [=duct dud=(unit goof) wrapped-task=(hobo task)] - =* call-args +< - ?: =(~ eggs.spore) - ~> %slog.[0 leaf+"gall: direct morphogenesis"] - =. state.adult-gate spore(eggs *(map term yoke)) - (call:adult-core call-args) - ?^ dud - ~> %slog.[0 leaf+"gall: pupa call dud"] - (mean >mote.u.dud< tang.u.dud) - =/ task ((harden task:gall) wrapped-task) - ?: ?=(%vega -.task) - [~ pupal-gate] - (molt duct `[duct %slip %g task]) - :: - ++ scry scry:adult-core - ++ stay spore - ++ take - |= [=wire =duct dud=(unit goof) sign=sign-arvo] - =* take-args +< - ?: =(~ eggs.spore) - ~> %slog.[0 leaf+"gall: direct morphogenesis"] - =. state.adult-gate spore(eggs *(map term yoke)) - (take:adult-core take-args) - ?^ dud - ~> %slog.[0 leaf+"gall: pupa take dud"] - (mean >mote.u.dud< tang.u.dud) - ?: =(/sys/lyv wire) - (molt duct ~) - (molt duct `[duct %pass wire %b %huck sign]) - :: - ++ load - |^ |= old=spore-any - =. spore-tag `@ud`-.old - =? old ?=(%7 -.old) (spore-7-to-8 old) - =? old ?=(%8 -.old) (spore-8-to-9 old) - =? old ?=(%9 -.old) (spore-9-to-10 old) - ?> ?=(%10 -.old) - =. spore old - ?. =(~ eggs.spore) - pupal-gate - ~> %slog.[0 leaf+"gall: direct morphogenesis"] - %_ adult-gate - state spore(eggs *(map term yoke)) - == - :: - +$ spore-any $%(^spore spore-9 spore-8 spore-7) - +$ spore-7 - $: %7 - wipe-eyre-subs=_| ::NOTE band-aid for #3196 - system-duct=duct - outstanding=(map [wire duct] (qeu remote-request-9)) - contacts=(set ship) - eggs=(map term egg-7) - blocked=(map term (qeu blocked-move)) - == - :: - +$ spore-8 - $: %8 - system-duct=duct - outstanding=(map [wire duct] (qeu remote-request-9)) - contacts=(set ship) - eggs=(map term egg-8) - blocked=(map term (qeu blocked-move)) - == - :: - +$ egg-7 egg-8 - +$ egg-8 - $: control-duct=duct - run-nonce=@t - live=? - =stats - watches=watches-8 - old-state=(each vase vase) - =beak - marks=(map duct mark) - == - :: - +$ watches-8 [inbound=bitt outbound=boat-8] - +$ boat-8 (map [wire ship term] [acked=? =path]) - :: - +$ spore-9 - $: %9 - system-duct=duct - outstanding=(map [wire duct] (qeu remote-request-9)) - contacts=(set ship) - eggs=(map term egg) - blocked=(map term (qeu blocked-move)) - =bug - == - :: - +$ remote-request-9 - ?(remote-request %cork) - :: - ++ spore-7-to-8 - |= old=spore-7 - ^- spore-8 - :- %8 - =. eggs.old - %- ~(urn by eggs.old) - |= [a=term e=egg-7] - ::NOTE kiln will kick off appropriate app revival - e(old-state [%| p.old-state.e]) - +>.old - :: - ++ spore-8-to-9 - |= old=spore-8 - ^- spore-9 - =- old(- %9, eggs -, blocked [blocked.old *bug]) - %- ~(run by eggs.old) - |= =egg-8 - ^- egg - =/ [=bitt =boat =boar] (watches-8-to-9 watches.egg-8) - :* control-duct.egg-8 - run-nonce.egg-8 - sub-nonce=1 - live.egg-8 - stats.egg-8 - bitt boat boar - [old-state beak marks]:egg-8 - == - :: - ++ watches-8-to-9 - |= watches-8 - ^- [bitt boat boar] - [inbound outbound (~(run by outbound) |=([acked=? =path] nonce=0))] - :: - ++ spore-9-to-10 - |= old=spore-9 - =- old(- %10, outstanding -) - %- ~(run by outstanding.old) - |= q=(qeu remote-request-9) - %- ~(gas to *(qeu remote-request)) - %+ murn ~(tap to q) - |=(r=remote-request-9 ?:(?=(%cork r) ~ `r)) - -- - -- :: adult gall vane interface, for type compatibility with pupa :: -=| state=state-10 +=| state=state-11 |= [now=@da eny=@uvJ rof=roof] =* gall-payload . -=< ~% %gall-wrap ..mo ~ - |% - ++ call ^call - ++ load ^load - ++ scry ^scry - ++ stay ^stay - ++ take ^take - -- ~% %gall-top ..part ~ |% :: +mo: Arvo-level move handling @@ -413,27 +211,14 @@ mo-core =. mo-core (mo-pass i.list) $(list t.list) - :: +mo-jolt: (re)start agent if not already started on this desk + :: +mo-jolt: (re)start agent :: ++ mo-jolt |= [dap=term =ship =desk] ^+ mo-core - =/ yak (~(get by yokes.state) dap) - ?~ yak - (mo-boot dap ship desk) - ?. -.agent.u.yak - (mo-boot dap ship desk) - ?. =(desk q.beak.u.yak) - (mo-boot dap ship desk) - mo-core - :: +mo-boot: ask %ford to build us a core for the specified agent. - :: - ++ mo-boot - |= [dap=term =ship =desk] - ^+ mo-core - =/ =case [%da now] - =/ =wire /sys/cor/[dap]/(scot %p ship)/[desk]/(scot case) - (mo-pass wire %c %warp ship desk ~ %sing %a case /app/[dap]/hoon) + =/ =wire /sys/cor/[dap]/(scot %p ship)/[desk] + ..mo-core + :: XX (mo-pass wire %c %jolt dap ship desk) :: +mo-doff: kill all outgoing subscriptions :: ++ mo-doff @@ -476,17 +261,24 @@ ^+ mo-core :: =/ yak (~(get by yokes.state) dap) - =/ tex - ?~ yak "installing" - ?- -.agent.u.yak - %& "reloading" - %| "reviving" + =/ tex=(unit tape) + ?~ yak `"installing" + ?- -.agent.u.yak + %| `"reviving" + %& + ?: =(code.u.yak agent) + ~ + `"reloading" == - ~> %slog.[0 leaf+"gall: {tex} {}"] + =+ ?~ tex ~ + ~> %slog.[0 leaf+"gall: {u.tex} {}"] ~ :: ?^ yak + ?: &(=(q.beak.u.yak q.bek) =(code.u.yak agent) =(-.agent.u.yak &)) + mo-core + :: =. yokes.state - (~(put by yokes.state) dap u.yak(beak bek)) + (~(put by yokes.state) dap u.yak(beak bek, code agent)) =/ ap-core (ap-abed:ap dap `our) =. ap-core (ap-reinstall:ap-core agent) =. mo-core ap-abet:ap-core @@ -497,6 +289,7 @@ %* . *yoke control-duct hen beak bek + code agent agent &+agent run-nonce (scot %uw (end 5 (shas %yoke-nonce eny))) == @@ -516,60 +309,6 @@ =. mo-core (mo-clear-queue dap) =/ =suss [dap %boot now] (mo-give %onto [%.y suss]) - :: +mo-subscribe-to-agent-builds: request agent update notices - :: - :: Also subscribe to our own source path, in case we get reloaded - :: but none of the agents do. This way, Clay will still notify us, - :: and we'll be able to exit the chrysalis. - :: - ++ mo-subscribe-to-agent-builds - |= date=@da - ^+ mo-core - =. mo-core (mo-abed system-duct.state) - :: - =/ sources=(jug desk [care:clay path]) - %+ ~(put by *(jug desk [care:clay path])) %base - %- sy - :~ [%z /sys/hoon/hoon] - [%z /sys/arvo/hoon] - [%z /sys/lull/hoon] - [%z /sys/zuse/hoon] - [%z /sys/vane/gall/hoon] - [%z /sys/kelvin] - == - :: - =. sources - =/ apps=(list [dap=term =yoke]) ~(tap by yokes.state) - |- ^+ sources - ?~ apps - sources - =? sources ?=(%& -.agent.yoke.i.apps) - (~(put ju sources) q.beak.yoke.i.apps %a /app/[dap.i.apps]/hoon) - $(apps t.apps) - :: - %- mo-past - %- zing - %+ turn ~(tap by sources) - |= [=desk paths=(set [care:clay path])] - :~ [/sys/lyv %c %warp our desk ~] - [/sys/lyv %c %warp our desk ~ %mult da+date paths] - == - :: +mo-scry-agent-cage: read $agent core from clay - :: - ++ mo-scry-agent-cage - |= [dap=term =desk =case:clay] - ^- (each agent tang) - =/ bek=beak [our desk case] - =/ sky (rof ~ %ca bek /app/[dap]/hoon) - ?~ sky |+[leaf+"gall: {} scry blocked"]~ - ?~ u.sky |+[leaf+"gall: {} scry failed"]~ - =/ =cage u.u.sky - ?. =(%vase p.cage) - |+[leaf+"gall: bad mark {} for agent {}"]~ - =/ res (mule |.(!<(agent !<(vase q.cage)))) - ?: ?=(%& -.res) - &+p.res - |+[[leaf+"gall: {} not valid agent"] p.res] :: +mo-send-foreign-request: handle local request to .ship :: ++ mo-send-foreign-request @@ -676,9 +415,9 @@ ^+ mo-core :: ?+ -.wire !! - %lyv (mo-handle-sys-lyv wire sign-arvo) + %lyv ..mo-core :: vestigial + %cor ..mo-core :: vestigial %era (mo-handle-sys-era wire sign-arvo) - %cor (mo-handle-sys-cor wire sign-arvo) %lag (mo-handle-sys-lag wire sign-arvo) %req (mo-handle-sys-req wire sign-arvo) %way (mo-handle-sys-way wire sign-arvo) @@ -693,60 +432,6 @@ ?. ?=(%breach -.public-keys-result.sign-arvo) mo-core (mo-breach who.public-keys-result.sign-arvo) - :: +mo-handle-sys-cor: receive a built agent from %clay - :: - ++ mo-handle-sys-cor - |= [=wire =sign-arvo] - ^+ mo-core - :: - ?> ?=([%cor @ @ @ @ ~] wire) - =/ [dap=term her=@ta desk=@ta dat=@ta ~] t.wire - =/ =beak [(slav %p her) desk da+now] - ?> ?=([?(%behn %clay) %writ *] sign-arvo) - ?~ p.sign-arvo - (mean leaf+"gall: failed to build agent {}" ~) - =/ cag=cage r.u.p.sign-arvo - ?. =(%vase p.cag) - (mean leaf+"gall: bad %writ {} for {}" ~) - =/ res (mule |.(!<(agent !<(vase q.cag)))) - ?: ?=(%| -.res) - (mean leaf+["gall: bad agent {}"] p.res) - =. mo-core (mo-receive-core dap beak p.res) - (mo-subscribe-to-agent-builds now) - :: +mo-handle-sys-lyv: handle notice that agents have been rebuilt - :: - ++ mo-handle-sys-lyv - |= [=wire =sign-arvo] - ^+ mo-core - ?> ?=([%lyv ~] wire) - ?> ?=([?(%behn %clay) %wris *] sign-arvo) - =/ nex=(list [=care:clay =path]) ~(tap in q.sign-arvo) - ~> %slog.[0 leaf+"gall: reloading agents"] - ~< %slog.[0 leaf+"gall: reloaded agents"] - =; cor (mo-subscribe-to-agent-builds:cor now) - %+ roll nex - |= [[=care:clay =path] cor=_mo-core] - ^+ cor - :: We throw away %z results because we only have them to guarantee - :: molting. Clay will tell us if e.g. changing hoon.hoon affects - :: the result of a particular app (usually it will). - :: - ?. =(%a care) - cor - ~| path=path - =/ dap dap:;;([%app dap=@tas %hoon ~] path) - =/ yok=(unit yoke) (~(get by yokes.state) dap) - ?~ yok - ~> %slog.[0 leaf+"gall: no agent to reload: {}"] - cor - ?: ?=(%| -.agent.u.yok) - ~> %slog.[0 leaf+"gall: dead agent reload: {}"] - cor - =/ bek=beak [our q.beak.u.yok da+now] - =/ rag (mo-scry-agent-cage dap q.bek da+now) - ?: ?=(%| -.rag) - (mean p.rag) - (mo-receive-core:cor dap bek p.rag) :: +mo-handle-sys-lag: handle an ames %clog notification :: ++ mo-handle-sys-lag @@ -900,14 +585,6 @@ ?. =(run-nonce.u.yoke i.t.wire) %- (slog leaf+"gall: got old {<+<.sign-arvo>} for {}" ~) mo-core - :: if agent must be running, revive all needed agents then apply - :: - ?: ?& ?=(%| -.agent.u.yoke) - ?=(?(%dojo %hood) dap) - == - =. mo-core (mo-pass /nowhere %g %jolt %base %hood) - =. mo-core (mo-pass /nowhere %g %jolt %base %dojo) - (mo-pass use+wire %b %huck sign-arvo) :: ?. ?=([?(%gall %behn) %unto *] sign-arvo) ?: ?=(%| -.agent.u.yoke) @@ -1004,15 +681,36 @@ ~> %slog.0^leaf/"gall: nuking {}" =. mo-core ap-abet:ap-nuke:(ap-abed:ap dap `our) mo-core(yokes.state (~(del by yokes.state) dap)) + :: +mo-load: install agents + :: + ++ mo-load + |= agents=(list [=dude =beak =agent]) + =. mo-core + |- ^+ mo-core + ?~ agents mo-core + =/ [=dude =desk] [dude q.beak]:i.agents + :: ~> %slog.0^leaf/"gall: starting {} on {}" + $(agents t.agents, mo-core (mo-receive-core i.agents)) + :: + =/ kil + =/ lol (skim ~(tap by yokes.state) |=([term yoke] -.agent)) + =/ mol (~(gas by *(map term yoke)) lol) + =/ sol ~(key by mol) + =/ new (silt (turn agents head)) + ~(tap in (~(dif in sol) new)) + |- ^+ mo-core + ?~ kil mo-core + ~> %slog.0^leaf/"gall: stopping {}" + $(kil t.kil, mo-core (mo-idle i.kil)) :: +mo-peek: call to +ap-peek (which is not accessible outside of +mo). :: ++ mo-peek ~/ %mo-peek - |= [dap=term =routes care=term =path] + |= [veb=? dap=term =routes care=term =path] ^- (unit (unit cage)) :: =/ app (ap-abed:ap dap routes) - (ap-peek:app care path) + (ap-peek:app veb care path) :: ++ mo-apply |= [dap=term =routes =deal] @@ -1089,12 +787,6 @@ :: ?. |(!is-running is-blocked) (mo-apply agent routes deal) - :: if agent must be running, revive all needed agents then apply - :: - ?: ?=(?(%hood %dojo) agent) - =. mo-core (mo-pass /nowhere %g %jolt %base %hood) - =. mo-core (mo-pass /nowhere %g %jolt %base %dojo) - (mo-slip %g %deal [ship our] agent deal) :: =/ blocked=(qeu blocked-move) =/ waiting (~(get by blocked.state) agent) @@ -1186,19 +878,6 @@ |= [dap=term =routes] ^+ ap-core (ap-yoke dap routes (~(got by yokes.state) dap)) - :: +ap-hatch: initialize agent state from $egg, after upgrade - :: - ++ ap-abut - |= [dap=term =egg] - ^+ ap-core - =/ yak=^yoke - ?: ?=(%| -.old-state.egg) - egg - =/ res (mo-scry-agent-cage dap q.beak.egg da+now) - ?: ?=(%| -.res) - (mean p.res) - egg(p.old-state `agent`p.res) - (ap-yoke dap `our yak) :: +ap-yoke: initialize agent state, starting from a $yoke :: ++ ap-yoke @@ -1240,7 +919,7 @@ %+ turn ~(tap by bitt.yoke) |= [=duct =ship =path] path - =/ will=(list card:agent:gall) + =/ will=(list card:agent) %+ welp ?: =(~ inbound-paths) ~ @@ -1443,7 +1122,7 @@ :: ++ ap-peek ~/ %ap-peek - |= [care=term tyl=path] + |= [veb=? care=term tyl=path] ^- (unit (unit cage)) :: take trailing mark off path for %x scrys :: @@ -1456,6 +1135,7 @@ =/ peek-result=(each (unit (unit cage)) tang) (ap-mule-peek |.((on-peek:ap-agent-core [care tyl]))) ?: ?=(%| -.peek-result) + ?. veb [~ ~] ((slog leaf+"peek bad result" p.peek-result) [~ ~]) :: for non-%x scries, or failed %x scries, or %x results that already :: have the requested mark, produce the result as-is @@ -2053,6 +1733,7 @@ %sear mo-abet:(mo-filter-queue:mo-core ship.task) %jolt mo-abet:(mo-jolt:mo-core dude.task our desk.task) %idle mo-abet:(mo-idle:mo-core dude.task) + %load mo-abet:(mo-load:mo-core +.task) %nuke mo-abet:(mo-nuke:mo-core dude.task) %doff mo-abet:(mo-doff:mo-core +.task) %rake mo-abet:(mo-rake:mo-core +.task) @@ -2063,7 +1744,141 @@ == :: +load: recreate vane; note, only valid if called from pupa :: -++ load !! +++ load + |^ |= old=spore-any + =? old ?=(%7 -.old) (spore-7-to-8 old) + =? old ?=(%8 -.old) (spore-8-to-9 old) + =? old ?=(%9 -.old) (spore-9-to-10 old) + =? old ?=(%10 -.old) (spore-10-to-11 old) + ?> ?=(%11 -.old) + gall-payload(state old) + :: + +$ spore-any $%(spore spore-7 spore-8 spore-9 spore-10) + +$ spore-10 + $: %10 + system-duct=duct + outstanding=(map [wire duct] (qeu remote-request)) + contacts=(set ship) + eggs=(map term egg-10) + blocked=(map term (qeu blocked-move)) + =bug + == + +$ egg-10 + $: control-duct=duct + run-nonce=@t + sub-nonce=@ + live=? + =stats + =bitt + =boat + =boar + old-state=(each vase vase) + =beak + marks=(map duct mark) + == + +$ spore-9 + $: %9 + system-duct=duct + outstanding=(map [wire duct] (qeu remote-request-9)) + contacts=(set ship) + eggs=(map term egg-10) + blocked=(map term (qeu blocked-move)) + =bug + == + :: + +$ remote-request-9 ?(remote-request %cork) + :: + +$ spore-8 + $: %8 + system-duct=duct + outstanding=(map [wire duct] (qeu remote-request-9)) + contacts=(set ship) + eggs=(map term egg-8) + blocked=(map term (qeu blocked-move)) + == + +$ egg-8 + $: control-duct=duct + run-nonce=@t + live=? + =stats + watches=watches-8 + old-state=(each vase vase) + =beak + marks=(map duct mark) + == + +$ watches-8 [inbound=bitt outbound=boat-8] + +$ boat-8 (map [wire ship term] [acked=? =path]) + +$ spore-7 + $: %7 + wipe-eyre-subs=_| ::NOTE band-aid for #3196 + system-duct=duct + outstanding=(map [wire duct] (qeu remote-request-9)) + contacts=(set ship) + eggs=(map term egg-8) + blocked=(map term (qeu blocked-move)) + == + :: + ++ spore-7-to-8 + |= old=spore-7 + ^- spore-8 + :- %8 + =. eggs.old + %- ~(urn by eggs.old) + |= [a=term e=egg-8] + :: kiln will kick off appropriate app revival + :: + e(old-state [%| p.old-state.e]) + +>.old + :: + ++ spore-8-to-9 + |= old=spore-8 + ^- spore-9 + =- old(- %9, eggs -, blocked [blocked.old *bug]) + %- ~(run by eggs.old) + |= =egg-8 + ^- egg-10 + =/ [=bitt =boat =boar] (watches-8-to-9 watches.egg-8) + :* control-duct.egg-8 + run-nonce.egg-8 + sub-nonce=1 + live.egg-8 + stats.egg-8 + bitt boat boar + [old-state beak marks]:egg-8 + == + :: + ++ watches-8-to-9 + |= watches-8 + ^- [bitt boat boar] + [inbound outbound (~(run by outbound) |=([acked=? =path] nonce=0))] + :: + :: remove %cork + :: + ++ spore-9-to-10 + |= old=spore-9 + =- old(- %10, outstanding -) + %- ~(run by outstanding.old) + |= q=(qeu remote-request-9) + %- ~(gas to *(qeu remote-request)) + %+ murn ~(tap to q) + |=(r=remote-request-9 ?:(?=(%cork r) ~ `r)) + :: + :: removed live + :: changed old-state from (each vase vase) to [%| vase] + :: added code + :: + ++ spore-10-to-11 + |= old=spore-10 + ^- spore + %= old + - %11 + eggs + %- ~(urn by eggs.old) + |= [a=term e=egg-10] + ^- egg + e(|3 |4.e(|4 `|8.e(old-state [%| p.old-state.e]))) + == + -- :: +scry: standard scry :: ++ scry @@ -2085,8 +1900,16 @@ (sort ~(tap by queued) aor) :: =/ running - =/ active (~(run by yokes.state) |=(yoke [%.y +<])) - (sort ~(tap by active) aor) + %+ turn (sort ~(tap by yokes.state) aor) + |= [dap=term =yoke] + ^- mass + =/ met=(list mass) + =/ dat (mo-peek:mo | dap [~ ship] %x /whey/mass) + ?: ?=(?(~ [~ ~]) dat) ~ + (fall ((soft (list mass)) q.q.u.u.dat) ~) + ?~ met + dap^&+yoke + dap^|+(welp met dot+&+yoke ~) :: =/ maz=(list mass) :~ [%foreign %.y contacts.state] @@ -2160,7 +1983,7 @@ ?. ?=(^ path) ~ =/ =routes [~ ship] - (mo-peek:mo dap routes care path) + (mo-peek:mo & dap routes care path) :: +stay: save without cache; suspend non-%base agents :: :: TODO: superfluous? see +molt @@ -2172,12 +1995,12 @@ |= =yoke ^- egg %= yoke + code ~ agent + :- %| ?: ?=(%| -.agent.yoke) - [%| p.agent.yoke] - ?: =(%base q.beak.yoke) - [%& on-save:p.agent.yoke] - [%| on-save:p.agent.yoke] + p.agent.yoke + on-save:p.agent.yoke == :: +take: response :: diff --git a/pkg/arvo/sys/vane/khan.hoon b/pkg/arvo/sys/vane/khan.hoon index 62b1999b9..c35efebd5 100644 --- a/pkg/arvo/sys/vane/khan.hoon +++ b/pkg/arvo/sys/vane/khan.hoon @@ -102,15 +102,15 @@ =/ =beam (need (de-beam t.wire)) ?>(?=([@ ~] s.beam) beam(s i.s.beam)) :: -++ start-spider - |= =vase - ^- note - [%g %deal [our our] %spider %poke %spider-start vase] +++ poke-spider + |= [hen=duct =cage] + ^- move + [hen %pass //g %g %deal [our our] %spider %poke cage] :: ++ watch-spider - |= =path - ^- note - [%g %deal [our our] %spider %watch path] + |= [hen=duct =path] + ^- move + [hen %pass //g %g %deal [our our] %spider %watch path] -- =| khan-state =* state - @@ -134,22 +134,8 @@ %born [~ khan-gate(hey hen, tic 0)] :: - %fard - =/ tid=@ta - %^ cat 3 - 'khan-fyrd--' - (scot %uv (sham (mix tic eny))) - =. tic +(tic) - =* fyd p.task - =/ =beak (get-beak bear.fyd now) - =/ args [~ `tid beak name.fyd q.args.fyd] - :_ khan-gate - %+ turn - :~ (watch-spider /thread-result/[tid]) - (start-spider !>(args)) - == - |=(=note ^-(move [hen %pass //g note])) - :: + %fard (bard hen 'khan-fyrd--' bear.p.task %| [name args]:p.task) + %lard (bard hen 'khan-lard--' bear.task %& shed.task) %fyrd =* fyd p.task =/ =beak (get-beak bear.fyd now) @@ -160,6 +146,23 @@ =- [[hen %pass wire -]~ khan-gate] [%k %fard bear.fyd name.fyd p.q.args.fyd vase] == +:: +++ bard + |= [hen=duct prefix=@ta =bear payload=(each shed [name=term args=cage])] + ^- [(list move) _khan-gate] + =/ =tid:rand (cat 3 prefix (scot %uv (sham (mix tic eny)))) + =/ =beak (get-beak bear now) + =/ =cage + ?- -.payload + %& [%spider-inline !>([~ `tid beak p.payload])] + %| [%spider-start !>([~ `tid beak [name q.args]:p.payload])] + == + =. tic +(tic) + :_ khan-gate + :~ (watch-spider hen /thread-result/[tid]) + (poke-spider hen cage) + == +:: :: +load: migrate an old state to a new khan version :: ++ load @@ -195,7 +198,7 @@ ?+ p.cag ~&(bad-fact+p.cag !!) %thread-fail =/ =tang !<(tang q.cag) - %- (slog 'khan-fact' tang) + :: %- (slog 'khan-fact' tang) [hen %give %arow %| p.cag tang]~ :: %thread-done diff --git a/pkg/arvo/sys/zuse.hoon b/pkg/arvo/sys/zuse.hoon index 6c48fe74e..7591a4087 100644 --- a/pkg/arvo/sys/zuse.hoon +++ b/pkg/arvo/sys/zuse.hoon @@ -4,7 +4,7 @@ => ..lull ~% %zuse ..part ~ |% -++ zuse %418 +++ zuse %417 :: :: :: :::: :: :: (2) engines :: :: :: diff --git a/pkg/arvo/ted/naive-csv.hoon b/pkg/arvo/ted/naive-csv.hoon index 3ce3029eb..978c5947c 100644 --- a/pkg/arvo/ted/naive-csv.hoon +++ b/pkg/arvo/ted/naive-csv.hoon @@ -33,10 +33,6 @@ naive, naive-tx=naive-transactions, *strandio -:: starting snapshot. this may not be the right starting point once we have -:: clay tombstoning and the snapshot may be updated -:: -/* snap %azimuth-snapshot /app/azimuth/version-0/azimuth-snapshot :: =, strand=strand:spider =, jael @@ -103,7 +99,11 @@ ;< =events bind:m (scry events /gx/azimuth/logs/noun) =/ [naive-contract=address chain-id=@] [naive chain-id]:(get-network:dice net) - =/ snap=snap-state:dice snap + ;< =bowl:spider bind:m get-bowl + =/ snap=snap-state:dice + .^ snap-state:dice %gx + /(scot %p our.bowl)/azimuth/(scot %da now.bowl)/last-snap/noun + == :: ;< ~ bind:m %- flog-text %+ weld "naive-csv: processing {} ethereum logs " diff --git a/pkg/arvo/ted/test.hoon b/pkg/arvo/ted/test.hoon index 43a81700c..fb4064bd5 100644 --- a/pkg/arvo/ted/test.hoon +++ b/pkg/arvo/ted/test.hoon @@ -44,10 +44,6 @@ %+ turn ~(tap by paths-to-tests) |= [=path test-arms=(list test-arm)] ^- (list test) - :: strip off leading 'tests' from :path - :: - ?. ?=([%tests *] path) ~ - =/ path t.path ::NOTE TMI :: for each test, add the test's name to :path :: %+ turn test-arms @@ -108,7 +104,16 @@ |= arg=vase =/ m (strand ,vase) ^- form:m +;< =bowl:strand bind:m get-bowl:strandio =/ paz=(list path) + :: if no args, test everything under /=base=/tests + :: + ?~ q.arg + ~[/(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/tests] + :: else cast path to ~[path] if needed + :: + ?@ +<.q.arg + [(tail !<([~ path] arg)) ~] (tail !<([~ (list path)] arg)) =/ bez=(list beam) (turn paz |=(p=path ~|([%test-not-beam p] (need (de-beam p))))) diff --git a/pkg/arvo/tests/lib/naive.hoon b/pkg/arvo/tests/lib/naive.hoon index aa107df84..5e3ceec5b 100644 --- a/pkg/arvo/tests/lib/naive.hoon +++ b/pkg/arvo/tests/lib/naive.hoon @@ -739,19 +739,19 @@ ++ gen-rut-jar ^~ ^- (jar @p event) =/ filter ;: cork - (cury filter-owner %.y) + ::(cury filter-owner %.y) ::(cury filter-proxy %spawn) - (cury filter-nonce %.y) + ::(cury filter-nonce %.y) ::(cury filter-rank %galaxy) ::(cury filter-dominion %l1) %- cury :- filter-tx-type - :* ::%spawn - ::%transfer-point + :* %spawn + %transfer-point %configure-keys - ::%set-management-proxy - ::%set-spawn-proxy - ::%set-transfer-proxy + %set-management-proxy + %set-spawn-proxy + %set-transfer-proxy ~ == == diff --git a/pkg/arvo/tests/run/hints.hoon b/pkg/arvo/tests/run/hints.hoon index 7481b105b..ac382497f 100644 --- a/pkg/arvo/tests/run/hints.hoon +++ b/pkg/arvo/tests/run/hints.hoon @@ -1,21 +1,33 @@ :: Test that these hints do not crash the runtime -:: there is no need to include the hints for dynamic %bout +:: there is no need to include a test for dynamic %bout :: since all hoon tests exersize dynamic %bout |% -:: these test that the hilt-trace hints +:: test that these trace hints :: are safe to run or ignore -++ test-hela-hilt +++ test-hilt-hela ~> %hela ~ -++ test-nara-hilt +++ test-hint-hela + ~> %hela.[1 leaf+"test-hint-hela ~"] + ~ +++ test-hilt-nara ~> %nara ~ -:: these test that the hint-trace hints -:: are safe to run or ignore -++ test-hela-hint - ~> %hela.[1 leaf+"test-hela-trace-hint"] +++ test-hint-nara + ~> %nara.[1 leaf+"test-hint-nara ~"] ~ -++ test-nara-hint - ~> %nara.[1 leaf+"test-nara-trace-hint"] +:: test that theses bytecode-report hints +:: are safe to run or ignore +++ test-hilt-xray + ~> %xray + ~ +++ test-hint-xray + ~> %xray.[1 leaf+"test-hint-xray ~"] + ~ +:: test that the hilt bout hint +:: is safe to run or ignore +++ test-hilt-bout + ~> %bout ~ -- + diff --git a/pkg/arvo/tests/sys/grq.hoon b/pkg/arvo/tests/sys/grq.hoon index 7bf1e0a6b..424889b51 100644 --- a/pkg/arvo/tests/sys/grq.hoon +++ b/pkg/arvo/tests/sys/grq.hoon @@ -1,504 +1,505 @@ :: test gall subscription nonce incrementation and ames flow killing :: -/+ *test, v=test-ames-gall -|% -++ test-watch - %- run-chain - |. :- %| - =+ nec-bud:v - :: uncomment to turn on verbose debug output - ::=^ * ames.nec - :: (ames-call:v ames.nec ~[/none] [%spew ~[%msg %snd %rcv %odd]] *roof) - ::=^ * ames.bud - :: (ames-call:v ames.bud ~[/none] [%spew ~[%msg %snd %rcv %odd]] *roof) - :: poke %sub to tell it to subscribe - =/ =task:gall [%deal [~nec ~nec] %sub %poke watch+!>(~bud)] - =^ t1 gall.nec - %: gall-check-call:v gall.nec - [~1111.1.1 0xdead.beef *roof] - [~[/foo] task] - :~ :- ~[/foo] [%give %unto %poke-ack ~] - :- ~[/init] - :* %pass /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud - [%g %deal [~nec ~bud] %pub %watch /foo] - == == - == - :- t1 |. :- %| - :: handle gall passing the %watch to itself, which passes to ames - =^ t2 gall.nec - %: gall-check-call:v gall.nec - [~1111.1.1 0xdead.beef *roof] - :- ~[/use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud /init] - [%deal [~nec ~bud] %pub %watch /foo] - :~ :- ~[/init] [%pass /sys/lag %a %heed ~bud] - :- ~[/init] [%pass /sys/era %j %public-keys (sy ~bud ~)] - :- ~[/use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud /init] - [%pass /sys/way/~bud/pub %a %plea ~bud %g /ge/pub [%0 %s /foo]] - == - == - :- t2 |. :- %| - :: subscriber ames handles %plea from gall, gives a packet to vere - =^ t3 ames.nec - %: ames-check-call:v ames.nec - [~1111.1.1 0xdead.beef *roof] - :- :~ /sys/way/~bud/pub - /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud - /init - == - [%plea ~bud %g /ge/pub [%0 %s /foo]] - :~ :- ~[//unix] - :* %give %send [%& ~bud] - 0xae59.5b29.277b.22c1.20b7.a8db.9086.46df.31bd.f9bc. - 2633.7300.17d4.f5fc.8be5.8bfe.5c9d.36d9.2ea1.7cb3. - 8a00.0200.0132.8fd4.f000 - == - :- ~[/ames] [%pass /pump/~bud/0 %b %wait ~1111.1.1..00.00.01] - == - == - :- t3 |. :- %| - :: publisher ames hears %watch, passes to gall - =^ t4 ames.bud - %: ames-check-call:v ames.bud - [~1111.1.2 0xbeef.dead *roof] - :- ~[//unix] - :* %hear [%& ~nec] - 0xae59.5b29.277b.22c1.20b7.a8db.9086.46df.31bd.f9bc. - 2633.7300.17d4.f5fc.8be5.8bfe.5c9d.36d9.2ea1.7cb3. - 8a00.0200.0132.8fd4.f000 - == - :~ :- ~[//unix] [%pass /qos %d %flog %text "; ~nec is your neighbor"] - :- ~[//unix] - [%pass /bone/~nec/0/1 %g %plea ~nec %g /ge/pub [%0 %s /foo]] - == - == - :- t4 |. :- %| - :: publisher gall hears %watch from ames, passes to itself - =^ t5 gall.bud - %: gall-check-call:v gall.bud - [~1111.1.2 0xbeef.dead *roof] - :- ~[/bone/~nec/0/1 //unix] - [%plea ~nec %g /ge/pub [%0 %s /foo]] - :~ :- ~[/init] [%pass /sys/lag %a %heed ~nec] - :- ~[/init] [%pass /sys/era %j %public-keys (sy ~nec ~)] - :- ~[/bone/~nec/0/1 //unix] - [%pass /sys/req/~nec/pub %g %deal [~nec ~bud] %pub %watch /foo] - == - == - :- t5 |. :- %| - :: publisher gall runs %pub with %watch, gives ack to itself - =^ t6 gall.bud - %: gall-check-call:v gall.bud - [~1111.1.2 0xbeef.dead *roof] - :- ~[/sys/req/~nec/pub /bone/~nec/0/1 //unix] - [%deal [~nec ~bud] %pub %watch /foo] - :~ :- ~[/sys/req/~nec/pub /bone/~nec/0/1 //unix] - [%give %unto %watch-ack ~] - == - == - :- t6 |. :- %| - :: gall gives ack to ames - =^ t7 gall.bud - %: gall-check-take:v gall.bud - [~1111.1.2 0xbeef.dead *roof] - :+ /sys/req/~nec/pub ~[/bone/~nec/0/1 //unix] - [%gall %unto %watch-ack ~] - :~ :- ~[/bone/~nec/0/1 //unix] [%give %done ~] - == - == - :- t7 |. :- %| - :: publisher ames hears ack from gall, sends over the network - =^ t8 ames.bud - %: ames-check-take:v ames.bud - [~1111.1.2 0xbeef.dead *roof] - :+ /bone/~nec/0/1 ~[//unix] - [%gall %done ~] - :~ :- ~[//unix] - :* %give %send [%& ~nec] - 0x2.0219.8100.0485.5530.3c88.9068.3cc6.484e. - 2d9d.076e.6d00.0100.0223.9ae9.5000 - == == - == - :- t8 |. :- %| - :: subscriber ames hears watch-ack packet, gives to gall - =^ t9 ames.nec - %: ames-check-call:v ames.nec - [~1111.1.3 0xdead.beef *roof] - :- ~[//unix] - :* %hear [%& ~bud] - 0x2.0219.8100.0485.5530.3c88.9068.3cc6.484e. - 2d9d.076e.6d00.0100.0223.9ae9.5000 - == - :~ :- ~[//unix] [%pass /qos %d %flog %text "; ~bud is your neighbor"] - :- :~ /sys/way/~bud/pub - /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud - /init - == - [%give %done ~] - :- ~[/ames] [%pass /pump/~bud/0 %b %rest ~1111.1.1..00.00.01] - == - == - :- t9 |. :- %| - :: gall gives %done to itself - =^ t10 gall.nec - %: gall-check-take:v gall.nec - [~1111.1.3 0xdead.beef *roof] - :+ /sys/way/~bud/pub - ~[/use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud /init] - [%ames %done ~] - :~ :- ~[/use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud /init] - [%give %unto %watch-ack ~] - == - == - :- t10 |. :- %| - :: gall gives watch-ack to itself - =^ t11 gall.nec - %: gall-check-take:v gall.nec - [~1111.1.3 0xdead.beef *roof] - :+ /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud - ~[/init] - [%gall %unto %watch-ack ~] - ~ - == - :- t11 |. :- %| - :: start the clog and kick process; give clog to publisher gall - =^ t12 gall.bud - %: gall-check-take:v gall.bud - [~1111.1.4 0xbeef.dead *roof] - :+ /sys/lag ~[/init] - [%ames %clog ~nec] - :~ :- ~[/sys/req/~nec/pub /bone/~nec/0/1 //unix] - [%give %unto %kick ~] - == - == - :- t12 |. :- %| - :: gall gives %kick %boon to ames - =^ t13 gall.bud - %: gall-check-take:v gall.bud - [~1111.1.4 0xbeef.dead *roof] - :+ /sys/req/~nec/pub ~[/bone/~nec/0/1 //unix] - [%gall %unto %kick ~] - :~ :- ~[/bone/~nec/0/1 //unix] [%give %boon %x ~] - == - == - :- t13 |. :- %| - :: ames gives kick over the network - =^ t14 ames.bud - %: ames-check-take:v ames.bud - [~1111.1.4 0xbeef.dead *roof] - :+ /bone/~nec/0/1 ~[//unix] - [%gall %boon %x ~] - :~ :- ~[//unix] - :* %give %send [%& ~nec] - 0xa1fc.cd35.c730.9a00.07e0.90a2.f87c.3657.935e. - 4ca0.801d.3ddc.d400.0100.0223.bc18.1000 - == - :- ~[/ames] [%pass /pump/~nec/1 %b %wait ~1111.1.4..00.00.01] - == - == - :- t14 |. :- %| - :: subscriber ames receives kick, gives to gall and gives ack to unix - =^ t15 ames.nec - %: ames-check-call:v ames.nec - [~1111.1.5 0xdead.beef *roof] - :- ~[//unix] - :* %hear [%& ~bud] - 0xa1fc.cd35.c730.9a00.07e0.90a2.f87c.3657.935e. - 4ca0.801d.3ddc.d400.0100.0223.bc18.1000 - == - :~ :- :~ /sys/way/~bud/pub - /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud - /init - == - [%give %boon %x ~] - :- ~[//unix] - :* %give %send [%& ~bud] - 0xfe.e208.da00.0491.bf7f.9594.2ddc.0948. - 9de0.3906.b678.6e00.0200.0132.e55d.5000 - == == - == - :- t15 |. :- %| - :: subscriber gall receives kick %boon from ames, gives to self - =^ t16 gall.nec - %: gall-check-take:v gall.nec - [~1111.1.5 0xdead.beef *roof] - :+ /sys/way/~bud/pub - ~[/use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud /init] - [%ames %boon %x ~] - :~ :- ~[/use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud /init] - [%give %unto %kick ~] - :- ~[/use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud /init] - [%pass /sys/way/~bud/pub %a %cork ~bud] - == - == - :: subscriber gall receives %kick from itself - =^ t17 gall.nec - %: gall-check-take:v gall.nec - [~1111.1.5 0xdead.beef *roof] - :+ /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud - ~[/init] - [%gall %unto %kick ~] - :~ :- ~[/init] - :* %pass /use/sub/0w1.d6Isf/out/~bud/pub/2/sub-foo/~bud - [%g %deal [~nec ~bud] %pub %watch /foo] - == == - == - :- t17 |. :- %| - :: gall receives %deal %watch from itself, passes to ames - =^ t18 gall.nec - %: gall-check-call:v gall.nec - [~1111.1.5 0xdead.beef *roof] - :- ~[/use/sub/0w1.d6Isf/out/~bud/pub/2/sub-foo/~bud /init] - [%deal [~nec ~bud] %pub %watch /foo] - :~ :- ~[/use/sub/0w1.d6Isf/out/~bud/pub/2/sub-foo/~bud /init] - [%pass /sys/way/~bud/pub %a %plea ~bud %g /ge/pub [%0 %s /foo]] - == - == - :- t18 |. :- %| - :: subscriber ames sends new %watch - =^ t19 ames.nec - %: ames-check-call:v ames.nec - [~1111.1.5 0xdead.beef *roof] - :- :~ /sys/way/~bud/pub - /use/sub/0w1.d6Isf/out/~bud/pub/2/sub-foo/~bud - /init - == - [%plea ~bud %g /ge/pub [%0 %s /foo]] - :~ :- ~[//unix] - :* %give %send [%& ~bud] - 0xfe.9174.6d7c.e042.4ea7.cf3c.08da.3acf.68ec.3bd1.1f2c.abfe.f500. - 1897.c42e.a3ec.2159.86d6.e2f1.b344.9d06.b600.0200.0132.ebe7.8800 - == - :- ~[/ames] [%pass /pump/~bud/4 %b %wait ~1111.1.5..00.00.01] - == - == - :- t19 |. :- %| - :: subscriber ames sends %cork - =^ t20 ames.nec - %: ames-check-call:v ames.nec - [~1111.1.5 0xdead.beef *roof] - :- :~ /sys/way/~bud/pub - /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud - /init - == - [%cork ~bud] - :~ :- ~[//unix] - :* %give %send [%& ~bud] - 0xb.130c.ab37.ca24.49cd.aecb.23ba.70f1.6f1c.4d00.124e.c9a5. - 3413.3843.d81c.47c4.7040.6e62.3700.0200.0132.e1ab.9000 - == - :- ~[/ames] [%pass /pump/~bud/0 %b %wait ~1111.1.5..00.02.00] - == - == - :: publisher ames hears %kick ack - :- t20 |. :- %| - =^ t21 ames.bud - %: ames-check-call:v ames.bud - [~1111.1.6 0xbeef.dead *roof] - :- ~[//unix] - :* %hear [%& ~nec] - 0xfe.e208.da00.0491.bf7f.9594.2ddc.0948. - 9de0.3906.b678.6e00.0200.0132.e55d.5000 - == - :~ :- ~[/ames] [%pass /pump/~nec/1 %b %rest ~1111.1.4..00.00.01] - == - == - :: publisher ames hears new %watch - :- t21 |. :- %| - =^ t22 ames.bud - %: ames-check-call:v ames.bud - [~1111.1.7 0xbeef.dead *roof] - :- ~[//unix] - :* %hear [%& ~nec] - 0xfe.9174.6d7c.e042.4ea7.cf3c.08da.3acf.68ec.3bd1.1f2c.abfe.f500. - 1897.c42e.a3ec.2159.86d6.e2f1.b344.9d06.b600.0200.0132.ebe7.8800 - == - :~ :- ~[//unix] - [%pass /bone/~nec/0/5 %g %plea ~nec %g /ge/pub [%0 %s /foo]] - == - == - :: publisher gall hears new %watch, passes to self - :- t22 |. :- %| - =^ t23 gall.bud - %: gall-check-call:v gall.bud - [~1111.1.7 0xbeef.dead *roof] - :- ~[/bone/~nec/0/5 //unix] - [%plea ~nec %g /ge/pub [%0 %s /foo]] - :~ :- ~[/bone/~nec/0/5 //unix] - [%pass /sys/req/~nec/pub %g %deal [~nec ~bud] %pub %watch /foo] - == - == - :: publisher gall runs :pub's +on-watch, gives ack to self - :- t23 |. :- %| - =^ t24 gall.bud - %: gall-check-call:v gall.bud - [~1111.1.7 0xbeef.dead *roof] - :- ~[/sys/req/~nec/pub /bone/~nec/0/5 //unix] - [%deal [~nec ~bud] %pub %watch /foo] - :~ :- ~[/sys/req/~nec/pub /bone/~nec/0/5 //unix] - [%give %unto %watch-ack ~] - == - == - :: publisher gall hears %watch-ack, gives to ames - :- t24 |. :- %| - =^ t25 gall.bud - %: gall-check-take:v gall.bud - [~1111.1.7 0xbeef.dead *roof] - :+ /sys/req/~nec/pub ~[/bone/~nec/0/5 //unix] - [%gall %unto %watch-ack ~] - :~ :- ~[/bone/~nec/0/5 //unix] [%give %done ~] - == - == - :: publisher ames hears done from gall, sends over the network - :- t25 |. :- %| - =^ t26 ames.bud - %: ames-check-take:v ames.bud - [~1111.1.7 0xbeef.dead *roof] - :+ /bone/~nec/0/5 ~[//unix] - [%gall %done ~] - :~ :- ~[//unix] - :* %give %send [%& ~nec] - 0x5f5.c27c.c400.0587.8b0d.0a5d.eb8e.39fa. - 49f4.4848.bfa6.f600.0100.0223.c98c.8800 - == == - == - :: publisher ames hears %cork, passes to itself - :- t26 |. :- %| - =^ t27 ames.bud - %: ames-check-call:v ames.bud - [~1111.1.8 0xbeef.dead *roof] - :- ~[//unix] - :* %hear [%& ~nec] - 0xb.130c.ab37.ca24.49cd.aecb.23ba.70f1.6f1c.4d00.124e.c9a5. - 3413.3843.d81c.47c4.7040.6e62.3700.0200.0132.e1ab.9000 - == - :~ :- ~[//unix] [%pass /bone/~nec/0/1 %a %plea ~nec [%a /close ~]] - == - == - :- t27 |. :- %| - :: publisher ames hear cork plea from self, give %done to self - =^ t28 ames.bud - %: ames-check-call:v ames.bud - [~1111.1.8 0xbeef.dead *roof] - :- ~[/bone/~nec/0/1 //unix] - [%plea ~nec [%a /close ~]] - :~ :- ~[/bone/~nec/0/1 //unix] [%give %done ~] - == - == - :: publisher ames hears cork done from self, sends ack packet - :- t28 |. :- %| - =^ t29 ames.bud - %: ames-check-take:v ames.bud - [~1111.1.8 0xbeef.dead *roof] - :+ /bone/~nec/0/1 - ~[//unix] - [%ames %done ~] - :~ :- ~[//unix] - :* %give %send [%& ~nec] - 0x5f.f966.8e00.0449.bdec.9006.c7e5.1237. - 1d87.53fe.d7bb.ad00.0100.0223.c6a8.5800 - == == - == - :: subscriber ames hears %watch-ack, gives to gall - :- t29 |. :- %| - =^ t30 ames.nec - %: ames-check-call:v ames.nec - [~1111.1.9 0xdead.beef *roof] - :- ~[//unix] - :* %hear [%& ~bud] - 0x5f5.c27c.c400.0587.8b0d.0a5d.eb8e.39fa. - 49f4.4848.bfa6.f600.0100.0223.c98c.8800 - == - :~ :- :~ /sys/way/~bud/pub - /use/sub/0w1.d6Isf/out/~bud/pub/2/sub-foo/~bud - /init - == - [%give %done ~] - :- ~[/ames] [%pass /pump/~bud/4 %b %rest ~1111.1.5..00.00.01] - == - == - :: subscriber gall hears new %watch-ack from ames, gives to self - :- t30 |. :- %| - =^ t31 gall.nec - %: gall-check-take:v gall.nec - [~1111.1.9 0xdead.beef *roof] - :+ /sys/way/~bud/pub - :~ /use/sub/0w1.d6Isf/out/~bud/pub/2/sub-foo/~bud - /init - == - [%ames %done ~] - :~ :- :~ /use/sub/0w1.d6Isf/out/~bud/pub/2/sub-foo/~bud - /init - == - [%give %unto %watch-ack ~] - == - == - :: subscriber gall hears new %watch-ack from self, tells :sub - :- t31 |. :- %| - =^ t32 gall.nec - %: gall-check-take:v gall.nec - [~1111.1.9 0xdead.beef *roof] - :+ /use/sub/0w1.d6Isf/out/~bud/pub/2/sub-foo/~bud - ~[/init] - [%gall %unto %watch-ack ~] - ~ - == - :: subscriber ames hears %cork ack - :- t32 |. :- %| - =^ t33 ames.nec - %: ames-check-call:v ames.nec - [~1111.1.10 0xdead.beef *roof] - :- ~[//unix] - :* %hear [%& ~bud] - 0x5f.f966.8e00.0449.bdec.9006.c7e5.1237. - 1d87.53fe.d7bb.ad00.0100.0223.c6a8.5800 - == - :~ :- :~ /sys/way/~bud/pub - /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud - /init - == - [%give %done ~] - :- ~[/ames] [%pass /pump/~bud/0 %b %rest ~1111.1.5..00.02.00] - == - == - :: subscriber gall hears %cork ack from ames - :- t33 |. :- %| - =^ t34 gall.nec - %: gall-check-take:v gall.nec - [~1111.1.10 0xdead.beef *roof] - :+ /sys/way/~bud/pub - :~ /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud - /init - == - [%ames %done ~] - ~ - == - :- t34 |. :- %& - ;: weld - %+ expect-eq - !> (sy 0 ~) - !> =< corked - %: ames-scry-peer:v - ames.nec - [~1111.1.10 0xdead.beef *roof] - [~nec ~bud] - == - :: - %+ expect-eq - !> (sy 1 ~) - !> =< corked - %: ames-scry-peer:v - ames.bud - [~1111.1.8 0xbeef.dead *roof] - [~bud ~nec] - == - :: - %+ expect-eq - !> 2 - !> %: gall-scry-nonce:v - gall.nec - [~1111.1.10 0xdead.beef *roof] - ~nec %sub - [~bud %pub /sub-foo/~bud] - == - == --- +:: /+ *test, v=test-ames-gall +:: |% +:: ++ test-watch +:: %- run-chain +:: |. :- %| +:: =+ nec-bud:v +:: :: uncomment to turn on verbose debug output +:: ::=^ * ames.nec +:: :: (ames-call:v ames.nec ~[/none] [%spew ~[%msg %snd %rcv %odd]] *roof) +:: ::=^ * ames.bud +:: :: (ames-call:v ames.bud ~[/none] [%spew ~[%msg %snd %rcv %odd]] *roof) +:: :: poke %sub to tell it to subscribe +:: =/ =task:gall [%deal [~nec ~nec] %sub %poke watch+!>(~bud)] +:: =^ t1 gall.nec +:: %: gall-check-call:v gall.nec +:: [~1111.1.1 0xdead.beef *roof] +:: [~[/foo] task] +:: :~ :- ~[/foo] [%give %unto %poke-ack ~] +:: :- ~[/init] +:: :* %pass /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud +:: [%g %deal [~nec ~bud] %pub %watch /foo] +:: == == +:: == +:: :- t1 |. :- %| +:: :: handle gall passing the %watch to itself, which passes to ames +:: =^ t2 gall.nec +:: %: gall-check-call:v gall.nec +:: [~1111.1.1 0xdead.beef *roof] +:: :- ~[/use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud /init] +:: [%deal [~nec ~bud] %pub %watch /foo] +:: :~ :- ~[/init] [%pass /sys/lag %a %heed ~bud] +:: :- ~[/init] [%pass /sys/era %j %public-keys (sy ~bud ~)] +:: :- ~[/use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud /init] +:: [%pass /sys/way/~bud/pub %a %plea ~bud %g /ge/pub [%0 %s /foo]] +:: == +:: == +:: :- t2 |. :- %| +:: :: subscriber ames handles %plea from gall, gives a packet to vere +:: =^ t3 ames.nec +:: %: ames-check-call:v ames.nec +:: [~1111.1.1 0xdead.beef *roof] +:: :- :~ /sys/way/~bud/pub +:: /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud +:: /init +:: == +:: [%plea ~bud %g /ge/pub [%0 %s /foo]] +:: :~ :- ~[//unix] +:: :* %give %send [%& ~bud] +:: 0xae59.5b29.277b.22c1.20b7.a8db.9086.46df.31bd.f9bc. +:: 2633.7300.17d4.f5fc.8be5.8bfe.5c9d.36d9.2ea1.7cb3. +:: 8a00.0200.0132.8fd4.f000 +:: == +:: :- ~[/ames] [%pass /pump/~bud/0 %b %wait ~1111.1.1..00.00.01] +:: == +:: == +:: :- t3 |. :- %| +:: :: publisher ames hears %watch, passes to gall +:: =^ t4 ames.bud +:: %: ames-check-call:v ames.bud +:: [~1111.1.2 0xbeef.dead *roof] +:: :- ~[//unix] +:: :* %hear [%& ~nec] +:: 0xae59.5b29.277b.22c1.20b7.a8db.9086.46df.31bd.f9bc. +:: 2633.7300.17d4.f5fc.8be5.8bfe.5c9d.36d9.2ea1.7cb3. +:: 8a00.0200.0132.8fd4.f000 +:: == +:: :~ :- ~[//unix] [%pass /qos %d %flog %text "; ~nec is your neighbor"] +:: :- ~[//unix] +:: [%pass /bone/~nec/0/1 %g %plea ~nec %g /ge/pub [%0 %s /foo]] +:: == +:: == +:: :- t4 |. :- %| +:: :: publisher gall hears %watch from ames, passes to itself +:: =^ t5 gall.bud +:: %: gall-check-call:v gall.bud +:: [~1111.1.2 0xbeef.dead *roof] +:: :- ~[/bone/~nec/0/1 //unix] +:: [%plea ~nec %g /ge/pub [%0 %s /foo]] +:: :~ :- ~[/init] [%pass /sys/lag %a %heed ~nec] +:: :- ~[/init] [%pass /sys/era %j %public-keys (sy ~nec ~)] +:: :- ~[/bone/~nec/0/1 //unix] +:: [%pass /sys/req/~nec/pub %g %deal [~nec ~bud] %pub %watch /foo] +:: == +:: == +:: :- t5 |. :- %| +:: :: publisher gall runs %pub with %watch, gives ack to itself +:: =^ t6 gall.bud +:: %: gall-check-call:v gall.bud +:: [~1111.1.2 0xbeef.dead *roof] +:: :- ~[/sys/req/~nec/pub /bone/~nec/0/1 //unix] +:: [%deal [~nec ~bud] %pub %watch /foo] +:: :~ :- ~[/sys/req/~nec/pub /bone/~nec/0/1 //unix] +:: [%give %unto %watch-ack ~] +:: == +:: == +:: :- t6 |. :- %| +:: :: gall gives ack to ames +:: =^ t7 gall.bud +:: %: gall-check-take:v gall.bud +:: [~1111.1.2 0xbeef.dead *roof] +:: :+ /sys/req/~nec/pub ~[/bone/~nec/0/1 //unix] +:: [%gall %unto %watch-ack ~] +:: :~ :- ~[/bone/~nec/0/1 //unix] [%give %done ~] +:: == +:: == +:: :- t7 |. :- %| +:: :: publisher ames hears ack from gall, sends over the network +:: =^ t8 ames.bud +:: %: ames-check-take:v ames.bud +:: [~1111.1.2 0xbeef.dead *roof] +:: :+ /bone/~nec/0/1 ~[//unix] +:: [%gall %done ~] +:: :~ :- ~[//unix] +:: :* %give %send [%& ~nec] +:: 0x2.0219.8100.0485.5530.3c88.9068.3cc6.484e. +:: 2d9d.076e.6d00.0100.0223.9ae9.5000 +:: == == +:: == +:: :- t8 |. :- %| +:: :: subscriber ames hears watch-ack packet, gives to gall +:: =^ t9 ames.nec +:: %: ames-check-call:v ames.nec +:: [~1111.1.3 0xdead.beef *roof] +:: :- ~[//unix] +:: :* %hear [%& ~bud] +:: 0x2.0219.8100.0485.5530.3c88.9068.3cc6.484e. +:: 2d9d.076e.6d00.0100.0223.9ae9.5000 +:: == +:: :~ :- ~[//unix] [%pass /qos %d %flog %text "; ~bud is your neighbor"] +:: :- :~ /sys/way/~bud/pub +:: /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud +:: /init +:: == +:: [%give %done ~] +:: :- ~[/ames] [%pass /pump/~bud/0 %b %rest ~1111.1.1..00.00.01] +:: == +:: == +:: :- t9 |. :- %| +:: :: gall gives %done to itself +:: =^ t10 gall.nec +:: %: gall-check-take:v gall.nec +:: [~1111.1.3 0xdead.beef *roof] +:: :+ /sys/way/~bud/pub +:: ~[/use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud /init] +:: [%ames %done ~] +:: :~ :- ~[/use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud /init] +:: [%give %unto %watch-ack ~] +:: == +:: == +:: :- t10 |. :- %| +:: :: gall gives watch-ack to itself +:: =^ t11 gall.nec +:: %: gall-check-take:v gall.nec +:: [~1111.1.3 0xdead.beef *roof] +:: :+ /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud +:: ~[/init] +:: [%gall %unto %watch-ack ~] +:: ~ +:: == +:: :- t11 |. :- %| +:: :: start the clog and kick process; give clog to publisher gall +:: =^ t12 gall.bud +:: %: gall-check-take:v gall.bud +:: [~1111.1.4 0xbeef.dead *roof] +:: :+ /sys/lag ~[/init] +:: [%ames %clog ~nec] +:: :~ :- ~[/sys/req/~nec/pub /bone/~nec/0/1 //unix] +:: [%give %unto %kick ~] +:: == +:: == +:: :- t12 |. :- %| +:: :: gall gives %kick %boon to ames +:: =^ t13 gall.bud +:: %: gall-check-take:v gall.bud +:: [~1111.1.4 0xbeef.dead *roof] +:: :+ /sys/req/~nec/pub ~[/bone/~nec/0/1 //unix] +:: [%gall %unto %kick ~] +:: :~ :- ~[/bone/~nec/0/1 //unix] [%give %boon %x ~] +:: == +:: == +:: :- t13 |. :- %| +:: :: ames gives kick over the network +:: =^ t14 ames.bud +:: %: ames-check-take:v ames.bud +:: [~1111.1.4 0xbeef.dead *roof] +:: :+ /bone/~nec/0/1 ~[//unix] +:: [%gall %boon %x ~] +:: :~ :- ~[//unix] +:: :* %give %send [%& ~nec] +:: 0xa1fc.cd35.c730.9a00.07e0.90a2.f87c.3657.935e. +:: 4ca0.801d.3ddc.d400.0100.0223.bc18.1000 +:: == +:: :- ~[/ames] [%pass /pump/~nec/1 %b %wait ~1111.1.4..00.00.01] +:: == +:: == +:: :- t14 |. :- %| +:: :: subscriber ames receives kick, gives to gall and gives ack to unix +:: =^ t15 ames.nec +:: %: ames-check-call:v ames.nec +:: [~1111.1.5 0xdead.beef *roof] +:: :- ~[//unix] +:: :* %hear [%& ~bud] +:: 0xa1fc.cd35.c730.9a00.07e0.90a2.f87c.3657.935e. +:: 4ca0.801d.3ddc.d400.0100.0223.bc18.1000 +:: == +:: :~ :- :~ /sys/way/~bud/pub +:: /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud +:: /init +:: == +:: [%give %boon %x ~] +:: :- ~[//unix] +:: :* %give %send [%& ~bud] +:: 0xfe.e208.da00.0491.bf7f.9594.2ddc.0948. +:: 9de0.3906.b678.6e00.0200.0132.e55d.5000 +:: == == +:: == +:: :- t15 |. :- %| +:: :: subscriber gall receives kick %boon from ames, gives to self +:: =^ t16 gall.nec +:: %: gall-check-take:v gall.nec +:: [~1111.1.5 0xdead.beef *roof] +:: :+ /sys/way/~bud/pub +:: ~[/use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud /init] +:: [%ames %boon %x ~] +:: :~ :- ~[/use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud /init] +:: [%give %unto %kick ~] +:: :- ~[/use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud /init] +:: [%pass /sys/way/~bud/pub %a %cork ~bud] +:: == +:: == +:: :: subscriber gall receives %kick from itself +:: =^ t17 gall.nec +:: %: gall-check-take:v gall.nec +:: [~1111.1.5 0xdead.beef *roof] +:: :+ /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud +:: ~[/init] +:: [%gall %unto %kick ~] +:: :~ :- ~[/init] +:: :* %pass /use/sub/0w1.d6Isf/out/~bud/pub/2/sub-foo/~bud +:: [%g %deal [~nec ~bud] %pub %watch /foo] +:: == == +:: == +:: :- t17 |. :- %| +:: :: gall receives %deal %watch from itself, passes to ames +:: =^ t18 gall.nec +:: %: gall-check-call:v gall.nec +:: [~1111.1.5 0xdead.beef *roof] +:: :- ~[/use/sub/0w1.d6Isf/out/~bud/pub/2/sub-foo/~bud /init] +:: [%deal [~nec ~bud] %pub %watch /foo] +:: :~ :- ~[/use/sub/0w1.d6Isf/out/~bud/pub/2/sub-foo/~bud /init] +:: [%pass /sys/way/~bud/pub %a %plea ~bud %g /ge/pub [%0 %s /foo]] +:: == +:: == +:: :- t18 |. :- %| +:: :: subscriber ames sends new %watch +:: =^ t19 ames.nec +:: %: ames-check-call:v ames.nec +:: [~1111.1.5 0xdead.beef *roof] +:: :- :~ /sys/way/~bud/pub +:: /use/sub/0w1.d6Isf/out/~bud/pub/2/sub-foo/~bud +:: /init +:: == +:: [%plea ~bud %g /ge/pub [%0 %s /foo]] +:: :~ :- ~[//unix] +:: :* %give %send [%& ~bud] +:: 0xfe.9174.6d7c.e042.4ea7.cf3c.08da.3acf.68ec.3bd1.1f2c.abfe.f500. +:: 1897.c42e.a3ec.2159.86d6.e2f1.b344.9d06.b600.0200.0132.ebe7.8800 +:: == +:: :- ~[/ames] [%pass /pump/~bud/4 %b %wait ~1111.1.5..00.00.01] +:: == +:: == +:: :- t19 |. :- %| +:: :: subscriber ames sends %cork +:: =^ t20 ames.nec +:: %: ames-check-call:v ames.nec +:: [~1111.1.5 0xdead.beef *roof] +:: :- :~ /sys/way/~bud/pub +:: /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud +:: /init +:: == +:: [%cork ~bud] +:: :~ :- ~[//unix] +:: :* %give %send [%& ~bud] +:: 0xb.130c.ab37.ca24.49cd.aecb.23ba.70f1.6f1c.4d00.124e.c9a5. +:: 3413.3843.d81c.47c4.7040.6e62.3700.0200.0132.e1ab.9000 +:: == +:: :- ~[/ames] [%pass /pump/~bud/0 %b %wait ~1111.1.5..00.02.00] +:: == +:: == +:: :: publisher ames hears %kick ack +:: :- t20 |. :- %| +:: =^ t21 ames.bud +:: %: ames-check-call:v ames.bud +:: [~1111.1.6 0xbeef.dead *roof] +:: :- ~[//unix] +:: :* %hear [%& ~nec] +:: 0xfe.e208.da00.0491.bf7f.9594.2ddc.0948. +:: 9de0.3906.b678.6e00.0200.0132.e55d.5000 +:: == +:: :~ :- ~[/ames] [%pass /pump/~nec/1 %b %rest ~1111.1.4..00.00.01] +:: == +:: == +:: :: publisher ames hears new %watch +:: :- t21 |. :- %| +:: =^ t22 ames.bud +:: %: ames-check-call:v ames.bud +:: [~1111.1.7 0xbeef.dead *roof] +:: :- ~[//unix] +:: :* %hear [%& ~nec] +:: 0xfe.9174.6d7c.e042.4ea7.cf3c.08da.3acf.68ec.3bd1.1f2c.abfe.f500. +:: 1897.c42e.a3ec.2159.86d6.e2f1.b344.9d06.b600.0200.0132.ebe7.8800 +:: == +:: :~ :- ~[//unix] +:: [%pass /bone/~nec/0/5 %g %plea ~nec %g /ge/pub [%0 %s /foo]] +:: == +:: == +:: :: publisher gall hears new %watch, passes to self +:: :- t22 |. :- %| +:: =^ t23 gall.bud +:: %: gall-check-call:v gall.bud +:: [~1111.1.7 0xbeef.dead *roof] +:: :- ~[/bone/~nec/0/5 //unix] +:: [%plea ~nec %g /ge/pub [%0 %s /foo]] +:: :~ :- ~[/bone/~nec/0/5 //unix] +:: [%pass /sys/req/~nec/pub %g %deal [~nec ~bud] %pub %watch /foo] +:: == +:: == +:: :: publisher gall runs :pub's +on-watch, gives ack to self +:: :- t23 |. :- %| +:: =^ t24 gall.bud +:: %: gall-check-call:v gall.bud +:: [~1111.1.7 0xbeef.dead *roof] +:: :- ~[/sys/req/~nec/pub /bone/~nec/0/5 //unix] +:: [%deal [~nec ~bud] %pub %watch /foo] +:: :~ :- ~[/sys/req/~nec/pub /bone/~nec/0/5 //unix] +:: [%give %unto %watch-ack ~] +:: == +:: == +:: :: publisher gall hears %watch-ack, gives to ames +:: :- t24 |. :- %| +:: =^ t25 gall.bud +:: %: gall-check-take:v gall.bud +:: [~1111.1.7 0xbeef.dead *roof] +:: :+ /sys/req/~nec/pub ~[/bone/~nec/0/5 //unix] +:: [%gall %unto %watch-ack ~] +:: :~ :- ~[/bone/~nec/0/5 //unix] [%give %done ~] +:: == +:: == +:: :: publisher ames hears done from gall, sends over the network +:: :- t25 |. :- %| +:: =^ t26 ames.bud +:: %: ames-check-take:v ames.bud +:: [~1111.1.7 0xbeef.dead *roof] +:: :+ /bone/~nec/0/5 ~[//unix] +:: [%gall %done ~] +:: :~ :- ~[//unix] +:: :* %give %send [%& ~nec] +:: 0x5f5.c27c.c400.0587.8b0d.0a5d.eb8e.39fa. +:: 49f4.4848.bfa6.f600.0100.0223.c98c.8800 +:: == == +:: == +:: :: publisher ames hears %cork, passes to itself +:: :- t26 |. :- %| +:: =^ t27 ames.bud +:: %: ames-check-call:v ames.bud +:: [~1111.1.8 0xbeef.dead *roof] +:: :- ~[//unix] +:: :* %hear [%& ~nec] +:: 0xb.130c.ab37.ca24.49cd.aecb.23ba.70f1.6f1c.4d00.124e.c9a5. +:: 3413.3843.d81c.47c4.7040.6e62.3700.0200.0132.e1ab.9000 +:: == +:: :~ :- ~[//unix] [%pass /bone/~nec/0/1 %a %plea ~nec [%a /close ~]] +:: == +:: == +:: :- t27 |. :- %| +:: :: publisher ames hear cork plea from self, give %done to self +:: =^ t28 ames.bud +:: %: ames-check-call:v ames.bud +:: [~1111.1.8 0xbeef.dead *roof] +:: :- ~[/bone/~nec/0/1 //unix] +:: [%plea ~nec [%a /close ~]] +:: :~ :- ~[/bone/~nec/0/1 //unix] [%give %done ~] +:: == +:: == +:: :: publisher ames hears cork done from self, sends ack packet +:: :- t28 |. :- %| +:: =^ t29 ames.bud +:: %: ames-check-take:v ames.bud +:: [~1111.1.8 0xbeef.dead *roof] +:: :+ /bone/~nec/0/1 +:: ~[//unix] +:: [%ames %done ~] +:: :~ :- ~[//unix] +:: :* %give %send [%& ~nec] +:: 0x5f.f966.8e00.0449.bdec.9006.c7e5.1237. +:: 1d87.53fe.d7bb.ad00.0100.0223.c6a8.5800 +:: == == +:: == +:: :: subscriber ames hears %watch-ack, gives to gall +:: :- t29 |. :- %| +:: =^ t30 ames.nec +:: %: ames-check-call:v ames.nec +:: [~1111.1.9 0xdead.beef *roof] +:: :- ~[//unix] +:: :* %hear [%& ~bud] +:: 0x5f5.c27c.c400.0587.8b0d.0a5d.eb8e.39fa. +:: 49f4.4848.bfa6.f600.0100.0223.c98c.8800 +:: == +:: :~ :- :~ /sys/way/~bud/pub +:: /use/sub/0w1.d6Isf/out/~bud/pub/2/sub-foo/~bud +:: /init +:: == +:: [%give %done ~] +:: :- ~[/ames] [%pass /pump/~bud/4 %b %rest ~1111.1.5..00.00.01] +:: == +:: == +:: :: subscriber gall hears new %watch-ack from ames, gives to self +:: :- t30 |. :- %| +:: =^ t31 gall.nec +:: %: gall-check-take:v gall.nec +:: [~1111.1.9 0xdead.beef *roof] +:: :+ /sys/way/~bud/pub +:: :~ /use/sub/0w1.d6Isf/out/~bud/pub/2/sub-foo/~bud +:: /init +:: == +:: [%ames %done ~] +:: :~ :- :~ /use/sub/0w1.d6Isf/out/~bud/pub/2/sub-foo/~bud +:: /init +:: == +:: [%give %unto %watch-ack ~] +:: == +:: == +:: :: subscriber gall hears new %watch-ack from self, tells :sub +:: :- t31 |. :- %| +:: =^ t32 gall.nec +:: %: gall-check-take:v gall.nec +:: [~1111.1.9 0xdead.beef *roof] +:: :+ /use/sub/0w1.d6Isf/out/~bud/pub/2/sub-foo/~bud +:: ~[/init] +:: [%gall %unto %watch-ack ~] +:: ~ +:: == +:: :: subscriber ames hears %cork ack +:: :- t32 |. :- %| +:: =^ t33 ames.nec +:: %: ames-check-call:v ames.nec +:: [~1111.1.10 0xdead.beef *roof] +:: :- ~[//unix] +:: :* %hear [%& ~bud] +:: 0x5f.f966.8e00.0449.bdec.9006.c7e5.1237. +:: 1d87.53fe.d7bb.ad00.0100.0223.c6a8.5800 +:: == +:: :~ :- :~ /sys/way/~bud/pub +:: /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud +:: /init +:: == +:: [%give %done ~] +:: :- ~[/ames] [%pass /pump/~bud/0 %b %rest ~1111.1.5..00.02.00] +:: == +:: == +:: :: subscriber gall hears %cork ack from ames +:: :- t33 |. :- %| +:: =^ t34 gall.nec +:: %: gall-check-take:v gall.nec +:: [~1111.1.10 0xdead.beef *roof] +:: :+ /sys/way/~bud/pub +:: :~ /use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud +:: /init +:: == +:: [%ames %done ~] +:: ~ +:: == +:: :- t34 |. :- %& +:: ;: weld +:: %+ expect-eq +:: !> (sy 0 ~) +:: !> =< corked +:: %: ames-scry-peer:v +:: ames.nec +:: [~1111.1.10 0xdead.beef *roof] +:: [~nec ~bud] +:: == +:: :: +:: %+ expect-eq +:: !> (sy 1 ~) +:: !> =< corked +:: %: ames-scry-peer:v +:: ames.bud +:: [~1111.1.8 0xbeef.dead *roof] +:: [~bud ~nec] +:: == +:: :: +:: %+ expect-eq +:: !> 2 +:: !> %: gall-scry-nonce:v +:: gall.nec +:: [~1111.1.10 0xdead.beef *roof] +:: ~nec %sub +:: [~bud %pub /sub-foo/~bud] +:: == +:: == +:: -- +~ diff --git a/pkg/arvo/tests/sys/vane/ames.hoon b/pkg/arvo/tests/sys/vane/ames.hoon index bca47314d..bf9b32119 100644 --- a/pkg/arvo/tests/sys/vane/ames.hoon +++ b/pkg/arvo/tests/sys/vane/ames.hoon @@ -251,17 +251,19 @@ !> shut-packet !> decoded :: -++ test-shut-packet-associated-data ^- tang - :: - =/ =shut-packet:ames - :+ bone=17 message-num=18 - [%& num-fragments=1 fragment-num=1 fragment=`@`0xdead.beef] - :: - =/ =packet:ames - (encode-shut-packet:ames shut-packet nec-sym ~marnec ~marbud-marbud 3 1) - :: - %- expect-fail - |.((decode-shut-packet:ames packet nec-sym 3 17)) +:: Crypto failures are now non-deterministic +:: +:: ++ test-shut-packet-associated-data ^- tang +:: :: +:: =/ =shut-packet:ames +:: :+ bone=17 message-num=18 +:: [%& num-fragments=1 fragment-num=1 fragment=`@`0xdead.beef] +:: :: +:: =/ =packet:ames +:: (encode-shut-packet:ames shut-packet nec-sym ~marnec ~marbud-marbud 3 1) +:: :: +:: %- expect-fail +:: |.((decode-shut-packet:ames packet nec-sym 3 17)) :: ++ test-alien-encounter ^- tang :: diff --git a/pkg/arvo/tests/sys/vane/gall.hoon b/pkg/arvo/tests/sys/vane/gall.hoon index 43b8569d3..73469503d 100644 --- a/pkg/arvo/tests/sys/vane/gall.hoon +++ b/pkg/arvo/tests/sys/vane/gall.hoon @@ -22,32 +22,6 @@ (gall-call gall-gate time *roof call-args expected-moves) :: -.res -:: +test-jolt: test %jolt; TODO: test clay response -:: -++ test-jolt - ^- tang - :: - =/ =duct ~[/init] - =/ time (add ~1111.1.1 ~s1) - =/ dap=term %my-agent - =/ ship ~nec - :: - =/ call-args - =/ =task:gall [%jolt %base dap] - [duct task] - :: - =/ =move:gall-gate - =/ =wire /sys/cor/[dap]/(scot %p ship)/base/(scot %da time) - =/ =note-arvo - [%c %warp ship %base ~ %sing %a da+time /app/[dap]/hoon] - [duct %pass wire note-arvo] - :: - =/ expected-moves=(list move:gall-gate) ~[move] - :: - =/ res - (gall-call gall-gate time *roof call-args expected-moves) - :: - -.res :: +gall-call: have %gall run a +task and assert it produces expected-moves :: ++ gall-call diff --git a/pkg/base-dev/lib/agentio.hoon b/pkg/base-dev/lib/agentio.hoon index d07c57dd1..5ab007361 100644 --- a/pkg/base-dev/lib/agentio.hoon +++ b/pkg/base-dev/lib/agentio.hoon @@ -85,6 +85,9 @@ ?:(?=(%sing genre) [genre mood] [genre mood]) (warp-our q.byk.bowl `rave) :: + ++ tire + (arvo %c %tire `~) + :: ++ connect |= [=binding:eyre app=term] (arvo %e %connect binding app) diff --git a/pkg/base-dev/lib/story.hoon b/pkg/base-dev/lib/story.hoon index 8cb3c2a93..d216d41a6 100644 --- a/pkg/base-dev/lib/story.hoon +++ b/pkg/base-dev/lib/story.hoon @@ -38,41 +38,17 @@ :: :: Canonical textual representation :: -++ tako-to-text - |= [=tako:clay] - ^- tape - "commit: {<`@uv`tako>}\0a" -:: -++ proses-to-text - |= [=proses] - ^- tape - =/ proses-list=(list prose) ~(tap in proses) - ?: ?=(~ proses-list) "" - ?: ?=([prose ~] proses-list) - (prose-to-text i.proses-list) - %- tail - %^ spin `(list prose)`t.proses-list - (prose-to-text i.proses-list) - |= [prz=prose state=tape] - ^- [prose tape] - :- prz - ;: welp - state - "|||" - "\0a" - (prose-to-text prz) - == -:: -++ prose-to-text - |= prz=prose - =/ [title=@t body=@t] prz - ^- tape - ;: welp - "{(trip title)}" - "\0a\0a" - "{(trip body)}" - "\0a" - == +++ chapter-to-text + |= [=tako:clay =proses] + ^- wain + :- (crip "commit: {<`@uv`tako>}") + %- zing + %+ join `wain`~['|||'] + %+ turn ~(tap in proses) + |= prose + ^- wain + %- to-wain:format + (rap 3 title '\0a\0a' body ~) :: :: Parsers :: diff --git a/pkg/base-dev/lib/strand.hoon b/pkg/base-dev/lib/strand.hoon index d49260225..b0db35b27 100644 --- a/pkg/base-dev/lib/strand.hoon +++ b/pkg/base-dev/lib/strand.hoon @@ -1,188 +1 @@ -|% -+$ card card:agent:gall -+$ input - $% [%poke =cage] - [%sign =wire =sign-arvo] - [%agent =wire =sign:agent:gall] - [%watch =path] - == -+$ strand-input [=bowl in=(unit input)] -+$ tid @tatid -+$ bowl - $: our=ship - src=ship - tid=tid - mom=(unit tid) - wex=boat:gall - sup=bitt:gall - eny=@uvJ - now=@da - byk=beak - == -:: -:: cards: cards to send immediately. These will go out even if a -:: later stage of the computation fails, so they shouldn't have -:: any semantic effect on the rest of the system. -:: Alternately, they may record an entry in contracts with -:: enough information to undo the effect if the computation -:: fails. -:: wait: don't move on, stay here. The next sign should come back -:: to this same callback. -:: skip: didn't expect this input; drop it down to be handled -:: elsewhere -:: cont: continue computation with new callback. -:: fail: abort computation; don't send effects -:: done: finish computation; send effects -:: -++ strand-output-raw - |* a=mold - $~ [~ %done *a] - $: cards=(list card) - $= next - $% [%wait ~] - [%skip ~] - [%cont self=(strand-form-raw a)] - [%fail err=(pair term tang)] - [%done value=a] - == - == -:: -++ strand-form-raw - |* a=mold - $-(strand-input (strand-output-raw a)) -:: -:: Abort strand computation with error message -:: -++ strand-fail - |= err=(pair term tang) - |= strand-input - [~ %fail err] -:: -:: Asynchronous transcaction monad. -:: -:: Combo of four monads: -:: - Reader on input -:: - Writer on card -:: - Continuation -:: - Exception -:: -++ strand - |* a=mold - |% - ++ output (strand-output-raw a) - :: - :: Type of an strand computation. - :: - ++ form (strand-form-raw a) - :: - :: Monadic pure. Identity computation for bind. - :: - ++ pure - |= arg=a - ^- form - |= strand-input - [~ %done arg] - :: - :: Monadic bind. Combines two computations, associatively. - :: - ++ bind - |* b=mold - |= [m-b=(strand-form-raw b) fun=$-(b form)] - ^- form - |= input=strand-input - =/ b-res=(strand-output-raw b) - (m-b input) - ^- output - :- cards.b-res - ?- -.next.b-res - %wait [%wait ~] - %skip [%skip ~] - %cont [%cont ..$(m-b self.next.b-res)] - %fail [%fail err.next.b-res] - %done [%cont (fun value.next.b-res)] - == - :: - :: The strand monad must be evaluted in a particular way to maintain - :: its monadic character. +take:eval implements this. - :: - ++ eval - |% - :: Indelible state of a strand - :: - +$ eval-form - $: =form - == - :: - :: Convert initial form to eval-form - :: - ++ from-form - |= =form - ^- eval-form - form - :: - :: The cases of results of +take - :: - +$ eval-result - $% [%next ~] - [%fail err=(pair term tang)] - [%done value=a] - == - :: - ++ validate-mark - |= [in=* =mark =bowl] - ^- cage - =+ .^ =dais:clay %cb - /(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/[mark] - == - =/ res (mule |.((vale.dais in))) - ?: ?=(%| -.res) - ~|(%spider-mark-fail (mean leaf+"spider: ames vale fail {}" p.res)) - [mark p.res] - :: - :: Take a new sign and run the strand against it - :: - ++ take - :: cards: accumulate throughout recursion the cards to be - :: produced now - =| cards=(list card) - |= [=eval-form =strand-input] - ^- [[(list card) =eval-result] _eval-form] - =* take-loop $ - =. in.strand-input - ?~ in.strand-input ~ - =/ in u.in.strand-input - ?. ?=(%agent -.in) `in - ?. ?=(%fact -.sign.in) `in - :: - :- ~ - :+ %agent wire.in - [%fact (validate-mark q.q.cage.sign.in p.cage.sign.in bowl.strand-input)] - :: run the strand callback - :: - =/ =output (form.eval-form strand-input) - :: add cards to cards - :: - =. cards - %+ welp - cards - :: XX add tag to wires? - cards.output - :: case-wise handle next steps - :: - ?- -.next.output - %wait [[cards %next ~] eval-form] - %skip [[cards %next ~] eval-form] - %fail [[cards %fail err.next.output] eval-form] - %done [[cards %done value.next.output] eval-form] - %cont - :: recurse to run continuation with initialization input - :: - %_ take-loop - form.eval-form self.next.output - strand-input [bowl.strand-input ~] - == - == - -- - -- --- -:: +rand diff --git a/pkg/base-dev/lib/test.hoon b/pkg/base-dev/lib/test.hoon index e0e6f9fa7..c5947b256 100644 --- a/pkg/base-dev/lib/test.hoon +++ b/pkg/base-dev/lib/test.hoon @@ -50,9 +50,11 @@ %& ~ %| ['expected success - failed' p.b] == -:: $test-chain: a sequence of tests to be run +:: $a-test-chain: a sequence of tests to be run :: -+$ test-chain +:: NB: arms shouldn't start with `test-` so that `-test % ~` runs +:: ++$ a-test-chain $_ |? ?: =(0 0) @@ -61,7 +63,7 @@ :: +run-chain: run a sequence of tests, stopping at first failure :: ++ run-chain - |= seq=test-chain + |= seq=a-test-chain ^- tang =/ res $:seq ?- -.res diff --git a/pkg/base-dev/mar/kelvin.hoon b/pkg/base-dev/mar/kelvin.hoon index f64063d18..7f1b409cb 100644 --- a/pkg/base-dev/mar/kelvin.hoon +++ b/pkg/base-dev/mar/kelvin.hoon @@ -1,18 +1,28 @@ -=/ weft ,[lal=@tas num=@ud] :: TODO remove after merge -|_ kel=weft +|_ kal=waft:clay ++ grow |% ++ mime `^mime`[/text/x-kelvin (as-octs:mimes:html hoon)] - ++ noun kel - ++ hoon (crip "{<[lal num]:kel>}\0a") + ++ noun kal + ++ hoon + %+ rap 3 + %+ turn + %+ sort + ~(tap in (waft-to-wefts:clay kal)) + |= [a=weft b=weft] + ?: =(lal.a lal.b) + (gte num.a num.b) + (gte lal.a lal.b) + |= =weft + (rap 3 '[%' (scot %tas lal.weft) ' ' (scot %ud num.weft) ']\0a' ~) + :: ++ txt (to-wain:format hoon) -- ++ grab |% - ++ noun weft + ++ noun waft:clay ++ mime |= [=mite len=@ud tex=@] - !<(weft (slap !>(~) (ream tex))) + (cord-to-waft:clay tex) -- ++ grad %noun -- diff --git a/pkg/base-dev/mar/story.hoon b/pkg/base-dev/mar/story.hoon index bf07ac742..70704efce 100644 --- a/pkg/base-dev/mar/story.hoon +++ b/pkg/base-dev/mar/story.hoon @@ -46,18 +46,13 @@ [/text/x-urb-story (as-octs:mimes:html (of-wain:format txt))] ++ txt ^- wain - %- snoc :_ '' :: ensures terminating newline is present + %- zing + %+ join `wain`~['---'] %+ murn ~(tap by tale) - |= [[=tako:clay =proses]] - ^- (unit cord) + |= [=tako:clay =proses] + ^- (unit wain) ?~ proses ~ - %- some - %- crip - ;: welp - (tako-to-text tako) - (proses-to-text proses) - "---" - == + (some (chapter-to-text tako proses)) -- ++ grab |% :: convert from diff --git a/pkg/base-dev/sur/hood.hoon b/pkg/base-dev/sur/hood.hoon index d1087a05b..785ea6abb 100644 --- a/pkg/base-dev/sur/hood.hoon +++ b/pkg/base-dev/sur/hood.hoon @@ -1,147 +1,125 @@ =, clay =* dude dude:gall |% -:: $snap: kiln snapshot -:: -+$ snap (map desk arak) -:: $diff: subscription update -:: -+$ diff - $% [%block =desk =arak =weft blockers=(set desk)] - [%reset =desk =arak] - [%commit =desk =arak] - [%merge-sunk =desk =arak =tang] - [%merge-fail =desk =arak =tang] - [%suspend =desk =arak] - [%revive =desk =arak] ++$ pike + $: sync=(unit [=ship =desk]) + hash=@uv + =zest + wic=(set weft) == -:: $arak: foreign vat tracker :: -:: .rail: upstream tracking state, if any -:: .rein: configuration for agents ++$ pikes (map desk pike) :: -+$ arak - $: rail=(unit rail) - =rein - == -:: $rail: upstream tracking state -:: -:: .publisher: Ship that originally published desk, if available -:: .paused: is tracking paused? or live -:: .ship: upstream ship (could be .our) -:: .desk: name of upstream desk -:: .aeon: next aeon to pull from upstream -:: .next: list of pending commits with future kelvins -:: -+$ rail - $: publisher=(unit ship) - paused=? - =ship - =desk - =aeon - next=(list rung) - == :: $rung: reference to upstream commit :: +$ rung [=aeon =weft] -:: $rein: diff from desk manifest :: -:: .liv: suspended? if suspended, no agents should run -:: .add: agents not in manifest that should be running -:: .sub: agents in manifest that should not be running ++$ sync-state [nun=@ta kid=(unit desk) let=@ud] ++$ sink (unit [her=@p sud=desk kid=(unit desk) let=@ud]) +:: +report-prep: get data required for reports :: -+$ rein - $: liv=_& - add=(set dude) - sub=(set dude) +++ report-prep + |= [our=@p now=@da] + =/ ego (scot %p our) + =/ wen (scot %da now) + :* .^(rock:tire %cx /(scot %p our)//(scot %da now)/tire) + .^(=cone %cx /(scot %p our)//(scot %da now)/domes) + .^((map desk [ship desk]) %gx /[ego]/hood/[wen]/kiln/sources/noun) + .^ (map [desk ship desk] sync-state) %gx + /[ego]/hood/[wen]/kiln/syncs/noun + == == -:: -+$ vat [=desk hash=@uv =cass =arak] :: +report-vats: report on all desk installations :: ++ report-vats |= [our=@p now=@da] ^- tang - =+ .^ raz=(list vat) - %gx /(scot %p our)/hood/(scot %da now)/kiln/vats/noun - == - :- (report-kids our now) - (turn raz |=(v=vat (report-vat our now v))) + =/ desks .^((set desk) %cd /(scot %p our)/base/(scot %da now)) + =/ prep (report-prep our now) + %+ turn ~(tap in desks) + |=(syd=desk (report-vat prep our now syd)) :: +report-vat: report on a single desk installation :: ++ report-vat - |= [our=ship now=@da vat] + |= $: $: tyr=rock:tire =cone sor=(map desk [ship desk]) + zyn=(map [desk ship desk] sync-state) + == + our=ship now=@da syd=desk + == ^- tank + =/ ego (scot %p our) + =/ wen (scot %da now) + =+ .^(=cass %cw /[ego]/[syd]/[wen]) ?: =(ud.cass 0) - leaf+"desk does not yet exist: {}" + leaf+"desk does not yet exist: {}" + ?: =(%kids syd) + =+ .^(hash=@uv %cz /[ego]/[syd]/[wen]) + leaf+"%kids %cz hash: {}" =/ kel-path - /(scot %p our)/[desk]/(scot %da now)/sys/kelvin + /[ego]/[syd]/[wen]/sys/kelvin ?. .^(? %cu kel-path) - leaf+"bad desk: {}" - =+ .^(=weft %cx kel-path) - :+ %rose ["" "{}" "::"] + leaf+"bad desk: {}" + =+ .^(=waft %cx kel-path) + :+ %rose ["" "{}" "::"] ^- tang - =/ meb (mergebase-hashes our desk now arak) - =/ poz - ?~ rail.arak "local" - ?:(paused.u.rail.arak "paused" "tracking") - =/ sat ?:(liv.rein.arak "running" "suspended") - =/ pen - ?~ rail.arak "~" - <(turn next.u.rail.arak |=([@ lal=@tas num=@] [lal num]))> - :~ leaf/"/sys/kelvin: {<[lal num]:weft>}" + =/ hash .^(@uv %cz /[ego]/[syd]/[wen]) + =/ =sink + ?~ s=(~(get by sor) syd) + ~ + ?~ z=(~(get by zyn) syd u.s) + ~ + `[-.u.s +.u.s +.u.z] + =/ meb=(list @uv) + ?~ sink [hash]~ + (mergebase-hashes our syd now her.u.sink sud.u.sink) + =/ dek (~(got by tyr) syd) + =/ =foam (~(got by cone) our syd) + =/ [on=(list [@tas ?]) of=(list [@tas ?])] + (skid ~(tap by ren.foam) |=([* ?] +<+)) + =/ sat + ?- zest.dek + %live "running" + %dead "suspended" + %held "suspended until next update" + == + =/ kul=tape + %+ roll + %+ sort + ~(tap in (waft-to-wefts:clay waft)) + |= [a=weft b=weft] + ?: =(lal.a lal.b) + (lte num.a num.b) + (lte lal.a lal.b) + |= [=weft =tape] + (welp " {<[lal num]:weft>}" tape) + :~ leaf/"/sys/kelvin: {kul}" leaf/"base hash: {?.(=(1 (lent meb)) <(head meb)>)}" leaf/"%cz hash: {}" :: leaf/"app status: {sat}" - leaf/"force on: {?:(=(~ add.rein.arak) "~" )}" - leaf/"force off: {?:(=(~ sub.rein.arak) "~" )}" + leaf/"force on: {?:(=(~ on) "~" )}" + leaf/"force off: {?:(=(~ of) "~" )}" :: - leaf/"publishing ship: {?~(rail.arak <~> )}" - leaf/"updates: {poz}" - leaf/"source ship: {?~(rail.arak <~> )}" - leaf/"source desk: {?~(rail.arak <~> )}" - leaf/"source aeon: {?~(rail.arak <~> )}" - leaf/"pending updates: {pen}" + leaf/"publishing ship: {?~(sink <~> <(get-publisher our syd now)>)}" + leaf/"updates: {?~(sink "local" "remote")}" + leaf/"source ship: {?~(sink <~> )}" + leaf/"source desk: {?~(sink <~> )}" + leaf/"source aeon: {?~(sink <~> )}" + leaf/"kids desk: {?~(sink <~> ?~(kid.u.sink <~> ))}" + leaf/"pending updates: {<`(list [@tas @ud])`~(tap in wic.dek)>}" == :: +report-kids: non-vat cz hash report for kids desk :: ++ report-kids |= [our=ship now=@da] ^- tank - =/ dek %kids + =/ syd %kids =/ ego (scot %p our) =/ wen (scot %da now) - ?. (~(has in .^((set desk) %cd /[ego]//[wen])) dek) + ?. (~(has in .^((set desk) %cd /[ego]//[wen])) syd) leaf/"no %kids desk" - =+ .^(hash=@uv %cz /[ego]/[dek]/[wen]) + =+ .^(hash=@uv %cz /[ego]/[syd]/[wen]) leaf/"%kids %cz hash: {}" -:: +read-kelvin-foreign: read /sys/kelvin from a foreign desk -:: -++ read-kelvin-foreign - |= [=ship =desk =aeon] - ^- weft - ~| read-foreign-kelvin/+< - =/ her (scot %p ship) - =/ syd (scot %tas desk) - =/ yon (scot %ud aeon) - :: - =/ dom .^(dome cv/~[her syd yon]) - =/ tak (scot %uv (~(got by hit.dom) let.dom)) - =/ yak .^(yaki cs/~[her syd yon %yaki tak]) - =/ lob (scot %uv (~(got by q.yak) /sys/kelvin)) - =/ peg .^(page cs/~[her syd yon %blob lob]) - ;;(weft q.peg) -:: +read-kelvin-local: read /sys/kelvin from a local desk -:: -++ read-kelvin-local - |= [our=ship =desk now=@da] - ^- (unit weft) - ~| read-kelvin-local+desk - =/ pax (en-beam [our desk da+now] /sys/kelvin) - ?. .^(? cu/pax) - ~ - [~ .^(weft cx/pax)] :: +read-bill-foreign: read /desk/bill from a foreign desk :: ++ read-bill-foreign @@ -169,21 +147,6 @@ ?. .^(? cu/pax) *(list dude) .^((list dude) cx/pax) -:: +adjust-dudes: which agents should be started and stopped -:: -:: Will ask Gall to start agents that it's already running -:: but that should be ok, and might be safer in case other -:: unprocessed moves would have turned them off. -:: -++ adjust-dudes - |= $: local=[our=ship =desk now=@da] - =rein - == - ^- [jolt=(list dude) idle=(list dude)] - =/ all=(list dude) (read-bill local) - =/ want (get-apps-want local all rein) - =/ have (get-apps-live local) - [want (skip have ~(has in (sy want)))] :: ++ get-remote-diff |= [our=ship here=desk now=@da her=ship there=desk when=aeon] @@ -210,38 +173,18 @@ ^- (list [=dude live=?]) %~ tap in .^((set [=dude live=?]) ge+/(scot %p our)/[desk]/(scot %da now)) -:: +get-apps-want: find which apps should be running on a desk -:: -++ get-apps-want - |= [local=[our=ship =desk now=@da] duz=(list dude) =rein] - ^- (list dude) - ?. liv.rein ~ - ?. |(=(`zuse+zuse (read-kelvin-local local)) =(%base desk.local)) ~ - =. duz (skip duz ~(has in sub.rein)) - =. duz (weld duz (skip ~(tap in add.rein) ~(has in (sy duz)))) - duz :: ++ mergebase-hashes - |= [our=@p =desk now=@da =arak] - ?~ rail.arak - ~ - =/ her (scot %p ship.u.rail.arak) + |= [our=@p syd=desk now=@da her=ship sud=desk] + =/ her (scot %p her) =/ ego (scot %p our) =/ wen (scot %da now) - %+ turn .^((list tako) %cs ~[ego desk wen %base her desk.u.rail.arak]) - |=(=tako .^(@uv %cs ~[ego desk wen %hash (scot %uv tako)])) + %+ turn .^((list tako) %cs ~[ego syd wen %base her sud]) + |=(=tako .^(@uv %cs ~[ego syd wen %hash (scot %uv tako)])) :: ++ enjs =, enjs:format |% - ++ vats - |= v=(list ^vat) - ^- json - %- pairs - %+ turn v - |= va=^vat - [desk.va (vat va)] - :: ++ tim |= t=@ ^- json @@ -254,15 +197,6 @@ da+(tim da.c) == :: - ++ vat - |= v=^vat - %- pairs - :~ desk+s+desk.v - hash+s+(scot %uv hash.v) - cass+(cass cass.v) - arak+(arak arak.v) - == - :: ++ weft |= w=^weft %- pairs @@ -276,30 +210,5 @@ :~ aeon+(numb aeon.r) weft+(weft weft.r) == - :: - ++ rein - |= r=^rein - %- pairs - :~ add+a+(turn ~(tap in add.r) (lead %s)) - sub+a+(turn ~(tap in sub.r) (lead %s)) - == - :: - ++ arak - |= a=^arak - %- pairs - :~ rail+?~(rail.a ~ (rail u.rail.a)) - rein+(rein rein.a) - == - :: - ++ rail - |= r=^rail - %- pairs - :~ ship+s+(scot %p ship.r) - publisher+?~(publisher.r ~ s+(scot %p u.publisher.r)) - desk+s+desk.r - paused+b+paused.r - aeon+(numb aeon.r) - next+a+(turn next.r rung) - == -- -- diff --git a/pkg/base-dev/sur/spider.hoon b/pkg/base-dev/sur/spider.hoon index 2a6a8207e..7c212681f 100644 --- a/pkg/base-dev/sur/spider.hoon +++ b/pkg/base-dev/sur/spider.hoon @@ -1,7 +1,7 @@ /+ libstrand=strand =, strand=strand:libstrand |% -+$ thread $-(vase _*form:(strand ,vase)) ++$ thread $-(vase shed:khan) +$ input [=tid =cage] +$ tid tid:strand +$ bowl bowl:strand @@ -18,4 +18,10 @@ file=term =vase == ++$ inline-args + $: parent=(unit tid) + use=(unit tid) + =beak + =shed:khan + == -- diff --git a/pkg/bitcoin/sys.kelvin b/pkg/bitcoin/sys.kelvin index e77a3de08..b7bcb9ecd 100644 --- a/pkg/bitcoin/sys.kelvin +++ b/pkg/bitcoin/sys.kelvin @@ -1 +1 @@ -[%zuse 418] +[%zuse 417] diff --git a/pkg/btc-wallet/package-lock.json b/pkg/btc-wallet/package-lock.json index 260cc52c4..35beb1357 100644 Binary files a/pkg/btc-wallet/package-lock.json and b/pkg/btc-wallet/package-lock.json differ diff --git a/pkg/garden/app/docket.hoon b/pkg/garden/app/docket.hoon index 6dec08cf7..54e595a69 100644 --- a/pkg/garden/app/docket.hoon +++ b/pkg/garden/app/docket.hoon @@ -3,7 +3,7 @@ |% +$ card card:agent:gall +$ app-state - $: %2 + $: %3 :: local charges=(map desk charge) == @@ -42,7 +42,7 @@ ++ on-init ^- (quip card _this) :_ this - :~ (~(watch-our pass /kiln) %hood /kiln/vats) + :~ ~(tire pass /tire) (~(connect pass /eyre) [~ /] %docket) (~(wait pass /init) (add 1 now.bowl)) (~(connect pass /eyre) [~ /apps] %docket) @@ -54,20 +54,21 @@ |^ =+ !<(old=app-states vase) =? old ?=(?(~ ^) -.old) [%1 old] - =^ cards old + =^ cards-1 old ?. ?=(%1 -.old) `old - =/ rein=cage kiln-rein+!>([%base %.y ~ ~]) - =/ nuke=cage kiln-uninstall+!>(%hodl) - :_ old(- %2) - :~ [%pass /rein %agent [our.bowl %hood] %poke rein] - [%pass /nuke %agent [our.bowl %hood] %poke nuke] - == - ?> ?=(%2 -.old) + `old(- %2) + =^ cards-2 old + ?. ?=(%2 -.old) `old + :_ old(- %3) :_ ~ + ~(tire pass /tire) + ?> ?=(%3 -.old) + =/ cards-tire [~(tire pass /tire) ~] =. -.state old :: inflate-cache needs to be called after the state is set :: =. +.state inflate-cache - [cards this] + [:(weld cards-1 cards-2 cards-tire) this] + :: ++ inflate-cache ^- cache @@ -81,9 +82,11 @@ $^ state-0-ket $% state-0-sig state-1 + state-2 app-state == :: + +$ state-2 [%2 (map desk charge)] +$ state-1 [%1 (map desk charge)] +$ state-0-sig $: ~ @@ -94,6 +97,7 @@ == -- :: + ++ on-save !>(-.state) ++ on-poke |= [=mark =vase] @@ -189,13 +193,21 @@ == :: [%x %charges ~] + =/ tyr + .^(rock:tire:clay %cx /(scot %p our.bowl)//(scot %da now.bowl)/tire) :- ~ :- ~ %- charge-update:cg :- %initial %- ~(gas by *(map desk charge)) - %+ turn ~(tap by charges) + %+ murn ~(tap by charges) |= [=desk =charge] - [desk (get-light-charge charge)] + ?~ got=(~(get by tyr) desk) + ~ + ?: ?& ?=(%dead zest.u.got) + ?=(~ (get-apps-have:hood our.bowl desk now.bowl)) + == + ~ + `u=[desk (get-light-charge charge)] :: [%x %charges @ %version ~] ?~ charge=(~(get by charges) i.t.t.path) @@ -212,114 +224,11 @@ ~ `state [%rein ~] ~&(%reined `state) [%nuke ~] ~&(%nuked `state) - [%kiln ~] take-kiln + [%kiln ~] `state [%charge @ *] (take-charge i.t.wire t.t.wire) == [cards this] :: - ++ take-kiln - ^- (quip card _state) - ?+ -.sign (on-agent:def:cc wire sign) - %kick [(~(watch-our pass /kiln) %hood /kiln/vats)^~ state] - %fact - |^ ^- (quip card _state) - ?+ p.cage.sign ~|(take-kiln-mark/p.cage.sign !!) - %kiln-vats-snap-0 (on-snap !<(snap:hood q.cage.sign)) - %kiln-vats-diff-0 (on-diff !<(diff:hood q.cage.sign)) - == - :: - ++ on-snap - |= =snap:hood - ^- (quip card _state) - =| fex=(list card) - =/ ark ~(tap by snap) - |- ^- (quip card _state) - ?~ ark [(flop fex) state] - =^ caz state (on-commit i.ark) - $(ark t.ark, fex (weld (flop caz) fex)) - :: - ++ on-diff - |= =diff:hood - =+ !<(=diff:hood q.cage.sign) - ?- -.diff - %commit (on-commit [desk arak]:diff) - %suspend (on-suspend [desk arak]:diff) - %revive (on-revive [desk arak]:diff) - ?(%block %reset %merge-sunk %merge-fail) - `state - == - :: - ++ on-commit - |= [=desk =arak:hood] - ^- (quip card _state) - =* cha ~(. ch desk) - ?. docket-exists:cha - ~? ?& !=(%base desk) - !=(%kids desk) - == - [dap.bowl %no-docket-file-for desk] - `state - :: always update the docket in state to match clay's - :: - =/ =docket docket:cha - =/ pre=(unit charge) (~(get by charges) desk) - =. charges (new-docket:cha docket) - :: if the new chad is a site, we're instantly done - :: - ?: ?=(%site -.href.docket) - =. charges (new-chad:cha %site ~) - :- ~[add-fact:cha] - state - :: - =. by-base (~(put by by-base) base.href.docket desk) - :: if the glob specification is unchanged, keep it - :: - ?: &(?=(^ pre) =(href.docket.u.pre href.docket) ?=(%glob -.chad.u.pre)) - [~[add-fact:cha] state] - :: if the glob spec changed, but we already host it, keep it - :: (this is the "just locally uploaded" case) - :: - ?: ?& ?=(^ pre) - ?=(%glob -.chad.u.pre) - :: - .= [(sham glob.chad.u.pre) %ames our.bowl] - glob-reference.href.docket - == - [~[add-fact:cha] state] - :: if the glob changed, forget the old and fetch the new - :: - =. charges (new-chad:cha %install ~) - [[add-fact:cha fetch-glob:cha] state] - :: - ++ on-suspend - |= [=desk =arak:hood] - ^- (quip card _state) - =* cha ~(. ch desk) - ?. (~(has by charges) desk) `state - =/ glob=(unit glob) - =/ =chad - chad:(~(got by charges) desk) - ?:(?=(%glob -.chad) `glob.chad ~) - =. charges (new-chad:cha %suspend glob) - :_(state ~[add-fact:cha]) - :: - ++ on-revive - |= [=desk =arak:hood] - ^- (quip card _state) - =* cha ~(. ch desk) - ?. (~(has by charges) desk) `state - =/ =charge (~(got by charges) desk) - ?. ?=(%glob -.href.docket.charge) - =. charges (new-chad:cha %site ~) - :_(state ~[add-fact:cha]) - =. charges - %- new-chad:cha - ?. ?=([%suspend ~ *] chad.charge) - [%install ~] - [%glob u.glob.chad.charge] - :_(state [add-fact fetch-glob]:cha) - -- - == ++ take-charge |= [=desk =^wire] ^- (quip card _state) @@ -398,6 +307,7 @@ :: ++ on-arvo |= [=wire sign=sign-arvo] + |^ =^ cards state ?+ wire (on-arvo:def wire sign) [%init ~] @@ -410,8 +320,117 @@ ?: accepted.sign `state ~& [dap.bowl %failed-to-bind path.binding.sign] `state + :: + [%tire ~] + ?> ?=([%clay %tire *] sign) + ?- -.p.sign + %& (on-rock p.p.sign) + %| (on-wave p.p.sign) + == + :: + [%warp * ~] + ?> ?=(%writ +<.sign) + (on-writ i.t.wire p.sign) == [cards this] + :: + ++ on-rock + |= tyr=rock:tire:clay + ^- (quip card _state) + =| fex=(list card) + =/ ark ~(tap by tyr) + |- ^- (quip card _state) + ?~ ark [(flop fex) state] + =^ caz state (on-zest [p zest.q]:i.ark) + $(ark t.ark, fex (weld (flop caz) fex)) + :: + ++ on-wave + |= =wave:tire:clay + ^- (quip card _state) + ?- -.wave + %wait `state + %warp `state + %zest (on-zest +.wave) + == + :: + ++ on-zest + |= [=desk =zest:clay] + ^- (quip card _state) + =* cha ~(. ch desk) + =/ card-1 + (~(warp-our pass /warp/[desk]) desk ~ %sing %z da+now.bowl /desk/docket-0) + =^ cards-2 state + ?. (~(has by charges) desk) + `state + =/ =charge (~(got by charges) desk) + ?- zest + %live + ?. ?=(%glob -.href.docket.charge) + =. charges (new-chad:cha %site ~) + :_(state ~[add-fact:cha]) + :_(state ~[add-fact:cha]) + :: + ?(%held %dead) + =/ glob=(unit glob) + ?:(?=(%glob -.chad.charge) `glob.chad.charge ~) + =. charges (new-chad:cha %suspend glob) + :_(state ~[add-fact:cha]) + == + [[card-1 cards-2] state] + :: + ++ on-writ + |= [=desk =riot:clay] + ^- (quip card _state) + =/ card-1 + (~(warp-our pass /warp/[desk]) desk ~ %next %z da+now.bowl /desk/docket-0) + =^ cards-2 state + =* cha ~(. ch desk) + =/ tyr + .^(rock:tire:clay %cx /(scot %p our.bowl)//(scot %da now.bowl)/tire) + ?. =(%live zest:(~(got by tyr) desk)) + `state + ?. docket-exists:cha + :: ~? ?& !=(%base desk) + :: !=(%kids desk) + :: == + :: [dap.bowl %no-docket-file-for desk] + ?. (~(has by charges) desk) + `state + :- ~[del-fact:cha] + state(charges (~(del by charges) desk)) + :: always update the docket in state to match clay's + :: + =/ =docket docket:cha + =/ pre=(unit charge) (~(get by charges) desk) + =. charges (new-docket:cha docket) + :: if the new chad is a site, we're instantly done + :: + ?: ?=(%site -.href.docket) + =. charges (new-chad:cha %site ~) + :- ~[add-fact:cha] + state + :: + =. by-base (~(put by by-base) base.href.docket desk) + :: if the glob specification is unchanged, keep it + :: + ?: &(?=(^ pre) =(href.docket.u.pre href.docket) ?=(%glob -.chad.u.pre)) + [~[add-fact:cha] state] + :: if the glob spec changed, but we already host it, keep it + :: (this is the "just locally uploaded" case) + :: + ?: ?& ?=(^ pre) + ?=(%glob -.chad.u.pre) + :: + .= [(sham glob.chad.u.pre) %ames our.bowl] + glob-reference.href.docket + == + [~[add-fact:cha] state] + :: if the glob changed, forget the old and fetch the new + :: + =. charges (new-chad:cha %install ~) + [[add-fact:cha fetch-glob:cha] state] + [[card-1 cards-2] state] + -- :: ++ on-fail on-fail:def ++ on-leave on-leave:def @@ -728,4 +747,3 @@ ++ docket .^(^docket %cx (scry:io desk docket-loc)) -- -- - diff --git a/pkg/garden/app/hark-system-hook.hoon b/pkg/garden/app/hark-system-hook.hoon index e7cd7132d..e4c499466 100644 --- a/pkg/garden/app/hark-system-hook.hoon +++ b/pkg/garden/app/hark-system-hook.hoon @@ -2,16 +2,16 @@ /+ verb, dbug, default-agent, agentio |% +$ card card:agent:gall -+$ state-0 [%0 lagging=_|] ++$ state-1 [%1 lagging=_|] :: ++ lag-interval ~m10 -- %+ verb | %- agent:dbug ^- agent:gall -=| state-0 +=| state-1 =* state - -=< +=< |_ =bowl:gall +* this . def ~(. (default-agent this %|) bowl) @@ -21,12 +21,23 @@ ++ on-init ^- (quip card _this) :_ this - [onboard watch:kiln check:lag ~]:cc + [onboard tire:cy check:lag ~]:cc :: ++ on-load |= =vase - =+ !<(old=state-0 vase) - `this(state old) + ^- (quip card _this) + |^ + =+ !<(old=app-states vase) + =^ cards-1 old + ?. ?=(%0 -.old) `old + [[tire:cy:cc]~ old(- %1)] + ?> ?=(%1 -.old) + =/ cards-tire [tire:cy:cc ~] + [(weld cards-1 cards-tire) this(state old)] + :: + +$ app-states $%(state-0 state-1) + +$ state-0 [%0 lagging=_|] + -- :: ++ on-save !>(state) ++ on-poke on-poke:def @@ -34,45 +45,57 @@ ++ on-watch on-watch:def ++ on-agent |= [=wire =sign:agent:gall] - |^ + ^- (quip card _this) ?+ wire (on-agent:def wire sign) - [%kiln %vats ~] take-kiln-vats + [%kiln %vats ~] `this == - ++ take-kiln-vats - ?- -.sign - ?(%poke-ack %watch-ack) (on-agent:def wire sign) - %kick :_(this (drop safe-watch:kiln:cc)) - :: - %fact - ?. ?=(%kiln-vats-diff-0 p.cage.sign) `this - =+ !<(=diff:hood q.cage.sign) - ?+ -.diff `this - :: - %commit - ?. |(=(desk.diff %base) ~(has-docket de:cc desk.diff)) `this - =/ =action:hark ~(commit de:cc desk.diff) +:: +++ on-arvo + |= [=wire sign=sign-arvo] + ^- (quip card _this) + |^ + ?+ wire (on-arvo:def wire sign) + [%clay %tire ~] take-clay-tire + [%clay %warp * ~] (take-clay-warp i.t.t.wire) + [%check-lag ~] take-check-lag + == + :: + ++ take-check-lag + ^- (quip card _this) + ?> ?=([%behn %wake *] sign) + =+ .^(lag=? %$ (scry:io %$ /zen/lag)) + ?: =(lagging lag) :_(this ~[check:lag:cc]) + :_ this(lagging lag) + :_ ~[check:lag:cc] + ?:(lagging start:lag:cc stop:lag:cc) + :: + ++ take-clay-tire + ^- (quip card _this) + ?> ?=(%tire +<.sign) + ?- -.p.sign + %& [(turn ~(tap in ~(key by p.p.sign)) warp:cy:cc) this] + %| + ?- -.p.p.sign + %zest `this + %warp `this + %wait + =/ =action:hark (~(blocked de:cc desk.p.p.sign) weft.p.p.sign) :_ this ~[(poke:ha:cc action)] - :: - %block - =/ =action:hark (~(blocked de:cc desk.diff) blockers.diff) - :_ this - ~[(poke:ha:cc action)] == == + :: + ++ take-clay-warp + |= =desk + ^- (quip card _this) + ?> ?=(%writ +<.sign) + =/ cards + ?. |(=(desk %base) ~(has-docket de:cc desk)) ~ + =/ =action:hark ~(commit de:cc desk) + ~[(poke:ha:cc action)] + [[(warp:cy:cc desk) cards] this] -- :: -++ on-arvo - |= [=wire sign=sign-arvo] - ^- (quip card _this) - ?. ?=([%check-lag ~] wire) (on-arvo:def wire sign) - ?> ?=([%behn %wake *] sign) - =+ .^(lag=? %$ (scry:io %$ /zen/lag)) - ?: =(lagging lag) :_(this ~[check:lag:cc]) - :_ this(lagging lag) - :_ ~[check:lag:cc] - ?:(lagging start:lag:cc stop:lag:cc) -:: ++ on-fail on-fail:def ++ on-leave on-leave:def -- @@ -89,7 +112,7 @@ [~[text+'Welcome to urbit'] ~ now.bowl / /] :: ++ lag - |% + |% ++ check (~(wait pass /check-lag) (add now.bowl lag-interval)) ++ place [q.byk.bowl /lag] ++ body `body:hark`[~[text/'Runtime lagging'] ~ now.bowl / /] @@ -102,24 +125,23 @@ ++ poke |=(=action:hark (poke-our:pass %hark-store hark-action+!>(action))) -- -++ kiln +:: +++ cy |% - ++ path /kiln/vats - ++ pass ~(. ^pass path) - ++ watch (watch-our:pass %hood path) - ++ watching (~(has by wex.bowl) [path our.bowl %hood]) - ++ safe-watch `(unit card)`?:(watching ~ `watch) + ++ tire ~(tire pass /clay/tire) + ++ warp + |= =desk + (~(warp-our pass /clay/warp/[desk]) desk ~ %next %z da+now.bowl /) -- :: ++ de |_ =desk - ++ scry-path (scry:io desk /desk/docket-0) + ++ scry-path (scry:io desk /desk/docket-0) ++ has-docket .^(? %cu scry-path) - ++ docket .^(docket:^docket %cx scry-path) - ++ hash .^(@uv %cz (scry:io desk ~)) - ++ place `place:hark`[q.byk.bowl /desk/[desk]] - ++ vat - .^(vat:hood %gx (scry:io %hood /kiln/vat/[desk]/noun)) + ++ docket .^(docket:^docket %cx scry-path) + ++ hash .^(@uv %cz (scry:io desk ~)) + ++ place `place:hark`[q.byk.bowl /desk/[desk]] + ++ version ud:.^(cass:clay %cw (scry:io desk /)) ++ body |= [=path title=cord content=(unit cord)] ^- body:hark @@ -131,7 +153,7 @@ %+ rap 3 ?: =(desk %base) ['System software' cord ~] - ?: has-docket + ?: has-docket ['App: "' title:docket '"' cord ~] ['Desk: ' desk cord ~] :: @@ -142,7 +164,7 @@ :: ++ commit ^- action:hark - ?:(=(1 ud.cass:vat) created updated) + ?:(=(1 version) created updated) :: ++ created ^- action:hark @@ -155,11 +177,11 @@ (body /desk/[desk] (title-prefix (rap 3 ' has been updated to ' get-version ~)) ~) :: ++ blocked - |= blockers=(set ^desk) + |= =weft ^- action:hark :+ %add-note [/blocked place] %^ body /blocked (title-prefix ' is blocked from upgrading') - `(rap 3 'Blocking desks: ' (join ', ' ~(tap in blockers))) + `(rap 3 'Blocked waiting for system version: ' (scot %ud num.weft) 'K' ~) :: ++ ver |= =version:^docket @@ -172,7 +194,7 @@ -- ++ note |% - ++ merge + ++ merge |= [=desk hash=@uv] ^- (list body:hark) :_ ~ diff --git a/pkg/garden/desk.docket-0 b/pkg/garden/desk.docket-0 index 6393b991c..f7e6cf433 100644 --- a/pkg/garden/desk.docket-0 +++ b/pkg/garden/desk.docket-0 @@ -1,7 +1,7 @@ :~ title+'System' info+'An app launcher for Urbit.' color+0xee.5432 - glob-http+['https://bootstrap.urbit.org/glob-0v5.kgrq2.gp725.bo5bk.dmr7d.h41qk.glob' 0v5.kgrq2.gp725.bo5bk.dmr7d.h41qk] + glob-http+['https://bootstrap.urbit.org/glob-0vm65f9.defur.eqhgj.62ls6.9v9lf.glob' 0vm65f9.defur.eqhgj.62ls6.9v9lf] ::glob-ames+~zod^0v0 base+'grid' version+[1 1 6] diff --git a/pkg/garden/lib/treaty.hoon b/pkg/garden/lib/treaty.hoon index bea8fc750..2a3205a56 100644 --- a/pkg/garden/lib/treaty.hoon +++ b/pkg/garden/lib/treaty.hoon @@ -28,6 +28,7 @@ %tas s+(scot %tas p.c) %ud (numb p.c) == + :: ++ foreign-desk |= [s=^ship =desk] ^- cord diff --git a/pkg/garden/sys.kelvin b/pkg/garden/sys.kelvin index e77a3de08..b7bcb9ecd 100644 --- a/pkg/garden/sys.kelvin +++ b/pkg/garden/sys.kelvin @@ -1 +1 @@ -[%zuse 418] +[%zuse 417] diff --git a/pkg/garden/ted/get-dudes.hoon b/pkg/garden/ted/get-dudes.hoon new file mode 100644 index 000000000..fe0b41d13 --- /dev/null +++ b/pkg/garden/ted/get-dudes.hoon @@ -0,0 +1,53 @@ +/- spider +/+ *strandio +:: +=, strand=strand:spider +:: +:: send on /spider/garden/json/get-dudes/json +:: +|% +++ buds :: get agents currently running + |= p=desk + =/ m (strand ,(list dude:gall)) + ^- form:m + ?. =(%$ p) + ;< q=(list dude:gall) bind:m (suds p) + (pure:m q) + ;< q=(list desk) bind:m duds + =| r=(list (list dude:gall)) + |- ^- form:m + =* s $ + ?~ q (pure:m (zing r)) + ;< t=(list dude:gall) bind:m (suds i.q) + s(q t.q, r [t r]) +:: +++ suds :: clean %ge scry + |= p=desk + =/ m (strand ,(list dude:gall)) + ^- form:m + ;< q=(set [dude:gall ?]) bind:m + (scry (set ,[dude:gall ?]) /ge/(scot %tas p)) + %- pure:m + (murn ~(tap in q) |=([dude:gall ?] ?.(+.+< ~ `-.+<))) +:: +++ duds :: get desks + =/ m (strand ,(list desk)) + ^- form:m + ;< p=(set desk) bind:m (scry (set ,desk) /cd/base) + (pure:m ~(tap in p)) +-- +:: +^- thread:spider +|= jon=vase +=/ m (strand ,vase) +^- form:m +;< =bowl:spider bind:m get-bowl +=, bowl +?~ know=!<((unit json) jon) + (pure:m !>(`json`[%s 'invalid-request'])) +?. ?=([%s @] u.know) + (pure:m !>(`json`[%s 'invalid-request'])) +=, format +;< breh=(list @tas) bind:m (buds (so:dejs u.know)) +%- pure:m +!>(`json`(frond:enjs 'buds' a+(turn breh |=(@tas s+[+<])))) diff --git a/pkg/grid/package-lock.json b/pkg/grid/package-lock.json index 841d7d47f..1c9fc4560 100644 Binary files a/pkg/grid/package-lock.json and b/pkg/grid/package-lock.json differ diff --git a/pkg/grid/package.json b/pkg/grid/package.json index 7a2bb01da..0ab3bb312 100644 --- a/pkg/grid/package.json +++ b/pkg/grid/package.json @@ -25,7 +25,7 @@ "@radix-ui/react-toggle": "^0.0.10", "@tlon/sigil-js": "^1.4.4", "@types/lodash": "^4.14.172", - "@urbit/api": "^2.1.1", + "@urbit/api": "^2.2.0", "@urbit/http-api": "^2.1.0", "big-integer": "^1.6.48", "classnames": "^2.3.1", diff --git a/pkg/grid/src/app.tsx b/pkg/grid/src/app.tsx index e973d8922..51d808845 100644 --- a/pkg/grid/src/app.tsx +++ b/pkg/grid/src/app.tsx @@ -86,9 +86,8 @@ const AppRoutes = () => { fetchCharges(); fetchAllies(); - const { fetchVats, fetchLag } = useKilnState.getState(); - fetchVats(); - fetchLag(); + const { initializeKiln } = useKilnState.getState(); + initializeKiln(); useContactState.getState().initialize(api); useHarkStore.getState().initialize(api); diff --git a/pkg/grid/src/components/AppInfo.tsx b/pkg/grid/src/components/AppInfo.tsx index a23597602..a6ad97fba 100644 --- a/pkg/grid/src/components/AppInfo.tsx +++ b/pkg/grid/src/components/AppInfo.tsx @@ -1,4 +1,4 @@ -import { chadIsRunning, Treaty, Vat } from '@urbit/api'; +import { chadIsRunning, Pike, Treaty } from '@urbit/api'; import clipboardCopy from 'clipboard-copy'; import React, { FC, useCallback, useState } from 'react'; import cn from 'classnames'; @@ -6,7 +6,7 @@ import { Button, PillButton } from './Button'; import { Dialog, DialogClose, DialogContent, DialogTrigger } from './Dialog'; import { DocketHeader } from './DocketHeader'; import { Spinner } from './Spinner'; -import { VatMeta } from './VatMeta'; +import { PikeMeta } from './PikeMeta'; import useDocketState, { ChargeWithDesk, useTreaty } from '../state/docket'; import { getAppHref, getAppName } from '../state/util'; import { addRecentApp } from '../nav/search/Home'; @@ -17,7 +17,7 @@ type InstallStatus = 'uninstalled' | 'installing' | 'installed'; type App = ChargeWithDesk | Treaty; interface AppInfoProps { docket: App; - vat?: Vat; + pike?: Pike; className?: string; } @@ -34,10 +34,9 @@ function getInstallStatus(docket: App): InstallStatus { return 'uninstalled'; } -function getRemoteDesk(docket: App, vat?: Vat) { - if (vat && vat.arak.rail) { - const { ship, desk } = vat.arak.rail; - return [ship, desk]; +function getRemoteDesk(docket: App, pike?: Pike) { + if (pike && pike.sync) { + return [pike.sync.ship, pike.sync.desk]; } if ('chad' in docket) { return ['', docket.desk]; @@ -46,10 +45,10 @@ function getRemoteDesk(docket: App, vat?: Vat) { return [ship, desk]; } -export const AppInfo: FC = ({ docket, vat, className }) => { +export const AppInfo: FC = ({ docket, pike, className }) => { const installStatus = getInstallStatus(docket); - const [ship, desk] = getRemoteDesk(docket, vat); - const publisher = vat?.arak?.rail?.publisher ?? ship; + const [ship, desk] = getRemoteDesk(docket, pike); + const publisher = pike?.sync?.ship ?? ship; const [copied, setCopied] = useState(false); const treaty = useTreaty(ship, desk); @@ -136,10 +135,10 @@ export const AppInfo: FC = ({ docket, vat, className }) => {
- {vat ? ( + {pike ? ( <>
- + ) : null} {!treaty ? null : ( diff --git a/pkg/grid/src/components/PikeMeta.tsx b/pkg/grid/src/components/PikeMeta.tsx new file mode 100644 index 000000000..9349eeb3c --- /dev/null +++ b/pkg/grid/src/components/PikeMeta.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { Pike } from '@urbit/api'; + +import { Attribute } from './Attribute'; + +export function PikeMeta(props: { pike: Pike }) { + const { pike } = props; + + const pluralUpdates = pike.wefts?.length !== 1; + return ( +
+ + {pike.hash} + + + %{pike.sync?.desk} + + {pike.wefts && pike.wefts.length > 0 ? ( + + {pike.wefts.length} update{pluralUpdates ? 's are' : ' is'} pending a System Update + + ) : null} +
+ ); +} diff --git a/pkg/grid/src/components/ShipName.tsx b/pkg/grid/src/components/ShipName.tsx index 5ada5a372..4a49706b1 100644 --- a/pkg/grid/src/components/ShipName.tsx +++ b/pkg/grid/src/components/ShipName.tsx @@ -3,11 +3,12 @@ import React, { HTMLAttributes } from 'react'; type ShipNameProps = { name: string; + truncate?: boolean; } & HTMLAttributes; -export const ShipName = ({ name, ...props }: ShipNameProps) => { +export const ShipName = ({ name, truncate = true, ...props }: ShipNameProps) => { const separator = /([_^-])/; - const citedName = cite(name); + const citedName = truncate ? cite(name) : name; if (!citedName) { return null; diff --git a/pkg/grid/src/components/SourceSetter.tsx b/pkg/grid/src/components/SourceSetter.tsx new file mode 100644 index 000000000..b37936f26 --- /dev/null +++ b/pkg/grid/src/components/SourceSetter.tsx @@ -0,0 +1,103 @@ +import React, { useCallback, useState } from 'react'; +import { useAsyncCall } from '../logic/useAsyncCall'; +import { Button } from './Button'; +import { ShipName } from './ShipName'; +import { Spinner } from './Spinner'; + +interface SourceSetterProps { + appName: string; + srcDesk: string; + srcShip?: string; + title: string; + toggleSrc: (desk: string, ship: string) => Promise; +} + +export default function SourceSetter({ + appName, + srcDesk, + srcShip, + title, + toggleSrc +}: SourceSetterProps) { + const [newSyncShip, setNewSyncShip] = useState(srcShip ?? ''); + const { status: requestStatus, call: handleSubmit } = useAsyncCall(toggleSrc); + const syncDirty = newSyncShip !== srcShip; + + const onUnset = useCallback(() => { + if (!srcShip) { + return; + } + if ( + // eslint-disable-next-line no-alert, no-restricted-globals + confirm(`Are you sure you want to unsync ${appName}? You will no longer receive updates.`) + ) { + toggleSrc(srcDesk, srcShip); + } + }, [srcShip, srcDesk]); + + const handleSourceChange = useCallback((e: React.ChangeEvent) => { + const { target } = e; + const value = target.value.trim(); + setNewSyncShip(value.startsWith('~') ? value : `~${value}`); + }, []); + + const onSubmit = useCallback( + async (e: React.FormEvent) => { + e.preventDefault(); + await handleSubmit(srcDesk, newSyncShip); + }, + [srcDesk, newSyncShip] + ); + + return ( + <> +

{title}

+
+ {srcShip ? ( + <> +

Automatic Updates

+

Automatically download and apply updates to keep {appName} up to date.

+
+

+ OTA Source:{' '} + +

+
+
+ +
+ + ) : ( +
+ +

Enter a valid urbit name to receive updates for {appName}.

+
+ + {syncDirty && ( + + )} +
+
+ )} +
+ + ); +} diff --git a/pkg/grid/src/components/VatMeta.tsx b/pkg/grid/src/components/VatMeta.tsx deleted file mode 100644 index f55351e41..000000000 --- a/pkg/grid/src/components/VatMeta.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; -import { Vat } from '@urbit/api'; - -import { Attribute } from './Attribute'; - -export function VatMeta(props: { vat: Vat }) { - const { vat } = props; - const { desk, arak, cass, hash } = vat; - - const { desk: foreignDesk, ship, next } = arak.rail || {}; - const pluralUpdates = next?.length !== 1; - return ( -
- - {hash} - - - %{desk} - - {next && next.length > 0 ? ( - - {next.length} update{pluralUpdates ? 's are' : ' is'} pending a System Update - - ) : null} -
- ); -} diff --git a/pkg/grid/src/nav/SystemMenu.tsx b/pkg/grid/src/nav/SystemMenu.tsx index 44f8379ca..fb2f0c51d 100644 --- a/pkg/grid/src/nav/SystemMenu.tsx +++ b/pkg/grid/src/nav/SystemMenu.tsx @@ -3,9 +3,9 @@ import classNames from 'classnames'; import clipboardCopy from 'clipboard-copy'; import React, { HTMLAttributes, useCallback, useState } from 'react'; import { Link, Route, useHistory } from 'react-router-dom'; -import { Vat } from '@urbit/api'; +import { Pike } from '@urbit/api'; import { Adjust } from '../components/icons/Adjust'; -import { useVat } from '../state/kiln'; +import { usePike } from '../state/kiln'; import { disableDefault, handleDropdownLink } from '../state/util'; import { useMedia } from '../logic/useMedia'; import { Cross } from '../components/icons/Cross'; @@ -17,15 +17,15 @@ type SystemMenuProps = HTMLAttributes & { shouldDim: boolean; }; -function getHash(vat: Vat): string { - const parts = vat.hash.split('.'); +function getHash(pike: Pike): string { + const parts = pike.hash.split('.'); return parts[parts.length - 1]; } export const SystemMenu = ({ className, open, subMenuOpen, shouldDim }: SystemMenuProps) => { const { push } = useHistory(); const [copied, setCopied] = useState(false); - const garden = useVat(window.desk); + const garden = usePike(window.desk); const hash = garden ? getHash(garden) : null; const isMobile = useMedia('(max-width: 639px)'); const select = useLeapStore((s) => s.select); diff --git a/pkg/grid/src/nav/notifications/BasicNotification.tsx b/pkg/grid/src/nav/notifications/BasicNotification.tsx index 7e7f87ed4..1999323c7 100644 --- a/pkg/grid/src/nav/notifications/BasicNotification.tsx +++ b/pkg/grid/src/nav/notifications/BasicNotification.tsx @@ -88,8 +88,8 @@ export const BasicNotification = ({ notification, lid }: BasicNotificationProps) {contents.length > 0 ? (
- {take(contents, MAX_CONTENTS).map((content) => ( -

+ {take(contents, MAX_CONTENTS).map((content, i) => ( +

))} diff --git a/pkg/grid/src/nav/notifications/Inbox.tsx b/pkg/grid/src/nav/notifications/Inbox.tsx index 4661f884e..74d5b880b 100644 --- a/pkg/grid/src/nav/notifications/Inbox.tsx +++ b/pkg/grid/src/nav/notifications/Inbox.tsx @@ -13,7 +13,7 @@ function renderNotification(notification: Notification, key: string, lid: HarkLi return ; } if (notification.bin.path === '/blocked' && notification.bin.place.path === '/desk/base') { - return ; + return ; } if (notification.bin.place.path === '/onboard') { return ; diff --git a/pkg/grid/src/nav/notifications/OnboardingNotification.tsx b/pkg/grid/src/nav/notifications/OnboardingNotification.tsx index bd9af8947..df6a8896e 100644 --- a/pkg/grid/src/nav/notifications/OnboardingNotification.tsx +++ b/pkg/grid/src/nav/notifications/OnboardingNotification.tsx @@ -1,15 +1,15 @@ import React from 'react'; import cn from 'classnames'; import { Link } from 'react-router-dom'; -import { HarkLid, Vats, getVatPublisher } from '@urbit/api'; +import { HarkLid, Pikes, getPikePublisher } from '@urbit/api'; import { Button } from '../../components/Button'; import { useBrowserId, useCurrentTheme } from '../../state/local'; import { getDarkColor } from '../../state/util'; -import useKilnState from '../../state/kiln'; +import { usePikes } from '../../state/kiln'; import { useHarkStore } from '../../state/hark'; import { useProtocolHandling } from '../../state/settings'; -const getCards = (vats: Vats, protocol: boolean): OnboardingCardProps[] => { +const getCards = (pikes: Pikes, protocol: boolean): OnboardingCardProps[] => { const cards = [ { title: 'Terminal', @@ -38,20 +38,6 @@ const getCards = (vats: Vats, protocol: boolean): OnboardingCardProps[] => { ship: '~mister-dister-dozzod-dozzod', desk: 'bitcoin' } - // Commenting out until we have something real - // { - // title: 'Debug', - // body: "Install a debugger. You can inspect your ship's internals using this interface", - // button: 'Install', - // color: '#E5E5E5', - // href: '/leap/search/direct/apps/~zod/debug' - // } - // { - // title: 'Build an app', - // body: 'You can instantly get started building new things on Urbit. Just right click your Landscape and select “New App”', - // button: 'Learn more', - // color: '#82A6CA' - // } ]; if ('registerProtocolHandler' in window.navigator && !protocol) { cards.push({ @@ -66,8 +52,8 @@ const getCards = (vats: Vats, protocol: boolean): OnboardingCardProps[] => { } return cards.filter((card) => { - return !Object.values(vats).find( - (vat) => getVatPublisher(vat) == card.ship && vat?.arak?.rail?.desk === card.desk + return !Object.values(pikes).find( + (pike) => getPikePublisher(pike) === card.ship && pike.sync?.desk === card.desk ); }); }; @@ -107,10 +93,10 @@ interface OnboardingNotificationProps { export const OnboardingNotification = ({ unread = false, lid }: OnboardingNotificationProps) => { const theme = useCurrentTheme(); - const vats = useKilnState((s) => s.vats); + const pikes = usePikes(); const browserId = useBrowserId(); const protocolHandling = useProtocolHandling(browserId); - const cards = getCards(vats, protocolHandling); + const cards = getCards(pikes, protocolHandling); if (cards.length === 0 && !('time' in lid)) { useHarkStore.getState().archiveNote( diff --git a/pkg/grid/src/nav/notifications/SystemNotification.tsx b/pkg/grid/src/nav/notifications/SystemNotification.tsx index c92822ae8..0a123fcec 100644 --- a/pkg/grid/src/nav/notifications/SystemNotification.tsx +++ b/pkg/grid/src/nav/notifications/SystemNotification.tsx @@ -1,18 +1,18 @@ -import { pick, pickBy, partition } from 'lodash'; +import { pick, partition } from 'lodash'; import React, { useCallback } from 'react'; -import { kilnBump } from '@urbit/api'; +import { HarkBin, HarkLid, kilnBump, Pike } from '@urbit/api'; +import { useHistory } from 'react-router-dom'; import { AppList } from '../../components/AppList'; import { Button } from '../../components/Button'; import { Dialog, DialogClose, DialogContent, DialogTrigger } from '../../components/Dialog'; import { Elbow } from '../../components/icons/Elbow'; import api from '../../state/api'; import { useCharges } from '../../state/docket'; -import useKilnState, { useVat } from '../../state/kiln'; +import useKilnState, { usePike } from '../../state/kiln'; import { NotificationButton } from './NotificationButton'; import { disableDefault } from '../../state/util'; -import { Vat } from '@urbit/api'; -import {useHistory} from 'react-router-dom'; +import { useHarkStore } from '../../state/hark'; export const RuntimeLagNotification = () => (
(
); -function vatIsBlocked(newKelvin: number, vat: Vat) { - return !(vat.arak?.rail?.next || []).find(({ aeon, weft }) => weft.kelvin === newKelvin); +function pikeIsBlocked(newKelvin: number, pike: Pike) { + return pike.zest === 'live' && !pike.wefts?.find(({ kelvin }) => kelvin === newKelvin); } -export const BaseBlockedNotification = () => { - const base = useVat('base'); +export const BaseBlockedNotification = ({ bin, lid }: { bin: HarkBin, lid: HarkLid }) => { + const basePike = usePike('base'); const { push } = useHistory(); // TODO: assert weft.name === 'zuse'?? - const newKelvin = base?.arak?.rail?.next?.[0]?.weft?.kelvin || 420; + const newKelvin = basePike?.wefts[0]?.kelvin ?? 417; const charges = useCharges(); - const [blocked, unblocked] = useKilnState((s) => { - const [b, u] = partition(Object.entries(s.vats), ([desk, vat]) => vatIsBlocked(newKelvin, vat)); + const [blocked] = useKilnState((s) => { + const [b, u] = partition(Object.entries(s.pikes), ([, pike]) => pikeIsBlocked(newKelvin, pike)); return [b.map(([d]) => d), u.map(([d]) => d)] as const; }); + const { toggleInstall } = useKilnState(); const blockedCharges = Object.values(pick(charges, blocked)); const count = blockedCharges.length; - const handlePauseOTAs = useCallback(() => {}, []); + const handlePauseOTAs = useCallback(async () => { + await useHarkStore.getState().archiveNote(bin, lid); + }, []); const handleArchiveApps = useCallback(async () => { - api.poke(kilnBump(true)); + await api.poke(kilnBump()); + await useHarkStore.getState().archiveNote(bin, lid); + push('/leap/upgrading'); }, []); @@ -81,12 +86,12 @@ export const BaseBlockedNotification = () => {

- In order to proceed with the System Update, you’ll need to temporarily archive these apps, - which will render them unusable, but with data intact. + In order to proceed with the System Update, you’ll need to temporarily suspend these apps. + This will render them unusable, but with data intact.

- Archived apps will automatically un-archive and resume operation when their developer - provides an app update. + Suspended apps will automatically resume operation when their developer + provides an update.

@@ -97,30 +102,24 @@ export const BaseBlockedNotification = () => { className="space-y-6 text-base tracking-tight" containerClass="w-full max-w-md" > -

Skip System Update

+

Delay System Update

- Skipping the application fo an incoming System Update will grant you the ability to - continue using incompatible apps at the cost of an urbit that's not up to date. -

-

- You can choose to apply System Updates from System Preferences any time.{' '} - - Learn More - + Are you sure you want to remain on an old version of Urbit + until these apps have been updated?

Cancel - Pause OTAs + Remain on Old Version
- Archive ({count}) apps and Apply System Update + Suspend ({count}) Apps and Apply Update { className="space-y-6 text-base tracking-tight" containerClass="w-full max-w-md" > -

Archive ({count}) Apps and Apply System Update

+

Suspend ({count}) Apps and Apply System Update

- The following apps will be archived until their developer provides a compatible update - to your system. + The following apps will be suspended until their developer provides an update.

{ Cancel - Archive Apps + Suspend Apps and Upgrade
diff --git a/pkg/grid/src/nav/preferences/AppPrefs.tsx b/pkg/grid/src/nav/preferences/AppPrefs.tsx index 51910f776..3cc00e1b9 100644 --- a/pkg/grid/src/nav/preferences/AppPrefs.tsx +++ b/pkg/grid/src/nav/preferences/AppPrefs.tsx @@ -1,39 +1,25 @@ -import React, { useCallback } from 'react'; +import React from 'react'; import { RouteComponentProps } from 'react-router-dom'; -import { Setting } from '../../components/Setting'; -import { ShipName } from '../../components/ShipName'; +import SourceSetter from '../../components/SourceSetter'; import { useCharge } from '../../state/docket'; -import useKilnState, { useVat } from '../../state/kiln'; +import useKilnState, { usePike } from '../../state/kiln'; import { getAppName } from '../../state/util'; export const AppPrefs = ({ match }: RouteComponentProps<{ desk: string }>) => { const { desk } = match.params; const charge = useCharge(desk); - const vat = useVat(desk); - const tracking = !!vat?.arak.rail; - const otasEnabled = !vat?.arak.rail?.paused; - const otaSource = vat?.arak.rail?.ship; - const toggleOTAs = useKilnState((s) => s.toggleOTAs); - - const toggleUpdates = useCallback((on: boolean) => toggleOTAs(desk, on), [desk, toggleOTAs]); + const appName = getAppName(charge); + const pike = usePike(desk); + const srcShip = pike?.sync?.ship; + const { toggleSync } = useKilnState(); return ( - <> -

{getAppName(charge)} Settings

-
- {tracking ? ( - -

Automatically download and apply updates to keep {getAppName(charge)} up to date.

- {otaSource && ( -

- OTA Source: -

- )} -
- ) : ( -

No settings

- )} -
- + ); }; diff --git a/pkg/grid/src/nav/preferences/SystemUpdatePrefs.tsx b/pkg/grid/src/nav/preferences/SystemUpdatePrefs.tsx index 4a8eafc55..b08bd32dc 100644 --- a/pkg/grid/src/nav/preferences/SystemUpdatePrefs.tsx +++ b/pkg/grid/src/nav/preferences/SystemUpdatePrefs.tsx @@ -1,88 +1,22 @@ import _ from 'lodash'; -import React, { ChangeEvent, FormEvent, useCallback, useEffect, useState } from 'react'; -import { Button } from '../../components/Button'; -import { Setting } from '../../components/Setting'; -import { ShipName } from '../../components/ShipName'; -import { Spinner } from '../../components/Spinner'; -import { useAsyncCall } from '../../logic/useAsyncCall'; -import useKilnState, { useVat } from '../../state/kiln'; +import React from 'react'; +import SourceSetter from '../../components/SourceSetter'; +import useKilnState, { usePike } from '../../state/kiln'; export const SystemUpdatePrefs = () => { - const { changeOTASource, toggleOTAs } = useKilnState((s) => - _.pick(s, ['toggleOTAs', 'changeOTASource']) - ); - const base = useVat('base'); - const otasEnabled = base && !(base.arak?.rail?.paused ?? true); - const otaSource = base && base.arak.rail?.ship; - - const toggleBase = useCallback((on: boolean) => toggleOTAs('base', on), [toggleOTAs]); - - const [source, setSource] = useState(''); - const sourceDirty = source !== otaSource; - const { status: sourceStatus, call: setOTA } = useAsyncCall(changeOTASource); - - useEffect(() => { - if (otaSource) { - setSource(otaSource); - } - }, [otaSource]); - - const handleSourceChange = useCallback((e: ChangeEvent) => { - const { target } = e; - const value = target.value.trim(); - setSource(value.startsWith('~') ? value : `~${value}`); - }, []); - - const onSubmit = useCallback( - (e: FormEvent) => { - e.preventDefault(); - setOTA(source); - }, - [source] - ); + const desk = 'base'; + const appName = 'your Urbit'; + const pike = usePike(desk); + const srcShip = pike?.sync?.ship; + const { toggleInstall } = useKilnState(); return ( - <> -

System Updates

-
- -

Automatically download and apply system updates to keep your Urbit up to date.

- {otaSource && ( -

- OTA Source: -

- )} -
-
- -

- Enter a valid urbit name into this form to change who you receive OTA updates from. Be - sure to select a reliable urbit! -

-
- - {sourceDirty && ( - - )} -
-
-
- + ); }; diff --git a/pkg/grid/src/nav/search/TreatyInfo.tsx b/pkg/grid/src/nav/search/TreatyInfo.tsx index a6c78feec..ac305e0d7 100644 --- a/pkg/grid/src/nav/search/TreatyInfo.tsx +++ b/pkg/grid/src/nav/search/TreatyInfo.tsx @@ -3,7 +3,7 @@ import { useParams } from 'react-router-dom'; import { AppInfo } from '../../components/AppInfo'; import { Spinner } from '../../components/Spinner'; import useDocketState, { useCharge, useTreaty } from '../../state/docket'; -import { useVat } from '../../state/kiln'; +import { usePike } from '../../state/kiln'; import { getAppName } from '../../state/util'; import { useLeapStore } from '../Nav'; @@ -11,7 +11,7 @@ export const TreatyInfo = () => { const select = useLeapStore((state) => state.select); const { host, desk } = useParams<{ host: string; desk: string }>(); const treaty = useTreaty(host, desk); - const vat = useVat(desk); + const pike = usePike(desk); const charge = useCharge(desk); const name = getAppName(treaty); @@ -34,5 +34,5 @@ export const TreatyInfo = () => {
); } - return ; + return ; }; diff --git a/pkg/grid/src/pages/Grid.tsx b/pkg/grid/src/pages/Grid.tsx index b1d968236..858cae3bf 100644 --- a/pkg/grid/src/pages/Grid.tsx +++ b/pkg/grid/src/pages/Grid.tsx @@ -26,8 +26,8 @@ export const Grid: FunctionComponent = () => { window.location.reload(); } const start = performance.now(); - await useKilnState.getState().fetchVats(); - await useKilnState.getState().fetchVats(); + await useKilnState.getState().fetchPikes(); + await useKilnState.getState().fetchPikes(); if (performance.now() - start > 5000) { attempt(count + 1); } else { diff --git a/pkg/grid/src/pages/PermalinkRoutes.tsx b/pkg/grid/src/pages/PermalinkRoutes.tsx index c1fefda0d..5a412c18f 100644 --- a/pkg/grid/src/pages/PermalinkRoutes.tsx +++ b/pkg/grid/src/pages/PermalinkRoutes.tsx @@ -1,15 +1,15 @@ +import { Pikes } from '@urbit/api'; import React, { useEffect } from 'react'; import { Switch, Route, Redirect, RouteComponentProps } from 'react-router-dom'; import { Spinner } from '../components/Spinner'; import { useQuery } from '../logic/useQuery'; import { useCharge } from '../state/docket'; -import useKilnState, { useKilnLoaded } from '../state/kiln'; +import { useKilnLoaded, usePikes } from '../state/kiln'; import { getAppHref } from '../state/util'; -function getDeskByForeignRef(ship: string, desk: string): string | undefined { - const { vats } = useKilnState.getState(); - const found = Object.entries(vats).find( - ([, vat]) => vat.arak.rail?.ship === ship && vat.arak.rail?.desk === desk +function getDeskByForeignRef(pikes: Pikes, ship: string, desk: string): string | undefined { + const found = Object.entries(pikes).find( + ([, pike]) => pike.sync?.ship === ship && pike.sync?.desk === desk ); return found ? found[0] : undefined; } @@ -22,8 +22,8 @@ type AppLinkProps = RouteComponentProps<{ function AppLink({ match, history, location }: AppLinkProps) { const { ship, desk, link = '' } = match.params; - const ourDesk = getDeskByForeignRef(ship, desk); - console.log(ourDesk); + const pikes = usePikes(); + const ourDesk = getDeskByForeignRef(pikes, ship, desk); if (ourDesk) { return ; diff --git a/pkg/grid/src/state/kiln.ts b/pkg/grid/src/state/kiln.ts index 06589f759..352535c64 100644 --- a/pkg/grid/src/state/kiln.ts +++ b/pkg/grid/src/state/kiln.ts @@ -1,99 +1,76 @@ import { - getVats, - Vats, scryLag, - getBlockers, - Vat, - kilnInstall, - kilnPause, - kilnResume + getPikes, + Pikes, + Pike, + kilnUnsync, + kilnSync, + kilnUninstall, + kilnInstall } from '@urbit/api'; import create from 'zustand'; import produce from 'immer'; import { useCallback } from 'react'; import api from './api'; import { fakeRequest, useMockData } from './util'; -import { mockVats } from './mock-data'; +import { mockPikes } from './mock-data'; interface KilnState { - vats: Vats; + pikes: Pikes; loaded: boolean; - fetchVats: () => Promise; lag: boolean; fetchLag: () => Promise; - changeOTASource: (ship: string) => Promise; - toggleOTAs: (desk: string, on: boolean) => Promise; + fetchPikes: () => Promise; + toggleInstall: (desk: string, ship: string) => Promise; + toggleSync: (desk: string, ship: string) => Promise; set: (s: KilnState) => void; + initializeKiln: () => Promise; } const useKilnState = create((set, get) => ({ - vats: useMockData ? mockVats : {}, + pikes: useMockData ? mockPikes : {}, lag: !!useMockData, loaded: false, - fetchVats: async () => { + fetchPikes: async () => { if (useMockData) { await fakeRequest({}, 500); set({ loaded: true }); return; } - const vats = await api.scry(getVats); - set({ vats, loaded: true }); + const pikes = await api.scry(getPikes); + set({ pikes, loaded: true }); }, fetchLag: async () => { const lag = await api.scry(scryLag); set({ lag }); }, - changeOTASource: async (ship: string) => { - if (useMockData) { - await fakeRequest(''); - set( - produce((draft: KilnState) => { - if (!draft.vats.base.arak.rail) { - return; - } - draft.vats.base.arak.rail.ship = ship; - }) - ); - return; - } - - await api.poke(kilnInstall(ship, 'kids', 'base')); + toggleInstall: async (desk: string, ship: string) => { + const synced = !!get().pikes[desk].sync; + await (useMockData + ? fakeRequest('') + : api.poke(synced ? kilnUninstall(desk) : kilnInstall(ship, 'kids', desk))); + await get().fetchPikes(); }, - toggleOTAs: async (desk: string, on: boolean) => { - set( - produce((draft: KilnState) => { - const { arak } = draft.vats[desk]; - if (!arak.rail) { - return; - } - if (on) { - arak.rail.paused = false; - } else { - arak.rail.paused = true; - } - }) - ); - - await (useMockData ? fakeRequest('') : api.poke(on ? kilnResume(desk) : kilnPause(desk))); - await get().fetchVats(); // refresh vat state + toggleSync: async (desk: string, ship: string) => { + const synced = !!get().pikes[desk].sync; + await (useMockData + ? fakeRequest('') + : api.poke(synced ? kilnUnsync(ship, desk) : kilnSync(ship, desk))); + await get().fetchPikes(); }, - set: produce(set) + set: produce(set), + initializeKiln: async () => { + await get().fetchLag(); + await get().fetchPikes(); + } })); -api.subscribe({ - app: 'hood', - path: '/kiln/vats', - event: () => { - useKilnState.getState().fetchVats(); - } -}); - -const selBlockers = (s: KilnState) => getBlockers(s.vats); -export function useBlockers() { - return useKilnState(selBlockers); +const selPikes = (s: KilnState) => s.pikes; +export function usePikes(): Pikes { + return useKilnState(selPikes); } -export function useVat(desk: string): Vat | undefined { - return useKilnState(useCallback((s) => s.vats[desk], [desk])); +export function usePike(desk: string): Pike | undefined { + return useKilnState(useCallback((s) => s.pikes[desk], [desk])); } const selLag = (s: KilnState) => s.lag; diff --git a/pkg/grid/src/state/mock-data.ts b/pkg/grid/src/state/mock-data.ts index 967f07dd9..f360483bc 100644 --- a/pkg/grid/src/state/mock-data.ts +++ b/pkg/grid/src/state/mock-data.ts @@ -1,6 +1,4 @@ import { - Vat, - Vats, Allies, Charges, DocketHrefGlob, @@ -13,7 +11,8 @@ import { Contact, Contacts, Timebox, - harkBinToId + harkBinToId, + Pikes } from '@urbit/api'; import _ from 'lodash'; import systemUrl from '../assets/system.png'; @@ -341,37 +340,35 @@ export const mockContacts: Contacts = { } }; -export const mockVat = (desk: string, blockers?: boolean): Vat => ({ - cass: { - da: '~2021.9.13..05.41.04..ae65', - ud: 1 +export const mockPikes: Pikes = { + kids: { + sync: null, + zest: 'dead', + wefts: [], + hash: '0v19.q7u27.omps3.fbhf4.53rai.co157.pben7.pu94n.63v4p.3kcb7.iafj0' }, - desk, - arak: { - rein: { - sub: [], - add: [] + garden: { + sync: { + desk: 'garden', + ship: '~mister-dister-dozzod-dozzod' }, - rail: - desk === 'uniswap' - ? null - : { - aeon: 3, - desk, - publisher: '~zod', - next: blockers ? [{ aeon: 3, weft: { name: 'zuse', kelvin: 419 } }] : [], - ship: '~zod', - paused: desk === 'groups' - } + zest: 'live', + wefts: [], + hash: '0v18.hbbs6.onu15.skjkv.qrfgl.vf4oo.0igo5.2q0d3.6r3r8.2dkmo.oa04m' }, - hash: '0vh.lhfn6.julg1.fs52d.g2lqj.q5kp0.2o7j3.2bljl.jdm34.hd46v.9uv5v' -}); - -const badVats = ['inbox', 'system', 'terminal', 'base']; -export const mockVats = _.reduce( - mockCharges, - (vats, charge, desk) => { - return { ...vats, [desk]: mockVat(desk, !badVats.includes(desk)) }; + landscape: { + sync: { + desk: 'landscape', + ship: '~lander-dister-dozzod-dozzod' + }, + zest: 'live', + wefts: [], + hash: '0v1t.qln8k.cskmt.cn6lv.gu335.jfba6.kte90.iqqn3.aj67b.t389a.8imuo' }, - { base: mockVat('base', true) } as Vats -); + base: { + sync: null, + zest: 'live', + wefts: [], + hash: '0v1e.b5auh.6u82i.hqk1r.22kli.4ubef.a1cbo.3g532.6l49k.g0i8e.t6eid' + } +}; diff --git a/pkg/grid/src/tiles/Tile.tsx b/pkg/grid/src/tiles/Tile.tsx index 4ffb59cc8..bc2bfe86c 100644 --- a/pkg/grid/src/tiles/Tile.tsx +++ b/pkg/grid/src/tiles/Tile.tsx @@ -8,7 +8,7 @@ import { getAppHref } from '../state/util'; import { useRecentsStore } from '../nav/search/Home'; import { ChargeWithDesk } from '../state/docket'; import { useTileColor } from './useTileColor'; -import { useVat } from '../state/kiln'; +import { usePike } from '../state/kiln'; import { Bullet } from '../components/icons/Bullet'; import { dragTypes } from './TileGrid'; @@ -21,11 +21,12 @@ type TileProps = { export const Tile: FunctionComponent = ({ charge, desk, disabled = false }) => { const addRecentApp = useRecentsStore((state) => state.addRecentApp); const { title, image, color, chad, href } = charge; - const vat = useVat(desk); + const pike = usePike(desk); const { lightText, tileColor, menuColor, suspendColor, suspendMenuColor } = useTileColor(color); const loading = !disabled && 'install' in chad; const suspended = disabled || 'suspend' in chad; const hung = 'hung' in chad; + // TODO should held zest be considered inactive? suspended? also, null sync? const active = !disabled && chadIsRunning(chad); const link = getAppHref(href); const backgroundColor = suspended ? suspendColor : active ? tileColor || 'purple' : suspendColor; @@ -56,6 +57,9 @@ export const Tile: FunctionComponent = ({ charge, desk, disabled = fa >
+ {pike?.zest === 'held' && !disabled && ( + + )} {!active && ( <> {loading && } @@ -65,9 +69,6 @@ export const Tile: FunctionComponent = ({ charge, desk, disabled = fa )}
- {vat?.arak.rail?.paused && !disabled && ( - - )} { const { desk } = useParams<{ desk: string }>(); const { push } = useHistory(); const charge = useCharge(desk); - const vat = useVat(desk); + const pike = usePike(desk); if (!charge) { return null; @@ -18,7 +18,7 @@ export const TileInfo = () => { return ( !open && push('/')}> - + ); diff --git a/pkg/interface/package-lock.json b/pkg/interface/package-lock.json index 9aa088012..517b38583 100644 Binary files a/pkg/interface/package-lock.json and b/pkg/interface/package-lock.json differ diff --git a/pkg/interface/src/views/apps/publish/components/Note.tsx b/pkg/interface/src/views/apps/publish/components/Note.tsx index 988e81eea..b5f7f5f2c 100644 --- a/pkg/interface/src/views/apps/publish/components/Note.tsx +++ b/pkg/interface/src/views/apps/publish/components/Note.tsx @@ -26,6 +26,7 @@ interface NoteProps { } export function NoteContent({ post }) { + console.log(post.contents); return ( diff --git a/pkg/landscape/app/contact-store.hoon b/pkg/landscape/app/contact-store.hoon index e3f750715..bac7cd9ec 100644 --- a/pkg/landscape/app/contact-store.hoon +++ b/pkg/landscape/app/contact-store.hoon @@ -123,7 +123,15 @@ :: ensure difference =/ old=(unit contact:store) (~(get by rolodex) ship) ?. ?| ?=(~ old) - !=(contact(last-updated *@da) u.old(last-updated *@da)) + :: if new contact is before existing contact, no-op + :: + :: NB: last-updated.contact is often *@da, so this + :: effectively stops add from applying if we already have + :: a contact for them + :: + ?& (gth last-updated.contact last-updated.u.old) + !=(contact(last-updated *@da) u.old(last-updated *@da)) + == == [~ state] ~| "cannot add a data url to cover!" diff --git a/pkg/landscape/app/graph-pull-hook.hoon b/pkg/landscape/app/graph-pull-hook.hoon index 1a134e614..364e0d00d 100644 --- a/pkg/landscape/app/graph-pull-hook.hoon +++ b/pkg/landscape/app/graph-pull-hook.hoon @@ -54,12 +54,7 @@ ++ on-pull-nack |= [=resource =tang] ^- (quip card _this) - %- (slog leaf+"nacked {}" tang) - :_ this - ?. (~(has in get-keys:gra) resource) ~ - =- [%pass /pull-nack %agent [our.bowl %graph-store] %poke %graph-update-3 -]~ - !> ^- update:store - [now.bowl [%archive-graph resource]] + `this :: ++ on-pull-kick |= =resource diff --git a/pkg/landscape/app/graph-store.hoon b/pkg/landscape/app/graph-store.hoon index 2e5db90fd..3170ead6e 100644 --- a/pkg/landscape/app/graph-store.hoon +++ b/pkg/landscape/app/graph-store.hoon @@ -11,16 +11,17 @@ [%3 network:one:store] [%4 network:store] [%5 network:store] - state-6 + [%6 network:store] + state-7 == ::- -+$ state-6 [%6 network:store] ++$ state-7 [%7 network:store] ++ orm orm:store ++ orm-log orm-log:store ++ mar %graph-update-3 -- :: -=| state-6 +=| state-7 =* state - :: %- agent:dbug @@ -96,7 +97,43 @@ (scag 2 (tap:orm-log update-log)) == :: - %6 [cards this(state old)] + %6 + =/ old-dms + %- ~(gas by *(map resource:store marked-graph:store)) + %+ skim ~(tap by graphs.old) + |=([r=resource:store *] (is-old-dm:upgrade:store r)) + =/ backup (backup:upgrade:store bowl) + %_ $ + -.old %7 + archive.old ~ + update-logs.old + %- ~(gas by *(map resource:store update-log:store)) + %+ murn ~(tap by update-logs.old) + |= [r=resource:store =update-log:store] + ?: (is-old-dm:upgrade:store r) + ~ + `[r (strip-sigs-log:upgrade:store update-log)] + :: + graphs.old + %- ~(gas by *(map resource:store marked-graph:store)) + %+ murn ~(tap by graphs.old) + |= [r=resource:store =graph:store mar=(unit mark)] + ?: (is-old-dm:upgrade:store r) + ~ + `[r (strip-sigs-graph:upgrade:store graph) mar] + :: + cards + ;: welp + cards + :: + (nuke-groups:upgrade:store bowl) + :: + (turn ~(tap by archive.old) backup) + (turn ~(tap by old-dms) backup) + == + == + :: + %7 [cards this(state old)] == :: ++ on-watch @@ -129,9 +166,21 @@ ?+ mark (on-poke:def mark vase) %graph-update-3 (graph-update !<(update:store vase)) %import (poke-import q.vase) + %migrated (poke-migrated !<(resource:store vase)) == [cards this] :: + ++ poke-migrated + |= r=resource:res + ^- (quip card _state) + =/ =path /(rap 3 'backup-' (scot %p entity.r) '-' name.r ~)/noun + =/ graph (~(got by graphs) r) + :- [%pass /migrate %agent [our.bowl %hood] %poke drum-put+!>([path (jam r graph)])]~ + %_ state + graphs (~(del by graphs) r) + update-logs (~(del by update-logs) r) + == + :: ++ graph-update |= =update:store ^- (quip card _state) @@ -644,6 +693,16 @@ |= =path ^- (unit (unit cage)) ?+ path (on-peek:def path) + [%x %whey ~] + =/ liv=(list mass) + (sort (turn ~(tap by graphs) |=([[* n=term] g=*] n^&+g)) aor) + =/ log=(list mass) + (sort (turn ~(tap by update-logs) |=([[* n=term] l=*] n^&+l)) aor) + =/ sil=(list mass) + (sort (turn ~(tap by archive) |=([[* n=term] g=*] n^&+g)) aor) + :^ ~ ~ %mass + !>(`(list mass)`[live+|+liv logs+|+log ?~(sil ~ [silo+|+sil ~])]) + :: [%x %export ~] ``noun+!>(state) :: [%x %keys ~] diff --git a/pkg/landscape/app/group-pull-hook.hoon b/pkg/landscape/app/group-pull-hook.hoon index f97582e70..aad34e33b 100644 --- a/pkg/landscape/app/group-pull-hook.hoon +++ b/pkg/landscape/app/group-pull-hook.hoon @@ -45,10 +45,7 @@ ++ on-pull-nack |= [=resource =tang] ^- (quip card _this) - %- (slog tang) - :_ this - =- [%pass / %agent [our.bowl %group-store] %poke -]~ - group-update-0+!>([%remove-group resource ~]) + `this :: ++ on-pull-kick |= =resource diff --git a/pkg/landscape/app/group-store.hoon b/pkg/landscape/app/group-store.hoon index f869a4c0a..c75814ec8 100644 --- a/pkg/landscape/app/group-store.hoon +++ b/pkg/landscape/app/group-store.hoon @@ -31,13 +31,16 @@ :: /- *group /+ store=group-store, default-agent, verb, dbug, resource, *migrate, agentio +/+ gladio |% +$ card card:agent:gall +++ ota-host ~sogryp-dister-dozzod-dozzod :: +$ versioned-state $% state-zero state-one state-two + state-three == :: +$ state-zero @@ -52,13 +55,19 @@ $: %2 =groups == +:: ++$ state-three + $: %3 + =groups + wait=(set ship) + == -- :: -=| state-two +=| state-three =* state - :: %- agent:dbug -%+ verb | +%+ verb & ^- agent:gall =< |_ =bowl:gall @@ -72,10 +81,24 @@ ++ on-load |= =old=vase =/ old !<(versioned-state old-vase) + =| cards=(list card) |^ - ?- -.old - %2 `this(state old) - :: + ?- -.old + %3 [(flop cards) this(state old)] + :: + %2 + %_ $ + old [%3 groups.old ~] + cards + %- welp + :_ cards + :~ [%pass /pyre/export %agent [our dap]:bowl %poke noun+!>(%export)] + [%pass /pyre/migrate %agent [our dap]:bowl %poke noun+!>(%migrate)] + [%pass / %agent [our %hood]:bowl %poke %kiln-install !>([%groups ota-host %groups])] + [%pass / %agent [our %hood]:bowl %poke %kiln-install !>([%talk ota-host %talk])] + == + == + :: %1 %_ $ -.old %2 @@ -112,6 +135,12 @@ =^ cards state ?+ mark (on-poke:def mark vase) %sane (poke-sane:gc !<(?(%check %fix) vase)) + :: + %noun + ?+ q.vase !! + %migrate poke-migrate:gc + %export poke-export:gc + == :: ?(%group-update-0 %group-action) (poke-group-update:gc !<(update:store vase)) @@ -125,6 +154,8 @@ |= =path ^- (quip card _this) ?> (team:title our.bowl src.bowl) + ?: ?=([%wait ~] path) + `this ?> ?=([%groups ~] path) :_ this [%give %fact ~ %group-update-0 !>([%initial groups])]~ @@ -135,6 +166,8 @@ |= =path ^- (unit (unit cage)) ?+ path (on-peek:def path) + [%x %wait ~] + ``ships+!>(~(tap in wait)) [%y %groups ~] ``noun+!>(`(set resource)`~(key by groups)) :: @@ -159,28 +192,38 @@ ++ on-agent |= [=wire =sign:agent:gall] ^- (quip card _this) - ?. ?=([%try-rejoin @ *] wire) - (on-agent:def wire sign) - ?> ?=(%poke-ack -.sign) - =/ rid=resource (de-path:resource t.t.wire) - ?~ p.sign - =/ =cage - [%pull-hook-action !>([%add entity.rid rid])] - :_ this - [%pass / %agent [our.bowl %group-pull-hook] %poke cage]~ - =/ nack-count=@ud (slav %ud i.t.wire) - =/ wakeup=@da - (add now.bowl (mul ~s1 (bex (min 19 nack-count)))) - :_ this - [%pass wire %arvo %b %wait wakeup]~ + =^ cards state + ?+ wire [- state]:(on-agent:def wire sign) + [%pyre *] (take-pyre:gc t.wire sign) + [%gladio @ ~] (take-migrate:gc sign) + :: + [%try-rejoin @ *] + ?> ?=(%poke-ack -.sign) + =/ rid=resource (de-path:resource t.t.wire) + ?~ p.sign + =/ =cage + [%pull-hook-action !>([%add entity.rid rid])] + :_ state + [%pass / %agent [our.bowl %group-pull-hook] %poke cage]~ + =/ nack-count=@ud (slav %ud i.t.wire) + =/ wakeup=@da + (add now.bowl (mul ~s1 (bex (min 19 nack-count)))) + :_ state + [%pass wire %arvo %b %wait wakeup]~ + == + [cards this] :: ++ on-arvo - |= [=wire =sign-arvo] + |= [=(pole knot) =sign-arvo] ^- (quip card _this) - ?. ?=([%try-rejoin @ *] wire) - (on-arvo:def wire sign-arvo) - =/ =resource (de-path:resource t.t.wire) - =/ nack-count=@ud (slav %ud i.t.wire) + ?: ?=([%gladio %backoff ship=@ ~] pole) + =^ cards state + (take-backoff:gc (slav %p ship.pole) sign-arvo) + [cards this] + ?. ?=([%try-rejoin count=@ res=*] pole) + (on-arvo:def pole sign-arvo) + =/ =resource (de-path:resource res.pole) + =/ nack-count=@ud (slav %ud count.pole) ?> ?=([%behn %wake *] sign-arvo) ~? ?=(^ error.sign-arvo) "behn errored in backoff timers, continuing anyway" @@ -192,6 +235,71 @@ :: |_ bol=bowl:gall +* io ~(. agentio bol) +++ poke-export + ^- (quip card _state) + :_ state + =; =cage + [%pass /export %agent [our.bol %hood] %poke cage]~ + drum-put+!>([/groups/jam ~(export gladio bol)]) +:: +++ poke-migrate + ^- (quip card _state) + =^ cards-1=(list card) wait + (~(migrate-start gladio bol) wait) + =/ cards-2=(list card) + (turn ~(tap in wait) watch-init-migrate) + =/ cards (welp cards-1 cards-2) + [cards state(wait wait)] +:: +++ watch-init-migrate + |= =ship + ^- card + [%pass /gladio/(scot %p ship) %agent [ship %groups] %watch /init] +:: +++ backoff-migrate + |= =ship + ^- card + [%pass /gladio/backoff/(scot %p ship) %arvo %b %wait (add ~h1 now.bol)] +:: +++ take-pyre + |= [=wire =sign:agent:gall] + ^- (quip card _state) + :_ state + ?> ?=(%poke-ack -.sign) + ?~ p.sign + ~ + [%pass / %pyre leaf/"{} failed" u.p.sign]~ +:: +++ take-backoff + |= [=ship sign=sign-arvo] + ^- (quip card _state) + ?> ?=([%behn %wake *] sign) + ?: ?=(^ error.sign) + `state + :_ state + ~[(watch-init-migrate ship)] +:: +++ take-migrate + |= =sign:agent:gall + ^- (quip card _state) + ?. (~(has in wait) src.bol) + :: already succeeded + `state + ?- -.sign + ?(%poke-ack %fact) `state + %kick :_(state (watch-init-migrate src.bol)^~) + %watch-ack + ?~ p.sign + :: they have public release + ~& migrating/src.bol + =. wait (~(del in wait) src.bol) + :_ state + :- [%give %fact ~[/wait] ships+!>(~(tap in wait))] + (~(migrate-ship gladio bol) src.bol) + :_ state + ~[(backoff-migrate src.bol)] + == +:: ++ peek-group |= rid=resource ^- (unit group) @@ -243,8 +351,8 @@ |= arc=* ^- (quip card _state) |^ - =/ sty=state-two - [%2 (remake-groups ;;((tree [resource tree-group]) +.arc))] + =/ sty=state-three + [%3 (remake-groups ;;((tree [resource tree-group]) +.arc)) ~] :_ sty %+ roll ~(tap by groups.sty) |= [[rid=resource grp=group] out=(list card)] diff --git a/pkg/landscape/app/metadata-pull-hook.hoon b/pkg/landscape/app/metadata-pull-hook.hoon index f2d08fd30..2877a098d 100644 --- a/pkg/landscape/app/metadata-pull-hook.hoon +++ b/pkg/landscape/app/metadata-pull-hook.hoon @@ -321,15 +321,7 @@ ++ on-pull-nack |= [=resource =tang] ^- (quip card _this) - =/ =associations:metadata - (metadata-for-group:met resource) - :_ this - %+ turn ~(tap by associations) - |= [=md-resource:metadata =association:metadata] - %+ poke-our:pass:io:hc %metadata-store - :- %metadata-update-2 - !> ^- update:metadata - [%remove resource md-resource] + `this :: ++ on-pull-kick |= =resource diff --git a/pkg/landscape/desk.bill b/pkg/landscape/desk.bill index a050ee619..573beb789 100644 --- a/pkg/landscape/desk.bill +++ b/pkg/landscape/desk.bill @@ -29,7 +29,6 @@ %metadata-hook %metadata-pull-hook %metadata-push-hook - %notify %observe-hook %sane %weather diff --git a/pkg/landscape/desk.docket-0 b/pkg/landscape/desk.docket-0 deleted file mode 100644 index e6b65c6ac..000000000 --- a/pkg/landscape/desk.docket-0 +++ /dev/null @@ -1,10 +0,0 @@ -:~ title+'Groups' - info+'A suite of applications to communicate on Urbit' - color+0xee.5432 - glob-http+['https://bootstrap.urbit.org/glob-0v7.2rpmd.966js.dt2sj.ggv4a.n15nq.glob' 0v7.2rpmd.966js.dt2sj.ggv4a.n15nq] - - base+'landscape' - version+[1 1 0] - website+'https://tlon.io' - license+'MIT' -== diff --git a/pkg/landscape/lib/gladio.hoon b/pkg/landscape/lib/gladio.hoon new file mode 100644 index 000000000..a46f3d968 --- /dev/null +++ b/pkg/landscape/lib/gladio.hoon @@ -0,0 +1,193 @@ +:: Migrate scripts +/- gra=graph-store +/- met=metadata-store +/- grp=group-store +/- i=migrate +/- *group +|_ =bowl:gall ++$ card card:agent:gall +:: if false, indicates that OTA should be done in one go, in order to +:: allow for testing on partial testnets +++ split-ota & +++ import-club + |= [=^groups =associations:met =network:gra] + %- ~(gas by *imports:club:i) + %+ murn ~(tap by graphs.network) + |= [=flag:i graph=graph:gra mar=(unit mark)] + ^- (unit [flag:i import:club:i]) + ?. =(mar `%graph-validator-chat) + ~ + ?~ assoc=(~(get by associations) [%graph flag]) + ~& missing-assoc-club/flag + ~ + ?~ group=(~(get by groups) group.u.assoc) + ~& missing-group/[flag group.u.assoc] + ~ + ?. hidden.u.group + ~ + `[flag members.u.group u.assoc graph] +:: +++ import-flags + |= [our=ship =^groups =associations:met =network:gra] + |= =mark + ^- (set flag:i) + %- ~(gas in *(set flag:i)) + %+ skim + ~(tap in ~(key by ((import-for-mark ~ groups associations network) mark))) + |= =flag:i + !=(our p.flag) +:: +++ import-for-mark + |= [her=(unit ship) =^groups =associations:met =network:gra] + |= =mark + ^- imports:graph:i + %- ~(gas by *imports:graph:i) + %+ murn ~(tap by graphs.network) + |= [=flag:i graph=graph:gra mar=(unit ^mark)] + ?. |(=(`p.flag her) =(her ~)) + ~ + ?. =(mar `mark) :: XX: correct detection? + ~ + ?~ assoc=(~(get by associations) [%graph flag]) + ~& missing-assoc/flag^mark + ~ + ?~ group=(~(get by groups) group.u.assoc) + ~& missing-group/[flag group.u.assoc] + ~ + ?: hidden.u.group + ~ + =/ writers=(set ship) + (~(get ju tags.u.group) %graph flag %writers) + ?~ log=(~(get by update-logs.network) flag) + ~& missing-log/flag :: XX: doesn't need to fail, but suspect case + ~ + `[flag writers u.assoc u.log graph] + +++ scry + |= [=dude:gall =path] + %- welp + :_ path + /gx/(scot %p our.bowl)/[dude]/(scot %da now.bowl) +++ groups + ~+ .^([@ =^groups *] (scry %group-store /export/noun)) +++ groups-raw + .^(* (scry %group-store /export/noun)) +++ network + ~+ .^([@ =network:gra] (scry %graph-store /export/noun)) +++ network-raw + .^(* (scry %graph-store /export/noun)) +++ associations + ~+ .^([@ =associations:met ~] (scry %metadata-store /export/noun)) +++ associations-raw + .^(* (scry %metadata-store /export/noun)) +++ export + %- jam + ^- * + :~ [%group-store groups-raw] + [%metadata-store associations-raw] + == +++ peers + |= =network:gra + =- (~(del in -) our.bowl) + %- ~(gas in *(set ship)) + (turn ~(tap in ~(key by graphs.network)) head) +++ poke-our + |= [=dude:gall =cage] + [%pass /gladio %agent [our.bowl dude] %poke cage] +++ migrate-start + |= wait=(set ship) + ^- (quip card (set ship)) + =+ network + =+ associations + =+ groups + =/ ships (peers network) + =/ dms (~(get by graphs:network) [our.bowl %dm-inbox]) + =/ import (import-for-mark `our.bowl groups associations network) + =/ clubs (import-club groups associations network) + =/ chats=imports:graph:i + (import %graph-validator-chat) + =/ diarys=imports:graph:i + (import %graph-validator-publish) + =/ links=imports:graph:i + (import %graph-validator-link) + =/ =imports:groups:i + %- ~(gas by *imports:groups:i) + %+ murn ~(tap by groups) + |= [=flag:i =group] + ^- (unit [_flag import:groups:i]) + ?: hidden.group + ~ + ?~ assoc=(~(get by associations) [%groups flag]) + ~& missing-group-assoc/flag + ~ + =/ chans=(map flag:i association:met) + %- ~(gas by *(map flag:i association:met)) + %+ murn ~(tap by associations) + |= [res=md-resource:met ass=association:met] + ^- (unit [flag:i association:met]) + ?. =(group.ass flag) ~ + `[resource.res ass] + =/ roles=(set flag:i) + %- ~(gas in *(set flag:i)) + %+ murn ~(tap by chans) + |= [=flag:i =association:met] + ^- (unit flag:i) + ?^ link=(~(get by links) flag) + ?: =(writers.u.link ~) ~ + `flag + ?^ diary=(~(get by diarys) flag) + ?: =(writers.u.diary ~) ~ + `flag + ?^ chat=(~(get by chats) flag) + ?: =(writers.u.chat ~) ~ + `flag + ~ + `[flag u.assoc chans roles group] + =/ dms (~(get by graphs:network) [our.bowl %dm-inbox]) + =/ flag-importer (import-flags our.bowl groups associations network) + =+ :* chat-flags=(flag-importer %graph-validator-chat) + heap-flags=(flag-importer %graph-validator-link) + diary-flags=(flag-importer %graph-validator-publish) + == + =/ setup=(list card) + %+ welp (migrate-ship our.bowl) + :* (poke-our %groups group-import+!>(imports)) + (poke-our %chat import-flags+!>(chat-flags)) + (poke-our %heap import-flags+!>(heap-flags)) + (poke-our %diary import-flags+!>(diary-flags)) + (poke-our %chat club-imports+!>(clubs)) + ?~ dms ~ + (poke-our %chat dm-imports+!>(p.u.dms))^~ + == + ?. split-ota + :_ ~ + (welp setup (zing (turn ~(tap in (~(del in ships) our.bowl)) migrate-ship))) + [setup (~(uni in ships) wait)] +:: +++ migrate-ship + |= her=ship + ^- (list card) + =+ groups + =+ network + =+ associations + =/ import (import-for-mark `her groups associations network) + =/ chats=imports:graph:i + (import %graph-validator-chat) + =/ diarys=imports:graph:i + (import %graph-validator-publish) + =/ links=imports:graph:i + (import %graph-validator-link) + =/ graph-flags + %. ~(key by links) + =- ~(uni in -) + (~(uni in ~(key by chats)) ~(key by diarys)) + %+ welp + %+ turn ~(tap in graph-flags) + |= =flag:i + ^- card + (poke-our %graph-store migrated+!>(flag)) + :~ (poke-our %chat graph-imports+!>(chats)) + (poke-our %diary graph-imports+!>(diarys)) + (poke-our %heap graph-imports+!>(links)) + == +-- diff --git a/pkg/landscape/lib/graph-store.hoon b/pkg/landscape/lib/graph-store.hoon index df11d0349..d81afb866 100644 --- a/pkg/landscape/lib/graph-store.hoon +++ b/pkg/landscape/lib/graph-store.hoon @@ -528,6 +528,81 @@ :: ++ upgrade |% + ++ is-old-dm |=(r=resource =('dm--' (end [3 4] name.r))) + ++ backup + |= =bowl:gall + |= [r=resource m=marked-graph] + ^- card:agent:gall + =/ pax /(rap 3 'archive-' (scot %p entity.r) '-' name.r ~)/noun + =/ =cage drum-put+!>([pax (jam r m)]) + [%pass /archive %agent [our.bowl %hood] %poke cage] + ++ strip-sigs-graph + |= g=graph + ^+ g + =* loop $ + %+ gas:orm *graph + %+ turn (tap:orm g) + |= [key=@ val=node] :: optional: also strip out deleted messages? + =? children.val ?=(%graph -.children.val) + [%graph loop(g p.children.val)] + :- key + ?. ?=(%& -.post.val) + val + val(signatures.p.post ~) + ++ strip-sigs-log + |= u=update-log + %+ gas:orm-log *update-log + %+ turn (tap:orm-log u) + |= [key=@ upd=logged-update] + :- key + :- p.upd + ?+ -.q.upd q.upd + %add-graph + q.upd(graph (strip-sigs-graph graph.q.upd)) + :: + %add-signatures + q.upd(signatures ~) + :: + %remove-signatures + q.upd(signatures ~) + :: + %add-nodes + %= q.upd + nodes + %- ~(run by nodes.q.upd) + |= =node + ^+ node + %= node + children + ?. ?=(%graph -.children.node) + children.node + [%graph (strip-sigs-graph p.children.node)] + :: + post + ?. ?=(%& -.post.node) + post.node + =. signatures.p.post.node ~ + post.node + == + == + == + :: + ++ nuke-groups + |= =bowl:gall + |^ ^- (list card:agent:gall) + ?. .^(? (gall-scry %u %groups)) + ~ + =+ .^(=desk (gall-scry %d %groups)) + :~ [%pass /nuke %agent [our.bowl %hood] %poke kiln-nuke+!>([desk &])] + [%pass /nuke %agent [our.bowl %docket] %poke docket-uninstall+!>(desk)] + [%pass /nuke %agent [our.bowl %docket] %poke docket-uninstall+!>(%talk)] + == + :: + ++ gall-scry + |= [=care:clay dap=dude:gall] + ^- path + /(cat 3 %g care)/(scot %p our.bowl)/[dap]/(scot %da now.bowl) + -- :: :: +two :: @@ -758,9 +833,9 @@ -- ++ import |= [arc=* our=ship] - ^- (quip card:agent:gall [%6 network]) + ^- (quip card:agent:gall [%7 network]) |^ - =/ sty [%6 (remake-network ;;(tree-network +.arc))] + =/ sty [%7 (remake-network ;;(tree-network +.arc))] :_ sty %+ turn ~(tap by graphs.sty) |= [rid=resource =marked-graph] diff --git a/pkg/landscape/sur/migrate.hoon b/pkg/landscape/sur/migrate.hoon new file mode 100644 index 000000000..3bf567298 --- /dev/null +++ b/pkg/landscape/sur/migrate.hoon @@ -0,0 +1,23 @@ +/- met=metadata-store, gra=graph-store +/- *group +|% ++$ flag (pair ship term) +++ graph + |% + +$ import + [writers=(set ship) =association:met =update-log:gra =graph:gra] + +$ imports (map flag import) + -- +:: +++ groups + |% + +$ import [=association:met chans=(map flag =association:met) roles=(set flag) =group] + +$ imports (map flag import) + -- +++ club + |% + +$ import [ships=(set ship) =association:met =graph:gra] + +$ imports (map flag import) + -- +-- + diff --git a/pkg/landscape/sys.kelvin b/pkg/landscape/sys.kelvin index e77a3de08..b7bcb9ecd 100644 --- a/pkg/landscape/sys.kelvin +++ b/pkg/landscape/sys.kelvin @@ -1 +1 @@ -[%zuse 418] +[%zuse 417] diff --git a/pkg/landscape/ted/graph/recover-archive.hoon b/pkg/landscape/ted/graph/recover-archive.hoon new file mode 100644 index 000000000..455ee9feb --- /dev/null +++ b/pkg/landscape/ted/graph/recover-archive.hoon @@ -0,0 +1,19 @@ +/- spider, graph=graph-store, met=metadata-store, *group, group-store, push-hook +/+ strandio, resource, graph-view +=> +|% +++ strand strand:spider +++ poke poke:strandio +++ poke-our poke-our:strandio +-- +=, strand=strand:spider +^- thread:spider +|= arg=vase +=/ m (strand ,vase) +^- form:m +=+ !<([~ pax=path] arg) +;< =bowl:spider bind:m get-bowl:strandio +=+ .^([rid=resource mar=marked-graph:graph] %cx pax) +;< ~ bind:m + (poke-our:strandio %graph-store %graph-update-3 !>([now.bowl %add-graph p.mar q.mar &])) +(pure:m *vase) diff --git a/pkg/landscape/ted/keep.hoon b/pkg/landscape/ted/keep.hoon new file mode 100644 index 000000000..3eb758cae --- /dev/null +++ b/pkg/landscape/ted/keep.hoon @@ -0,0 +1,14 @@ +/- spider, docket +/+ strandio +=, strand=strand:spider +^- thread:spider +|= arg=vase +=/ m (strand ,vase) +^- form:m +=+ !<(jim=@ arg) +;< =bowl:spider bind:m get-bowl:strandio +=/ home=path /(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl) +=/ =path /(cat 3 'backup-' (scot %da now.bowl))/noun + :: XX remove prints +;< ~ bind:m (poke-our:strandio %hood drum-put+!>([path jim])) +(pure:m *vase) diff --git a/pkg/landscape/ted/migrate.hoon b/pkg/landscape/ted/migrate.hoon new file mode 100644 index 000000000..ab92d379f --- /dev/null +++ b/pkg/landscape/ted/migrate.hoon @@ -0,0 +1,91 @@ +:: Migrate scripts +/- spider +/- gra=graph-store +/- met=metadata-store +/- grp=group-store +/- i=migrate +/- *group +/+ strandio +=, strand=strand:spider +|% +++ import-for-mark + |= [=groups =associations:met =network:gra] + |= =mark + ^- imports:graph:i + %- ~(gas by *imports:graph:i) + %+ murn ~(tap by graphs.network) + |= [=flag:i graph=graph:gra mar=(unit ^mark)] + ?. =(mar `mark) :: XX: correct detection? + ~ + ?~ assoc=(~(get by associations) [%graph flag]) + ~& missing-assoc/flag^mark + ~ + ?~ group=(~(get by groups) group.u.assoc) + ~& missing-group/[flag group.u.assoc] + ~ + =/ writers=(set ship) + (~(get ju tags.u.group) %graph flag %writers) + ?~ log=(~(get by update-logs.network) flag) + ~& missing-log/flag :: XX: doesn't need to fail, but suspect case + ~ + `[flag writers u.assoc u.log graph] +:: +-- +^- thread:spider +|= arg=vase +=/ m (strand ,vase) +^- form:m +;< =bowl:spider bind:m get-bowl:strandio +;< [%2 =groups] bind:m + (scry:strandio ,[%2 =groups] /gx/group-store/export/noun) +;< [%6 =network:gra] bind:m + (scry:strandio ,[%6 =network:gra] /gx/graph-store/export/noun) +;< =associations:met bind:m + (scry:strandio ,associations:met /gx/metadata-store/associations/noun) +=/ import (import-for-mark groups associations network) +=/ chats=imports:graph:i + (import %graph-validator-chat) +=/ diarys=imports:graph:i + (import %graph-validator-publish) +=/ links=imports:graph:i + (import %graph-validator-link) +=/ =imports:groups:i + %- ~(gas by *imports:groups:i) + %+ murn ~(tap by groups) + |= [=flag:i =group] + ^- (unit [_flag import:groups:i]) + ?~ assoc=(~(get by associations) [%groups flag]) + ~& missing-group-assoc/flag + ~ + =/ chans=(map flag:i association:met) + %- ~(gas by *(map flag:i association:met)) + %+ murn ~(tap by associations) + |= [res=md-resource:met ass=association:met] + ^- (unit [flag:i association:met]) + ?. =(group.ass flag) ~ + `[resource.res ass] + =/ roles=(set flag:i) + %- ~(gas in *(set flag:i)) + %+ murn ~(tap by chans) + |= [=flag:i =association:met] + ^- (unit flag:i) + ?^ link=(~(get by links) flag) + ?: =(writers.u.link ~) ~ + `flag + ?^ diary=(~(get by diarys) flag) + ?: =(writers.u.diary ~) ~ + `flag + ?^ chat=(~(get by chats) flag) + ?: =(writers.u.chat ~) ~ + `flag + ~ + `[flag u.assoc chans roles group] +;< ~ bind:m (poke-our:strandio %groups group-import+!>(imports)) +;< ~ bind:m (poke-our:strandio %chat graph-imports+!>(chats)) +;< ~ bind:m (poke-our:strandio %diary graph-imports+!>(diarys)) +;< ~ bind:m (poke-our:strandio %heap graph-imports+!>(links)) +;< ~ bind:m + ?~ dms=(~(get by graphs.network) [our.bowl %dm-inbox]) + (pure:(strand ,~) ~) + (poke-our:strandio %chat %dm-imports !>(p.u.dms)) +(pure:m *vase) diff --git a/pkg/npm/api/hood/lib.ts b/pkg/npm/api/hood/lib.ts index 6596d2924..02d868681 100644 --- a/pkg/npm/api/hood/lib.ts +++ b/pkg/npm/api/hood/lib.ts @@ -1,9 +1,9 @@ import { Poke, Scry } from '../lib'; -import { Vats, Vat } from './types'; +import { Pike } from './types'; -export const getVats: Scry = { +export const getPikes: Scry = { app: 'hood', - path: '/kiln/vats' + path: '/kiln/pikes' }; /** @@ -25,6 +25,44 @@ export function kilnInstall( }; } +/** + * Sync with a foreign desk + */ +export function kilnSync( + ship: string, + desk: string, + local?: string +): Poke { + return { + app: 'hood', + mark: 'kiln-sync', + json: { + ship, + desk, + local: local || desk + } + }; +} + +/** + * Unsync with a foreign desk + */ +export function kilnUnsync( + ship: string, + desk: string, + local?: string +): Poke { + return { + app: 'hood', + mark: 'kiln-unsync', + json: { + ship, + desk, + local: local || desk + } + }; +} + /** * Uninstall a desk */ @@ -58,14 +96,11 @@ export function kilnRevive( }; } -export function kilnBump(force = false, except = [] as string[]) { +export function kilnBump(): Poke { return { app: 'hood', mark: 'kiln-bump', - json: { - force, - except - } + json: null, }; } @@ -87,35 +122,6 @@ export function kilnResume(desk: string) { export const scryLag: Scry = ({ app: 'hood', path: '/kiln/lag' }); -export function getBlockers(vats: Vats): string[] { - const blockers: string[] = []; - const base = vats?.base; - if(!base) { - return blockers; - } - const blockedOn = base.arak.rail?.next?.[0]?.weft?.kelvin; - if(!blockedOn) { - return blockers; - } - - Object.entries(vats) - .filter(([desk]) => desk !== 'base') - .forEach(([desk, vat]) => { - // assuming only %zuse - const woofs = vat.arak.rail?.next || []; - const kelvins = woofs.map(n => n.weft.kelvin); - if(!(kelvins.includes(blockedOn))) { - blockers.push(desk); - } - }); - - return blockers; -} - -export function getVatPublisher(vat: Vat): string | undefined { - if (vat.arak.rail) { - const { rail } = vat.arak; - return (rail?.publisher || rail?.ship || undefined); - } - return undefined; +export function getPikePublisher(pike: Pike) { + return pike.sync?.ship; } diff --git a/pkg/npm/api/hood/types.ts b/pkg/npm/api/hood/types.ts index 5cf52fc76..17676b47a 100644 --- a/pkg/npm/api/hood/types.ts +++ b/pkg/npm/api/hood/types.ts @@ -161,3 +161,48 @@ export interface Vat { export interface Vats { [desk: string]: Vat; } +/** + * TODO: crisp one-liner describing a Pike + */ +export interface Pike { + /** + * Hash of the desk, rendered as `@uv` + * + * @remarks + * Equivalent to + * ```hoon + * .^(@uv %cz /=desk=) + * ``` + */ + hash: string; + sync: { + /** + * Source desk for this Pike + */ + desk: string; + /** + * Source ship for this Pike + */ + ship: string; + } | null; + /** + * {@link Weft}s associated with this Pike + */ + wefts: Weft[]; + /** + * how live is this pike? + * + * live - app is running + * held - app is not running, but is trying to run. this state can be entered + * in two main ways: + * - when installing an app but it hasn't finished downloading (or it did + * but failed to install for some reason) + * - when user forced a kelvin upgrade by suspending desks. + * dead - app is not running + */ + zest: "live" | "dead" | "held"; +} + +export interface Pikes { + [desk: string]: Pike; +} diff --git a/pkg/npm/api/package-lock.json b/pkg/npm/api/package-lock.json index b4a46ab92..5fc544281 100644 Binary files a/pkg/npm/api/package-lock.json and b/pkg/npm/api/package-lock.json differ diff --git a/pkg/npm/api/package.json b/pkg/npm/api/package.json index 88caa2f89..9c3d70f36 100644 --- a/pkg/npm/api/package.json +++ b/pkg/npm/api/package.json @@ -1,6 +1,6 @@ { "name": "@urbit/api", - "version": "2.1.1", + "version": "2.2.0", "description": "A library that provides bindings and types for Urbit's various userspace desks", "repository": { "type": "git", diff --git a/pkg/npm/http-api/package-lock.json b/pkg/npm/http-api/package-lock.json index 40aff042c..8a12743f1 100644 Binary files a/pkg/npm/http-api/package-lock.json and b/pkg/npm/http-api/package-lock.json differ diff --git a/pkg/urbit/bench/ur_bench.c b/pkg/urbit/bench/ur_bench.c index 40a4e518c..4c0151357 100644 --- a/pkg/urbit/bench/ur_bench.c +++ b/pkg/urbit/bench/ur_bench.c @@ -7,8 +7,9 @@ static void _setup(void) { - u3m_init(); + u3m_init(1 << 24); u3m_pave(c3y); + u3e_init(); } /* _ames_writ_ex(): |hi packet from fake ~zod to fake ~nec diff --git a/pkg/urbit/daemon/main.c b/pkg/urbit/daemon/main.c index fffb76262..1853ed871 100644 --- a/pkg/urbit/daemon/main.c +++ b/pkg/urbit/daemon/main.c @@ -4,6 +4,8 @@ #define U3_GLOBAL #define C3_GLOBAL #include "all.h" +#include "vere/ivory.h" +#include "ur/ur.h" #include "rsignal.h" #include #include "vere/vere.h" @@ -164,6 +166,9 @@ _main_init(void) u3_Host.ops_u.puf_c = "jam"; u3_Host.ops_u.hap_w = 50000; u3_Host.ops_u.kno_w = DefaultKernel; + + u3_Host.ops_u.lut_y = u3a_bits + 1; + u3_Host.ops_u.lom_y = u3a_bits + 1; } /* _main_pier_run(): get pier from binary path (argv[0]), if appropriate @@ -216,6 +221,7 @@ _main_getopt(c3_i argc, c3_c** argv) { "json-trace", no_argument, NULL, 'j' }, { "kernel-stage", required_argument, NULL, 'K' }, { "key-file", required_argument, NULL, 'k' }, + { "loom", required_argument, NULL, c3__loom }, { "local", no_argument, NULL, 'L' }, { "lite-boot", no_argument, NULL, 'l' }, { "replay-to", required_argument, NULL, 'n' }, @@ -238,6 +244,9 @@ _main_getopt(c3_i argc, c3_c** argv) { "exit", no_argument, NULL, 'x' }, { "scry-into", required_argument, NULL, 'Y' }, { "scry-format", required_argument, NULL, 'Z' }, + // + { "urth-loom", required_argument, NULL, 5 }, + // { NULL, 0, NULL, 0 }, }; @@ -246,6 +255,17 @@ _main_getopt(c3_i argc, c3_c** argv) lop_u, &lid_i)) ) { switch ( ch_i ) { + case 5: { // urth-loom + c3_w lut_w; + c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lut_w); + if ( (c3n == res_o) || (lut_w < 20) ) { + fprintf(stderr, "error: --urth-loom must be >= 20 and <= %u\r\n", u3a_bits + 2); + return c3n; + } + + u3_Host.ops_u.lut_y = lut_w; + break; + } case 'X': { u3_Host.ops_u.pek_c = strdup(optarg); break; @@ -346,6 +366,16 @@ _main_getopt(c3_i argc, c3_c** argv) } else u3_Host.ops_u.pes_s = arg_w; break; } + case c3__loom: { + c3_w lom_w; + c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w); + if ( (c3n == res_o) || (lom_w < 20) ) { + fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2); + return c3n; + } + u3_Host.ops_u.lom_y = lom_w; + break; + } case c3__noco: { u3_Host.ops_u.con = c3n; break; @@ -660,6 +690,7 @@ u3_ve_usage(c3_i argc, c3_c** argv) "-K, --kernel-stage STAGE Start at Hoon kernel version stage\n", "-k, --key-file KEYS Private key file (see also -G)\n", "-L, --local Local networking only\n", + " --loom Set loom to binary exponent (31 == 2GB)\n" "-l, --lite-boot Most-minimal startup\n", "-n, --replay-to NUMBER Replay up to event\n", "-P, --profile Profiling\n", @@ -997,9 +1028,9 @@ static void _cw_serf_commence(c3_i argc, c3_c* argv[]) { #ifdef U3_OS_mingw - if ( 8 > argc ) { + if ( 9 > argc ) { #else - if ( 7 > argc ) { + if ( 8 > argc ) { #endif fprintf(stderr, "serf: missing args\n"); exit(1); @@ -1011,9 +1042,11 @@ _cw_serf_commence(c3_i argc, c3_c* argv[]) c3_c* key_c = argv[3]; // XX use passkey c3_c* wag_c = argv[4]; c3_c* hap_c = argv[5]; - c3_c* eve_c = argv[6]; + c3_c* lom_c = argv[6]; + c3_w lom_w; + c3_c* eve_c = argv[7]; #ifdef U3_OS_mingw - c3_c* han_c = argv[7]; + c3_c* han_c = argv[8]; _cw_intr_win(han_c); #endif @@ -1039,6 +1072,7 @@ _cw_serf_commence(c3_i argc, c3_c* argv[]) { sscanf(wag_c, "%" SCNu32, &u3C.wag_w); sscanf(hap_c, "%" SCNu32, &u3_Host.ops_u.hap_w); + sscanf(lom_c, "%" SCNu32, &lom_w); if ( 1 != sscanf(eve_c, "%" PRIu64, &eve_d) ) { fprintf(stderr, "serf: rock: invalid number '%s'\r\n", argv[4]); @@ -1062,7 +1096,7 @@ _cw_serf_commence(c3_i argc, c3_c* argv[]) // { u3V.dir_c = strdup(dir_c); - u3V.sen_d = u3V.dun_d = u3m_boot(dir_c); + u3V.sen_d = u3V.dun_d = u3m_boot(dir_c, (size_t)1 << lom_w); if ( eve_d ) { // XX need not be fatal, need a u3m_reboot equivalent @@ -1152,6 +1186,117 @@ _cw_dock(c3_i argc, c3_c* argv[]) u3_king_dock(U3_VERE_PACE); } +/* _cw_eval_get_input(): read file til EOF and return a malloc'd string +*/ +c3_c* +_cw_eval_get_input(FILE* fil_u, size_t siz_i) +{ + c3_i car_i; + size_t len_i = 0; + c3_c* str_c = c3_realloc(NULL, siz_i);//size is start size + + while( EOF != (car_i = fgetc(fil_u)) ){ + str_c[len_i++] = car_i; + if( len_i == siz_i ){ + siz_i += 16; + str_c = c3_realloc(str_c, siz_i); + } + } + + str_c[len_i++]='\0'; + + return c3_realloc(str_c, len_i); +} + +/* _cw_eval(): initialize and run the hoon evaluator +*/ +static void +_cw_eval(c3_i argc, c3_c* argv[]) +{ + c3_i ch_i, lid_i; + c3_w arg_w; + + static struct option lop_u[] = { + { "loom", required_argument, NULL, c3__loom }, + { NULL, 0, NULL, 0 } + }; + + while ( -1 != (ch_i=getopt_long(argc, argv, "", lop_u, &lid_i)) ) { + switch ( ch_i ) { + case c3__loom: { + c3_w lom_w; + c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w); + if ( (c3n == res_o) || (lom_w < 20) ) { + fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2); + exit(1); + } + u3_Host.ops_u.lom_y = lom_w; + } break; + + case '?': { + fprintf(stderr, "invalid argument\r\n"); + exit(1); + } break; + } + } + + // argv[optind] is always "eval" + // + + if ( optind + 1 != argc ) { + fprintf(stderr, "invalid command\r\n"); + exit(1); + } + + c3_c* evl_c = _cw_eval_get_input(stdin, 10); + + // initialize the Loom and load the Ivory Pill + // + { + c3_d len_d = u3_Ivory_pill_len; + c3_y* byt_y = u3_Ivory_pill; + u3_cue_xeno* sil_u; + u3_weak pil; + + u3C.wag_w |= u3o_hashless; + u3m_boot_lite((size_t)1 << u3_Host.ops_u.lom_y); + sil_u = u3s_cue_xeno_init_with(ur_fib27, ur_fib28); + if ( u3_none == (pil = u3s_cue_xeno_with(sil_u, len_d, byt_y)) ) { + printf("lite: unable to cue ivory pill\r\n"); + exit(1); + } + u3s_cue_xeno_done(sil_u); + if ( c3n == u3v_boot_lite(pil) ) { + u3l_log("lite: boot failed\r\n"); + exit(1); + } + } + + printf("eval:\n"); + + // +wish for an eval gate (virtualized twice for pretty-printing) + // + u3_noun gat = u3v_wish("|=(a=@t (sell (slap !>(+>.$) (rain /eval a))))"); + u3_noun res; + { + u3_noun sam = u3i_string(evl_c); + u3_noun cor = u3nc(u3k(u3h(gat)), u3nc(sam, u3k(u3t(u3t(gat))))); + res = u3m_soft(0, u3n_kick_on, cor); + } + + + if ( 0 == u3h(res) ) { // successful execution, print output + u3_pier_tank(0, 0, u3k(u3t(res))); + } + else { // error, print stack trace + u3_pier_punt_goof("eval", u3k(res)); + } + + u3z(res); + u3z(gat); + free(evl_c); +} + /* _cw_info(): print pier info */ static void @@ -1175,7 +1320,7 @@ _cw_info(c3_i argc, c3_c* argv[]) } break; } - c3_d eve_d = u3m_boot(u3_Host.dir_c); + c3_d eve_d = u3m_boot(u3_Host.dir_c, u3a_bytes); u3_disk* log_u = _cw_disk_init(u3_Host.dir_c); fprintf(stderr, "\r\nurbit: %s at event %" PRIu64 "\r\n", @@ -1212,7 +1357,7 @@ _cw_grab(c3_i argc, c3_c* argv[]) } break; } - u3m_boot(u3_Host.dir_c); + u3m_boot(u3_Host.dir_c, u3a_bytes); u3C.wag_w |= u3o_hashless; u3_serf_grab(); u3m_stop(); @@ -1223,25 +1368,56 @@ _cw_grab(c3_i argc, c3_c* argv[]) static void _cw_cram(c3_i argc, c3_c* argv[]) { - switch ( argc ) { - case 2: { - if ( !(u3_Host.dir_c = _main_pier_run(argv[0])) ) { - fprintf(stderr, "unable to find pier\r\n"); - exit (1); - } - } break; + c3_i ch_i, lid_i; + c3_w arg_w; - case 3: { - u3_Host.dir_c = argv[2]; - } break; + static struct option lop_u[] = { + { "loom", required_argument, NULL, c3__loom }, + { NULL, 0, NULL, 0 } + }; - default: { - fprintf(stderr, "invalid command\r\n"); - exit(1); - } break; + u3_Host.dir_c = _main_pier_run(argv[0]); + + while ( -1 != (ch_i=getopt_long(argc, argv, "", lop_u, &lid_i)) ) { + switch ( ch_i ) { + case c3__loom: { + c3_w lom_w; + c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w); + if ( (c3n == res_o) || (lom_w < 20) ) { + fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2); + exit(1); + } + u3_Host.ops_u.lom_y = lom_w; + } break; + + case '?': { + fprintf(stderr, "invalid argument\r\n"); + exit(1); + } break; + } } - c3_d eve_d = u3m_boot(u3_Host.dir_c); + // argv[optind] is always "cram" + // + + if ( !u3_Host.dir_c ) { + if ( optind + 1 < argc ) { + u3_Host.dir_c = argv[optind + 1]; + } + else { + fprintf(stderr, "invalid command, pier required\r\n"); + exit(1); + } + + optind++; + } + + if ( optind + 1 != argc ) { + fprintf(stderr, "invalid command\r\n"); + exit(1); + } + + c3_d eve_d = u3m_boot(u3_Host.dir_c, (size_t)1 << u3_Host.ops_u.lom_y); u3_disk* log_u = _cw_disk_init(u3_Host.dir_c); // XX s/b try_aquire lock c3_o ret_o; @@ -1271,29 +1447,58 @@ _cw_cram(c3_i argc, c3_c* argv[]) static void _cw_queu(c3_i argc, c3_c* argv[]) { + c3_i ch_i, lid_i; + c3_w arg_w; + + static struct option lop_u[] = { + { "loom", required_argument, NULL, c3__loom }, + { NULL, 0, NULL, 0 } + }; + + u3_Host.dir_c = _main_pier_run(argv[0]); + + while ( -1 != (ch_i=getopt_long(argc, argv, "", lop_u, &lid_i)) ) { + switch ( ch_i ) { + case c3__loom: { + c3_w lom_w; + c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w); + if ( (c3n == res_o) || (lom_w < 20) ) { + fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2); + exit(1); + } + u3_Host.ops_u.lom_y = lom_w; + } break; + + case '?': { + fprintf(stderr, "invalid argument\r\n"); + exit(1); + } break; + } + } + + // argv[optind] is always "queu" + // + + if ( !u3_Host.dir_c ) { + if ( optind + 1 < argc ) { + u3_Host.dir_c = argv[optind + 1]; + } + else { + fprintf(stderr, "invalid command, pier required\r\n"); + exit(1); + } + + optind++; + } + + if ( optind + 1 != argc ) { + fprintf(stderr, "invalid command\r\n"); + exit(1); + } + c3_c* eve_c; c3_d eve_d; - switch ( argc ) { - case 3: { - if ( !(u3_Host.dir_c = _main_pier_run(argv[0])) ) { - fprintf(stderr, "unable to find pier\r\n"); - exit (1); - } - eve_c = argv[2]; - } break; - - case 4: { - u3_Host.dir_c = argv[2]; - eve_c = argv[3]; - } break; - - default: { - fprintf(stderr, "invalid command\r\n"); - exit(1); - } break; - } - if ( 1 != sscanf(eve_c, "%" PRIu64 "", &eve_d) ) { fprintf(stderr, "urbit: queu: invalid number '%s'\r\n", eve_c); exit(1); @@ -1303,7 +1508,7 @@ _cw_queu(c3_i argc, c3_c* argv[]) fprintf(stderr, "urbit: queu: preparing\r\n"); - u3m_boot(u3_Host.dir_c); + u3m_boot(u3_Host.dir_c, (size_t)1 << u3_Host.ops_u.lom_y); // XX can spuriously fail do to corrupt memory-image checkpoint, // need a u3m_half_boot equivalent @@ -1327,29 +1532,60 @@ _cw_queu(c3_i argc, c3_c* argv[]) static void _cw_meld(c3_i argc, c3_c* argv[]) { - switch ( argc ) { - case 2: { - if ( !(u3_Host.dir_c = _main_pier_run(argv[0])) ) { - fprintf(stderr, "unable to find pier\r\n"); - exit (1); - } - } break; + c3_i ch_i, lid_i; + c3_w arg_w; - case 3: { - u3_Host.dir_c = argv[2]; - } break; + static struct option lop_u[] = { + { "loom", required_argument, NULL, c3__loom }, + { NULL, 0, NULL, 0 } + }; - default: { - fprintf(stderr, "invalid command\r\n"); + u3_Host.dir_c = _main_pier_run(argv[0]); + + while ( -1 != (ch_i=getopt_long(argc, argv, "", lop_u, &lid_i)) ) { + switch ( ch_i ) { + case c3__loom: { + c3_w lom_w; + c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w); + if ( (c3n == res_o) || (lom_w < 20) ) { + fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2); + exit(1); + } + u3_Host.ops_u.lom_y = lom_w; + } break; + + case '?': { + fprintf(stderr, "invalid argument\r\n"); + exit(1); + } break; + } + } + + // argv[optind] is always "meld" + // + + if ( !u3_Host.dir_c ) { + if ( optind + 1 < argc ) { + u3_Host.dir_c = argv[optind + 1]; + } + else { + fprintf(stderr, "invalid command, pier required\r\n"); exit(1); - } break; + } + + optind++; + } + + if ( optind + 1 != argc ) { + fprintf(stderr, "invalid command\r\n"); + exit(1); } u3_disk* log_u = _cw_disk_init(u3_Host.dir_c); // XX s/b try_aquire lock c3_w pre_w; u3C.wag_w |= u3o_hashless; - u3m_boot(u3_Host.dir_c); + u3m_boot(u3_Host.dir_c, (size_t)1 << u3_Host.ops_u.lom_y); pre_w = u3a_open(u3R); u3u_meld(); @@ -1369,7 +1605,8 @@ _cw_next(c3_i argc, c3_c* argv[]) c3_w arg_w; static struct option lop_u[] = { - { "arch", required_argument, NULL, 'a' }, + { "arch", required_argument, NULL, 'a' }, + { "loom", required_argument, NULL, c3__loom }, { NULL, 0, NULL, 0 } }; @@ -1381,7 +1618,18 @@ _cw_next(c3_i argc, c3_c* argv[]) u3_Host.arc_c = strdup(optarg); } break; + case c3__loom: { + c3_w lom_w; + c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w); + if ( (c3n == res_o) || (lom_w < 20) ) { + fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2); + exit(1); + } + u3_Host.ops_u.lom_y = lom_w; + } break; + case '?': { + fprintf(stderr, "invalid argument\r\n"); exit(1); } break; } @@ -1409,6 +1657,7 @@ _cw_next(c3_i argc, c3_c* argv[]) u3_Host.pep_o = c3y; u3_Host.nex_o = c3y; + u3_Host.ops_u.tem = c3y; } /* _cw_pack(): compact memory, save, and exit. @@ -1416,27 +1665,58 @@ _cw_next(c3_i argc, c3_c* argv[]) static void _cw_pack(c3_i argc, c3_c* argv[]) { - switch ( argc ) { - case 2: { - if ( !(u3_Host.dir_c = _main_pier_run(argv[0])) ) { - fprintf(stderr, "unable to find pier\r\n"); - exit (1); - } - } break; + c3_i ch_i, lid_i; + c3_w arg_w; - case 3: { - u3_Host.dir_c = argv[2]; - } break; + static struct option lop_u[] = { + { "loom", required_argument, NULL, c3__loom }, + { NULL, 0, NULL, 0 } + }; - default: { - fprintf(stderr, "invalid command\r\n"); + u3_Host.dir_c = _main_pier_run(argv[0]); + + while ( -1 != (ch_i=getopt_long(argc, argv, "", lop_u, &lid_i)) ) { + switch ( ch_i ) { + case c3__loom: { + c3_w lom_w; + c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w); + if ( (c3n == res_o) || (lom_w < 20) ) { + fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2); + exit(1); + } + u3_Host.ops_u.lom_y = lom_w; + } break; + + case '?': { + fprintf(stderr, "invalid argument\r\n"); + exit(1); + } break; + } + } + + // argv[optind] is always "pack" + // + + if ( !u3_Host.dir_c ) { + if ( optind + 1 < argc ) { + u3_Host.dir_c = argv[optind + 1]; + } + else { + fprintf(stderr, "invalid command, pier required\r\n"); exit(1); - } break; + } + + optind++; + } + + if ( optind + 1 != argc ) { + fprintf(stderr, "invalid command\r\n"); + exit(1); } u3_disk* log_u = _cw_disk_init(u3_Host.dir_c); // XX s/b try_aquire lock - u3m_boot(u3_Host.dir_c); + u3m_boot(u3_Host.dir_c, (size_t)1 << u3_Host.ops_u.lom_y); u3a_print_memory(stderr, "urbit: pack: gained", u3m_pack()); u3e_save(); @@ -1449,25 +1729,57 @@ _cw_pack(c3_i argc, c3_c* argv[]) static void _cw_prep(c3_i argc, c3_c* argv[]) { - switch ( argc ) { - case 2: { - if ( !(u3_Host.dir_c = _main_pier_run(argv[0])) ) { - fprintf(stderr, "unable to find pier\r\n"); - exit (1); - } - } break; + c3_i ch_i, lid_i; + c3_w arg_w; - case 3: { - u3_Host.dir_c = argv[2]; - } break; + static struct option lop_u[] = { + { "loom", required_argument, NULL, c3__loom }, + { NULL, 0, NULL, 0 } + }; - default: { - fprintf(stderr, "invalid command\r\n"); + u3_Host.dir_c = _main_pier_run(argv[0]); + + while ( -1 != (ch_i=getopt_long(argc, argv, "", lop_u, &lid_i)) ) { + switch ( ch_i ) { + case c3__loom: { + c3_w lom_w; + c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w); + if ( (c3n == res_o) || (lom_w < 20) ) { + fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2); + exit(1); + } + u3_Host.ops_u.lom_y = lom_w; + } break; + + case '?': { + fprintf(stderr, "invalid argument\r\n"); + exit(1); + } break; + } + } + + // argv[optind] is always "prep" + // + + if ( !u3_Host.dir_c ) { + if ( optind + 1 < argc ) { + u3_Host.dir_c = argv[optind + 1]; + } + else { + fprintf(stderr, "invalid command, pier required\r\n"); exit(1); - } break; + } + + optind++; + } + + if ( optind + 1 != argc ) { + fprintf(stderr, "invalid command\r\n"); + exit(1); } u3_Host.pep_o = c3y; + u3_Host.ops_u.tem = c3y; } /* _cw_vere(): download vere @@ -1484,9 +1796,9 @@ _cw_vere(c3_i argc, c3_c* argv[]) c3_w arg_w; static struct option lop_u[] = { - { "arch", required_argument, NULL, 'a' }, - { "pace", required_argument, NULL, 'p' }, - { "version", required_argument, NULL, 'v' }, + { "arch", required_argument, NULL, 'a' }, + { "pace", required_argument, NULL, 'p' }, + { "version", required_argument, NULL, 'v' }, { NULL, 0, NULL, 0 } }; @@ -1583,6 +1895,100 @@ _cw_vere(c3_i argc, c3_c* argv[]) u3l_log("vere: download succeeded\r\n"); } +/* _cw_vile(): generatoe/print keyfile +*/ +static void +_cw_vile(c3_i argc, c3_c* argv[]) +{ + c3_i ch_i, lid_i; + c3_w arg_w; + + static struct option lop_u[] = { + { "loom", required_argument, NULL, c3__loom }, + { NULL, 0, NULL, 0 } + }; + + u3_Host.dir_c = _main_pier_run(argv[0]); + + while ( -1 != (ch_i=getopt_long(argc, argv, "", lop_u, &lid_i)) ) { + switch ( ch_i ) { + case c3__loom: { + c3_w lom_w; + c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w); + if ( (c3n == res_o) || (lom_w < 20) ) { + fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2); + exit(1); + } + u3_Host.ops_u.lom_y = lom_w; + } break; + + case '?': { + fprintf(stderr, "invalid argument\r\n"); + exit(1); + } break; + } + } + + // argv[optind] is always "vile" + // + + if ( !u3_Host.dir_c ) { + if ( optind + 1 < argc ) { + u3_Host.dir_c = argv[optind + 1]; + } + else { + fprintf(stderr, "invalid command, pier required\r\n"); + exit(1); + } + + optind++; + } + + if ( optind + 1 != argc ) { + fprintf(stderr, "invalid command\r\n"); + exit(1); + } + + // XX check if snapshot is stale? + // + c3_d eve_d = u3m_boot(u3_Host.dir_c, (size_t)1 << u3_Host.ops_u.lom_y); + u3_noun sam = u3nc(u3nc(u3_nul, u3_nul), + u3nc(c3n, u3nq(c3__once, 'j', c3__vile, u3_nul))); + u3_noun res = u3v_soft_peek(0, sam); + + + switch ( u3h(res) ) { + default: c3_assert(0); + + case c3n: { + fprintf(stderr, "vile: unable to retrieve key file\r\n"); + u3_pier_punt_goof("foo", u3k(u3t(res))); + } + case c3y: { + u3_noun dat, vil, out; + c3_c* out_c; + + if ( (u3_nul != u3h(u3t(res))) + || (c3n == u3r_pq(u3t(u3t(res)), c3__omen, 0, &dat)) + || (c3n == u3r_p(dat, c3__atom, &vil)) + || (c3n == u3a_is_atom(vil)) ) + { + fprintf(stderr, "vile: unable to extract key file\r\n"); + u3m_p("vil", res); + } + else { + out = u3dc("scot", c3__uw, u3k(vil)); + out_c = u3r_string(out); + puts(out_c); + c3_free(out_c); + u3z(out); + } + } + } + + u3z(res); +} + /* _cw_utils(): "worker" utilities and "serf" entrypoint */ static c3_i @@ -1601,9 +2007,12 @@ _cw_utils(c3_i argc, c3_c* argv[]) // [%prep dir=@t] :: prep upgrade // [%queu dir=@t eve=@ud] :: cue state // [?(%vere %fetch-vere) dir=@t] :: download vere + // [%vile dir=@t] :: extract keys // :: :: ipc: - // [%serf dir=@t key=@t wag=@t hap=@ud eve=@ud] :: compute - // == + // $: %serf :: compute + // dir=@t key=@t wag=@t hap=@ud :: + // lom=@ud eve=@ud :: + // == == :: // // NB: don't print to anything other than stderr; // other streams may be used for ipc. @@ -1626,6 +2035,7 @@ _cw_utils(c3_i argc, c3_c* argv[]) switch ( mot_m ) { case c3__cram: _cw_cram(argc, argv); return 1; case c3__dock: _cw_dock(argc, argv); return 1; + case c3__eval: _cw_eval(argc, argv); return 1; case c3__mass: case c3__grab: _cw_grab(argc, argv); return 1; @@ -1637,6 +2047,7 @@ _cw_utils(c3_i argc, c3_c* argv[]) case c3__prep: _cw_prep(argc, argv); return 2; // continue on case c3__queu: _cw_queu(argc, argv); return 1; case c3__vere: _cw_vere(argc, argv); return 1; + case c3__vile: _cw_vile(argc, argv); return 1; case c3__serf: _cw_serf_commence(argc, argv); return 1; } @@ -1828,7 +2239,7 @@ main(c3_i argc, // starting u3m configures OpenSSL memory functions, so we must do it // before any OpenSSL allocations // - u3m_boot_lite(); + u3m_boot_lite((size_t)1 << u3_Host.ops_u.lut_y); // Initialize OpenSSL for client and server // diff --git a/pkg/urbit/include/c/motes.h b/pkg/urbit/include/c/motes.h index e8b944394..f67a50f4e 100644 --- a/pkg/urbit/include/c/motes.h +++ b/pkg/urbit/include/c/motes.h @@ -387,6 +387,7 @@ # define c3__ergo c3_s4('e','r','g','o') # define c3__esh c3_s3('e','s','h') # define c3__etch c3_s4('e','t','c','h') +# define c3__eval c3_s4('e','v','a','l') # define c3__evil c3_s4('e','v','i','l') # define c3__ex c3_s2('e','x') # define c3__exit c3_s4('e','x','i','t') @@ -698,6 +699,7 @@ # define c3__lond c3_s4('l','o','n','d') # define c3__lonk c3_s4('l','o','n','k') # define c3__look c3_s4('l','o','o','k') +# define c3__loom c3_s4('l','o','o','m') # define c3__loop c3_s4('l','o','o','p') # define c3__lorb c3_s4('l','o','r','b') # define c3__lord c3_s4('l','o','r','d') @@ -1239,6 +1241,7 @@ # define c3__vern c3_s4('v','e','r','n') # define c3__very c3_s4('v','e','r','y') # define c3__view c3_s4('v','i','e','w') +# define c3__vile c3_s4('v','i','l', 'e') # define c3__vint c3_s4('v','i','n','t') # define c3__void c3_s4('v','o','i','d') # define c3__vorp c3_s4('v','o','r','p') @@ -1296,6 +1299,7 @@ # define c3__wtts c3_s4('w','t','t','s') # define c3__wtzp c3_s4('w','t','z','p') # define c3__wyrd c3_s4('w','y','r','d') +# define c3__xray c3_s4('x','r','a','y') # define c3__yell c3_s4('y','e','l','l') # define c3__yelp c3_s4('y','e','l','p') # define c3__z c3_s1('z') diff --git a/pkg/urbit/include/c/portable.h b/pkg/urbit/include/c/portable.h index 10c2aa710..671db4d06 100644 --- a/pkg/urbit/include/c/portable.h +++ b/pkg/urbit/include/c/portable.h @@ -113,8 +113,7 @@ # if defined(U3_OS_linux) # ifdef __LP64__ # ifdef U3_CPU_aarch64 -// XX not yet -//# define U3_OS_ARCH "aarch64-linux" +# define U3_OS_ARCH "aarch64-linux" # else # define U3_OS_ARCH "x86_64-linux" # endif @@ -158,24 +157,24 @@ # else # define U3_OS_LoomBase 0x36000000 # endif -# define U3_OS_LoomBits 29 +# define U3_OS_LoomBits 30 # elif defined(U3_OS_mingw) # define U3_OS_LoomBase 0x28000000000 -# define U3_OS_LoomBits 29 +# define U3_OS_LoomBits 30 # elif defined(U3_OS_osx) # ifdef __LP64__ # define U3_OS_LoomBase 0x28000000000 # else # define U3_OS_LoomBase 0x4000000 # endif -# define U3_OS_LoomBits 29 +# define U3_OS_LoomBits 30 # elif defined(U3_OS_bsd) # ifdef __LP64__ # define U3_OS_LoomBase 0x200000000 # else # define U3_OS_LoomBase 0x4000000 # endif -# define U3_OS_LoomBits 29 +# define U3_OS_LoomBits 30 # else # error "port: LoomBase" # endif diff --git a/pkg/urbit/include/noun/allocate.h b/pkg/urbit/include/noun/allocate.h index 529ad6fb6..964de538b 100644 --- a/pkg/urbit/include/noun/allocate.h +++ b/pkg/urbit/include/noun/allocate.h @@ -1,8 +1,6 @@ #ifndef U3_ALLOCATE_H #define U3_ALLOCATE_H -#include - #include "manage.h" /** Constants. @@ -15,15 +13,15 @@ */ # define u3a_page 12 - /* u3a_pages: number of pages in memory. + /* u3a_pages: maximum number of pages in memory. */ # define u3a_pages (1 << (u3a_bits - u3a_page)) - /* u3a_words: number of words in memory. + /* u3a_words: maximum number of words in memory. */ # define u3a_words (1 << u3a_bits) - /* u3a_bytes: number of bytes in memory. + /* u3a_bytes: maximum number of bytes in memory. */ # define u3a_bytes (sizeof(c3_w) * u3a_words) @@ -477,15 +475,6 @@ void* u3a_malloc(size_t len_i); - /* u3a_malloc_ssl(): openssl-shaped malloc - */ - void* - u3a_malloc_ssl(size_t len_i -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - , const char* file, int line -#endif - ); - /* u3a_calloc(): aligned storage measured in bytes. */ void* @@ -496,39 +485,11 @@ void* u3a_realloc(void* lag_v, size_t len_i); - /* u3a_realloc2(): gmp-shaped realloc. - */ - void* - u3a_realloc2(void* lag_v, size_t old_i, size_t new_i); - - /* u3a_realloc_ssl(): openssl-shaped realloc. - */ - void* - u3a_realloc_ssl(void* lag_v, size_t len_i -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - , const char* file, int line -#endif - ); - /* u3a_free(): free for aligned malloc. */ void u3a_free(void* tox_v); - /* u3a_free2(): gmp-shaped free. - */ - void - u3a_free2(void* tox_v, size_t siz_i); - - /* u3a_free_ssl(): openssl-shaped free. - */ - void - u3a_free_ssl(void* tox_v -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - , const char* file, int line -#endif - ); - /* Reference and arena control. */ /* u3a_gain(): gain a reference count in normal space. diff --git a/pkg/urbit/include/noun/events.h b/pkg/urbit/include/noun/events.h index 92d5c2a75..c1b95cde8 100644 --- a/pkg/urbit/include/noun/events.h +++ b/pkg/urbit/include/noun/events.h @@ -41,6 +41,7 @@ typedef struct _u3e_pool { c3_c* dir_c; // path to c3_w dit_w[u3a_pages >> 5]; // touched since last save + c3_w pag_w; // number of pages (<= u3a_pages) u3e_image nor_u; // north segment u3e_image sou_u; // south segment } u3e_pool; @@ -84,9 +85,14 @@ void u3e_foul(void); - /* u3e_init(): initialize page tracking. + /* u3e_init(): initialize guard page tracking. */ void u3e_init(void); + /* u3e_ward(): reposition guard page if needed. + */ + void + u3e_ward(u3_post low_p, u3_post hig_p); + #endif /* ifndef U3_EVENTS_H */ diff --git a/pkg/urbit/include/noun/manage.h b/pkg/urbit/include/noun/manage.h index 89f50d603..72e29f533 100644 --- a/pkg/urbit/include/noun/manage.h +++ b/pkg/urbit/include/noun/manage.h @@ -6,12 +6,12 @@ /* u3m_boot(): start the u3 system. return next event, starting from 1. */ c3_d - u3m_boot(c3_c* dir_c); + u3m_boot(c3_c* dir_c, size_t len_i); /* u3m_boot_lite(): start without checkpointing. */ c3_d - u3m_boot_lite(void); + u3m_boot_lite(size_t len_i); /* u3m_stop(): graceful shutdown cleanup. */ void @@ -37,7 +37,7 @@ /* u3m_init(): start the environment. */ void - u3m_init(); + u3m_init(size_t len_i); /* u3m_pave(): instantiate or activate image. */ diff --git a/pkg/urbit/include/noun/options.h b/pkg/urbit/include/noun/options.h index f73dba264..c1fd58c40 100644 --- a/pkg/urbit/include/noun/options.h +++ b/pkg/urbit/include/noun/options.h @@ -9,6 +9,7 @@ u3_noun who; // single identity c3_c* dir_c; // execution directory (pier) c3_w wag_w; // flags (both ways) + size_t wor_i; // loom word-length (<= u3a_words) void (*stderr_log_f)(c3_c*); // errors from c code void (*slog_f)(u3_noun); // function pointer for slog void (*sign_hold_f)(void); // suspend system signal regime diff --git a/pkg/urbit/include/noun/retrieve.h b/pkg/urbit/include/noun/retrieve.h index edd2275bf..b6e96e380 100644 --- a/pkg/urbit/include/noun/retrieve.h +++ b/pkg/urbit/include/noun/retrieve.h @@ -304,6 +304,7 @@ ** (1 << a_y). ** ** For example, (a_y == 3) returns the size in bytes. + ** NB: (a_y) must be < 37. */ c3_w u3r_met(c3_y a_y, @@ -362,18 +363,50 @@ u3r_bytes_all(c3_w* len_w, u3_atom a); + /* u3r_chop_bits(): + ** + ** XOR `wid_d` bits from`src_w` at `bif_g` to `dst_w` at `bif_g` + ** + ** NB: [dst_w] must have space for [bit_g + wid_d] bits + */ + void + u3r_chop_bits(c3_g bif_g, + c3_d wid_d, + c3_g bit_g, + c3_w* dst_w, + const c3_w* src_w); + + /* u3r_chop_words(): + ** + ** Into the bloq space of `met`, from position `fum` for a + ** span of `wid`, to position `tou`, XOR from `src_w` + ** into `dst_w`. + ** + ** NB: [dst_w] must have space for [tou_w + wid_w] bloqs + */ + void + u3r_chop_words(c3_g met_g, + c3_w fum_w, + c3_w wid_w, + c3_w tou_w, + c3_w* dst_w, + c3_w len_w, + const c3_w* src_w); + /* u3r_chop(): ** ** Into the bloq space of `met`, from position `fum` for a ** span of `wid`, to position `tou`, XOR from atom `src` - ** into ray `dst`. + ** into `dst_w`. + ** + ** NB: [dst_w] must have space for [tou_w + wid_w] bloqs */ void - u3r_chop(c3_g met_g, - c3_w fum_w, - c3_w wid_w, - c3_w tou_w, - c3_w* dst_w, + u3r_chop(c3_g met_g, + c3_w fum_w, + c3_w wid_w, + c3_w tou_w, + c3_w* dst_w, u3_atom src); /* u3r_mp(): diff --git a/pkg/urbit/include/noun/vortex.h b/pkg/urbit/include/noun/vortex.h index 3e8f01484..92320620a 100644 --- a/pkg/urbit/include/noun/vortex.h +++ b/pkg/urbit/include/noun/vortex.h @@ -77,6 +77,11 @@ u3_noun u3v_peek(u3_noun hap); + /* u3v_soft_peek(): softly query the reck namespace. + */ + u3_noun + u3v_soft_peek(c3_w mil_w, u3_noun sam); + /* u3v_poke(): insert and apply an input ovum (protected). */ u3_noun diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index d33d1ff84..d02771343 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -291,6 +291,8 @@ c3_c* key_c; // -k, private key file c3_o net; // -L, local-only networking c3_o lit; // -l, lite mode + c3_y lom_y; // loom bex + c3_y lut_y; // urth-loom bex c3_c* til_c; // -n, play till eve_d c3_o pro; // -P, profile c3_s per_s; // http port diff --git a/pkg/urbit/noun/allocate.c b/pkg/urbit/noun/allocate.c index 2a92e6490..f7ce67958 100644 --- a/pkg/urbit/noun/allocate.c +++ b/pkg/urbit/noun/allocate.c @@ -692,18 +692,6 @@ u3a_malloc(size_t len_i) return out_w; } -/* u3a_malloc_ssl(): openssl-shaped malloc -*/ -void* -u3a_malloc_ssl(size_t len_i -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - , const char* file, int line -#endif - ) -{ - return u3a_malloc(len_i); -} - /* u3a_cellblock(): allocate a block of cells on the hat. */ static c3_o @@ -885,26 +873,6 @@ u3a_realloc(void* lag_v, size_t len_i) return u3a_wealloc(lag_v, (len_w + 3) >> 2); } -/* u3a_realloc2(): gmp-shaped realloc. -*/ -void* -u3a_realloc2(void* lag_v, size_t old_i, size_t new_i) -{ - return u3a_realloc(lag_v, new_i); -} - -/* u3a_realloc_ssl(): openssl-shaped realloc. -*/ -void* -u3a_realloc_ssl(void* lag_v, size_t len_i -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - , const char* file, int line -#endif - ) -{ - return u3a_realloc(lag_v, len_i); -} - /* u3a_free(): free for aligned malloc. */ void @@ -921,26 +889,6 @@ u3a_free(void* tox_v) u3a_wfree(org_w); } -/* u3a_free2(): gmp-shaped free. -*/ -void -u3a_free2(void* tox_v, size_t siz_i) -{ - return u3a_free(tox_v); -} - -/* u3a_free_ssl(): openssl-shaped free. -*/ -void -u3a_free_ssl(void* tox_v -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - , const char* file, int line -#endif - ) -{ - return u3a_free(tox_v); -} - /* _me_wash_north(): clean up mug slots after copy. */ static void _me_wash_north(u3_noun dog); diff --git a/pkg/urbit/noun/events.c b/pkg/urbit/noun/events.c index 6986e91a2..ceec1bd41 100644 --- a/pkg/urbit/noun/events.c +++ b/pkg/urbit/noun/events.c @@ -136,9 +136,9 @@ u3e_check(c3_c* cap_c) sum_w += mug_w; } for ( i_w = 0; i_w < sou_w; i_w++ ) { - mug_w = _ce_check_page((u3a_pages - (i_w + 1))); + mug_w = _ce_check_page((u3P.pag_w - (i_w + 1))); if ( strcmp(cap_c, "boot") ) { - c3_assert(mug_w == u3K.mug_w[(u3a_pages - (i_w + 1))]); + c3_assert(mug_w == u3K.mug_w[(u3P.pag_w - (i_w + 1))]); } sum_w += mug_w; } @@ -195,7 +195,7 @@ _ce_center_guard_page(void) { u3p(c3_w) bot_p, top_p; if ( !u3R ) { - top_p = u3a_outa(u3_Loom + u3a_words); + top_p = u3a_outa(u3_Loom + u3C.wor_i); bot_p = u3a_outa(u3_Loom); } else if ( c3y == u3a_is_north(u3R) ) { @@ -226,8 +226,9 @@ _ce_center_guard_page(void) if ( -1 == mprotect(u3a_into(gar_pag_p), pag_siz_i, PROT_NONE) ) { fprintf(stderr, "loom: failed to protect the guard page " - "(base address %p)\r\n", - u3a_into(gar_pag_p)); + "(base address %p): %s\r\n", + u3a_into(gar_pag_p), + strerror(errno)); goto fail; } @@ -255,9 +256,9 @@ u3e_fault(void* adr_v, c3_i ser_i) c3_w* adr_w = (c3_w*) adr_v; - if ( (adr_w < u3_Loom) || (adr_w >= (u3_Loom + u3a_words)) ) { + if ( (adr_w < u3_Loom) || (adr_w >= (u3_Loom + u3C.wor_i)) ) { fprintf(stderr, "address %p out of loom!\r\n", adr_w); - fprintf(stderr, "loom: [%p : %p)\r\n", u3_Loom, u3_Loom + u3a_words); + fprintf(stderr, "loom: [%p : %p)\r\n", u3_Loom, u3_Loom + u3C.wor_i); c3_assert(0); return 0; } @@ -353,10 +354,17 @@ _ce_image_open(u3e_image* img_u) static void _ce_patch_write_control(u3_ce_patch* pat_u) { - c3_w len_w = sizeof(u3e_control) + - (pat_u->con_u->pgs_w * sizeof(u3e_line)); + ssize_t ret_i; + c3_w len_w = sizeof(u3e_control) + + (pat_u->con_u->pgs_w * sizeof(u3e_line)); - if ( len_w != write(pat_u->ctl_i, pat_u->con_u, len_w) ) { + if ( len_w != (ret_i = write(pat_u->ctl_i, pat_u->con_u, len_w)) ) { + if ( 0 < ret_i ) { + fprintf(stderr, "loom: patch ctl partial write: %zu\r\n", (size_t)ret_i); + } + else { + fprintf(stderr, "loom: patch ctl write: %s\r\n", strerror(errno)); + } c3_assert(0); } } @@ -424,11 +432,17 @@ _ce_patch_delete(void) { c3_c ful_c[8193]; - snprintf(ful_c, 8192, "%s/.urb/chk/control.bin", u3P.dir_c); - c3_unlink(ful_c); + snprintf(ful_c, 8192, "%s/.urb/chk/control.bin", u3P.dir_c); + if ( unlink(ful_c) ) { + fprintf(stderr, "loom: failed to delete control.bin: %s\r\n", + strerror(errno)); + } snprintf(ful_c, 8192, "%s/.urb/chk/memory.bin", u3P.dir_c); - c3_unlink(ful_c); + if ( unlink(ful_c) ) { + fprintf(stderr, "loom: failed to remove memory.bin: %s\r\n", + strerror(errno)); + } } /* _ce_patch_verify(): check patch data mug. @@ -436,7 +450,8 @@ _ce_patch_delete(void) static c3_o _ce_patch_verify(u3_ce_patch* pat_u) { - c3_w i_w; + ssize_t ret_i; + c3_w i_w; if ( u3e_version != pat_u->con_u->ver_y ) { fprintf(stderr, "loom: patch version mismatch: have %u, need %u\r\n", @@ -454,8 +469,13 @@ _ce_patch_verify(u3_ce_patch* pat_u) fprintf(stderr, "loom: patch seek: %s\r\n", strerror(errno)); return c3n; } - if ( -1 == read(pat_u->mem_i, mem_w, pag_siz_i) ) { - fprintf(stderr, "loom: patch read: %s\r\n", strerror(errno)); + if ( pag_siz_i != (ret_i = read(pat_u->mem_i, mem_w, pag_siz_i)) ) { + if ( 0 < ret_i ) { + fprintf(stderr, "loom: patch partial read: %zu\r\n", (size_t)ret_i); + } + else { + fprintf(stderr, "loom: patch read fail: %s\r\n", strerror(errno)); + } return c3n; } { @@ -542,8 +562,23 @@ _ce_patch_write_page(u3_ce_patch* pat_u, c3_w pgc_w, c3_w* mem_w) { - c3_assert(-1 != lseek(pat_u->mem_i, pgc_w * pag_siz_i, SEEK_SET)); - c3_assert(pag_siz_i == write(pat_u->mem_i, mem_w, pag_siz_i)); + ssize_t ret_i; + + if ( -1 == lseek(pat_u->mem_i, pgc_w * pag_siz_i, SEEK_SET) ) { + fprintf(stderr, "loom: patch page seek: %s\r\n", strerror(errno)); + c3_assert(0); + } + + if ( pag_siz_i != (ret_i = write(pat_u->mem_i, mem_w, pag_siz_i)) ) { + if ( 0 < ret_i ) { + fprintf(stderr, "loom: patch page partial write: %zu\r\n", + (size_t)ret_i); + } + else { + fprintf(stderr, "loom: patch page write: %s\r\n", strerror(errno)); + } + c3_assert(0); + } } /* _ce_patch_count_page(): count a page, producing new counter. @@ -586,6 +621,7 @@ _ce_patch_save_page(u3_ce_patch* pat_u, pag_siz_i, PROT_READ) ) { + fprintf(stderr, "loom: patch mprotect: %s\r\n", strerror(errno)); c3_assert(0); } @@ -613,6 +649,9 @@ _ce_patch_compose(void) nor_w = (nwr_w + (pag_wiz_i - 1)) >> u3a_page; sou_w = (swu_w + (pag_wiz_i - 1)) >> u3a_page; + + c3_assert( ((gar_pag_p >> u3a_page) >= nor_w) + && ((gar_pag_p >> u3a_page) <= (u3a_pages - (sou_w + 1))) ); } #ifdef U3_SNAPSHOT_VALIDATION @@ -629,7 +668,7 @@ _ce_patch_compose(void) pgs_w = _ce_patch_count_page(i_w, pgs_w); } for ( i_w = 0; i_w < sou_w; i_w++ ) { - pgs_w = _ce_patch_count_page((u3a_pages - (i_w + 1)), pgs_w); + pgs_w = _ce_patch_count_page((u3P.pag_w - (i_w + 1)), pgs_w); } } @@ -649,7 +688,7 @@ _ce_patch_compose(void) pgc_w = _ce_patch_save_page(pat_u, i_w, pgc_w); } for ( i_w = 0; i_w < sou_w; i_w++ ) { - pgc_w = _ce_patch_save_page(pat_u, (u3a_pages - (i_w + 1)), pgc_w); + pgc_w = _ce_patch_save_page(pat_u, (u3P.pag_w - (i_w + 1)), pgc_w); } pat_u->con_u->nor_w = nor_w; @@ -699,7 +738,7 @@ _ce_image_resize(u3e_image* img_u, c3_w pgs_w) { if ( img_u->pgs_w > pgs_w ) { if ( ftruncate(img_u->fid_i, pgs_w << (u3a_page + 2)) ) { - fprintf(stderr, "loom: image truncate %s: %s\r\n", + fprintf(stderr, "loom: image (%s) truncate: %s\r\n", img_u->nam_c, strerror(errno)); c3_assert(0); @@ -714,7 +753,8 @@ _ce_image_resize(u3e_image* img_u, c3_w pgs_w) static void _ce_patch_apply(u3_ce_patch* pat_u) { - c3_w i_w; + ssize_t ret_i; + c3_w i_w; // resize images // @@ -745,11 +785,17 @@ _ce_patch_apply(u3_ce_patch* pat_u) } else { fid_i = u3P.sou_u.fid_i; - off_w = (u3a_pages - (pag_w + 1)); + off_w = (u3P.pag_w - (pag_w + 1)); } - if ( -1 == read(pat_u->mem_i, mem_w, pag_siz_i) ) { - fprintf(stderr, "loom: patch apply read: %s\r\n", strerror(errno)); + if ( pag_siz_i != (ret_i = read(pat_u->mem_i, mem_w, pag_siz_i)) ) { + if ( 0 < ret_i ) { + fprintf(stderr, "loom: patch apply partial read: %zu\r\n", + (size_t)ret_i); + } + else { + fprintf(stderr, "loom: patch apply read: %s\r\n", strerror(errno)); + } c3_assert(0); } else { @@ -757,8 +803,14 @@ _ce_patch_apply(u3_ce_patch* pat_u) fprintf(stderr, "loom: patch apply seek: %s\r\n", strerror(errno)); c3_assert(0); } - if ( -1 == write(fid_i, mem_w, pag_siz_i) ) { - fprintf(stderr, "loom: patch apply write: %s\r\n", strerror(errno)); + if ( pag_siz_i != (ret_i = write(fid_i, mem_w, pag_siz_i)) ) { + if ( 0 < ret_i ) { + fprintf(stderr, "loom: patch apply partial write: %zu\r\n", + (size_t)ret_i); + } + else { + fprintf(stderr, "loom: patch apply write: %s\r\n", strerror(errno)); + } c3_assert(0); } } @@ -779,13 +831,26 @@ _ce_image_blit(u3e_image* img_u, return; } - c3_w i_w; - c3_w siz_w = pag_siz_i; + ssize_t ret_i; + c3_w i_w; + c3_w siz_w = pag_siz_i; + + if ( -1 == lseek(img_u->fid_i, 0, SEEK_SET) ) { + fprintf(stderr, "loom: image (%s) blit seek 0: %s\r\n", + img_u->nam_c, strerror(errno)); + c3_assert(0); + } - lseek(img_u->fid_i, 0, SEEK_SET); for ( i_w = 0; i_w < img_u->pgs_w; i_w++ ) { - if ( -1 == read(img_u->fid_i, ptr_w, siz_w) ) { - fprintf(stderr, "loom: image blit read: %s\r\n", strerror(errno)); + if ( siz_w != (ret_i = read(img_u->fid_i, ptr_w, siz_w)) ) { + if ( 0 < ret_i ) { + fprintf(stderr, "loom: image (%s) blit partial read: %zu\r\n", + img_u->nam_c, (size_t)ret_i); + } + else { + fprintf(stderr, "loom: image (%s) blit read: %s\r\n", + img_u->nam_c, strerror(errno)); + } c3_assert(0); } @@ -811,15 +876,27 @@ _ce_image_fine(u3e_image* img_u, c3_w* ptr_w, c3_ws stp_ws) { - c3_w i_w; - c3_w buf_w[pag_wiz_i]; + ssize_t ret_i; + c3_w i_w; + c3_w buf_w[pag_wiz_i]; + + if ( -1 == lseek(img_u->fid_i, 0, SEEK_SET) ) { + fprintf(stderr, "loom: image fine seek 0: %s\r\n", strerror(errno)); + c3_assert(0); + } - lseek(img_u->fid_i, 0, SEEK_SET); for ( i_w=0; i_w < img_u->pgs_w; i_w++ ) { c3_w mem_w, fil_w; - if ( -1 == read(img_u->fid_i, buf_w, pag_siz_i) ) { - fprintf(stderr, "loom: image fine read: %s\r\n", strerror(errno)); + if ( pag_siz_i != (ret_i = read(img_u->fid_i, buf_w, pag_siz_i)) ) { + if ( 0 < ret_i ) { + fprintf(stderr, "loom: image (%s) fine partial read: %zu\r\n", + img_u->nam_c, (size_t)ret_i); + } + else { + fprintf(stderr, "loom: image (%s) fine read: %s\r\n", + img_u->nam_c, strerror(errno)); + } c3_assert(0); } mem_w = u3r_mug_words(ptr_w, pag_wiz_i); @@ -828,11 +905,13 @@ _ce_image_fine(u3e_image* img_u, if ( mem_w != fil_w ) { c3_w pag_w = (ptr_w - u3_Loom) >> u3a_page; - fprintf(stderr, "mismatch: page %d, mem_w %x, fil_w %x, K %x\r\n", - pag_w, - mem_w, - fil_w, - u3K.mug_w[pag_w]); + fprintf(stderr, "loom: image (%s) mismatch: " + "page %d, mem_w %x, fil_w %x, K %x\r\n", + img_u->nam_c, + pag_w, + mem_w, + fil_w, + u3K.mug_w[pag_w]); abort(); } ptr_w += stp_ws; @@ -845,7 +924,8 @@ _ce_image_fine(u3e_image* img_u, static c3_o _ce_image_copy(u3e_image* fom_u, u3e_image* tou_u) { - c3_w i_w; + ssize_t ret_i; + c3_w i_w; // resize images // @@ -856,7 +936,9 @@ _ce_image_copy(u3e_image* fom_u, u3e_image* tou_u) if ( (-1 == lseek(fom_u->fid_i, 0, SEEK_SET)) || (-1 == lseek(tou_u->fid_i, 0, SEEK_SET)) ) { - fprintf(stderr, "loom: image copy seek 0: %s\r\n", strerror(errno)); + fprintf(stderr, "loom: image (%s) copy seek: %s\r\n", + fom_u->nam_c, + strerror(errno)); return c3n; } @@ -866,17 +948,32 @@ _ce_image_copy(u3e_image* fom_u, u3e_image* tou_u) c3_w mem_w[pag_wiz_i]; c3_w off_w = i_w; - if ( -1 == read(fom_u->fid_i, mem_w, pag_siz_i) ) { - fprintf(stderr, "loom: image copy read: %s\r\n", strerror(errno)); + if ( pag_siz_i != (ret_i = read(fom_u->fid_i, mem_w, pag_siz_i)) ) { + if ( 0 < ret_i ) { + fprintf(stderr, "loom: image (%s) copy partial read: %zu\r\n", + fom_u->nam_c, (size_t)ret_i); + } + else { + fprintf(stderr, "loom: image (%s) copy read: %s\r\n", + fom_u->nam_c, strerror(errno)); + } return c3n; } else { if ( -1 == lseek(tou_u->fid_i, (off_w << (u3a_page + 2)), SEEK_SET) ) { - fprintf(stderr, "loom: image copy seek: %s\r\n", strerror(errno)); + fprintf(stderr, "loom: image (%s) copy seek: %s\r\n", + tou_u->nam_c, strerror(errno)); return c3n; } - if ( -1 == write(tou_u->fid_i, mem_w, pag_siz_i) ) { - fprintf(stderr, "loom: image copy write: %s\r\n", strerror(errno)); + if ( pag_siz_i != (ret_i = write(tou_u->fid_i, mem_w, pag_siz_i)) ) { + if ( 0 < ret_i ) { + fprintf(stderr, "loom: image (%s) copy partial write: %zu\r\n", + tou_u->nam_c, (size_t)ret_i); + } + else { + fprintf(stderr, "loom: image (%s) copy write: %s\r\n", + tou_u->nam_c, strerror(errno)); + } return c3n; } } @@ -983,7 +1080,7 @@ u3e_save(void) pag_wiz_i); _ce_image_fine(&u3P.sou_u, - (u3_Loom + (1 << u3a_bits) - pag_wiz_i), + (u3_Loom + u3C.wor_i) - pag_wiz_i, -(ssize_t)pag_wiz_i); c3_assert(u3P.nor_u.pgs_w == u3K.nor_w); @@ -1006,11 +1103,20 @@ u3e_live(c3_o nuu_o, c3_c* dir_c) { // require that our page size is a multiple of the system page size. // - c3_assert(0 == (1 << (2 + u3a_page)) % sysconf(_SC_PAGESIZE)); + { + size_t sys_i = sysconf(_SC_PAGESIZE); + + if ( pag_siz_i % sys_i ) { + fprintf(stderr, "loom: incompatible system page size (%zuKB)\r\n", + sys_i >> 10); + exit(1); + } + } u3P.dir_c = dir_c; u3P.nor_u.nam_c = "north"; u3P.sou_u.nam_c = "south"; + u3P.pag_w = u3C.wor_i >> u3a_page; // XX review dryrun requirements, enable or remove // @@ -1041,6 +1147,13 @@ u3e_live(c3_o nuu_o, c3_c* dir_c) _ce_patch_delete(); } + // detect snapshots from a larger loom + // + if ( (u3P.nor_u.pgs_w + u3P.sou_u.pgs_w + 1) >= u3a_pages ) { + fprintf(stderr, "boot: snapshot too big for loom\r\n"); + exit(1); + } + // mark all pages dirty (pages in the snapshot will be marked clean) // u3e_foul(); @@ -1053,7 +1166,7 @@ u3e_live(c3_o nuu_o, c3_c* dir_c) pag_wiz_i); _ce_image_blit(&u3P.sou_u, - (u3_Loom + (1 << u3a_bits) - pag_wiz_i), + (u3_Loom + u3C.wor_i) - pag_wiz_i, -(ssize_t)pag_wiz_i); u3l_log("boot: protected loom\r\n"); @@ -1080,12 +1193,24 @@ u3e_live(c3_o nuu_o, c3_c* dir_c) c3_o u3e_yolo(void) { - // NB: u3e_save() will reinstate protection flags + // NB: u3e_save() will reinstate protection flags // - if ( 0 != mprotect((void *)u3_Loom, u3a_bytes, (PROT_READ | PROT_WRITE)) ) { + if ( 0 != mprotect((void *)u3_Loom, + u3C.wor_i << 2, + (PROT_READ | PROT_WRITE)) ) + { + // XX confirm recoverable errors + // + fprintf(stderr, "loom: yolo: %s\r\n", strerror(errno)); return c3n; } + if ( 0 != mprotect(u3a_into(gar_pag_p), pag_siz_i, PROT_NONE) ) { + fprintf(stderr, "loom: failed to protect guard page: %s\r\n", + strerror(errno)); + c3_assert(0); + } + return c3y; } @@ -1097,10 +1222,26 @@ u3e_foul(void) memset((void*)u3P.dit_w, 0xff, sizeof(u3P.dit_w)); } +/* u3e_init(): initialize guard page tracking. +*/ void u3e_init(void) { + u3P.pag_w = u3C.wor_i >> u3a_page; + #ifdef U3_GUARD_PAGE _ce_center_guard_page(); #endif } + +/* u3e_ward(): reposition guard page if needed. +*/ +void +u3e_ward(u3_post low_p, u3_post hig_p) +{ +#ifdef U3_GUARD_PAGE + if ( (low_p > gar_pag_p) || (hig_p < gar_pag_p) ) { + _ce_center_guard_page(); + } +#endif +} diff --git a/pkg/urbit/noun/manage.c b/pkg/urbit/noun/manage.c index c0659f42b..aa33b0328 100644 --- a/pkg/urbit/noun/manage.c +++ b/pkg/urbit/noun/manage.c @@ -553,7 +553,7 @@ _pave_home(void) { c3_w* mem_w = u3_Loom + 1; c3_w siz_w = c3_wiseof(u3v_home); - c3_w len_w = u3a_words - 1; + c3_w len_w = u3C.wor_i - 1; u3H = (void *)_pave_north(mem_w, siz_w, len_w); u3H->ver_w = u3v_version; @@ -574,7 +574,7 @@ _find_home(void) // c3_w* mem_w = u3_Loom + 1; c3_w siz_w = c3_wiseof(u3v_home); - c3_w len_w = u3a_words - 1; + c3_w len_w = u3C.wor_i - 1; { c3_w ver_w = *((mem_w + len_w) - 1); @@ -590,6 +590,11 @@ _find_home(void) u3H = (void *)((mem_w + len_w) - siz_w); u3R = &u3H->rod_u; + + // this looks risky, but there are no legitimate scenarios + // where it's wrong + // + u3R->cap_p = u3R->mat_p = u3C.wor_i - c3_wiseof(*u3H); } /* u3m_pave(): instantiate or activate image. @@ -690,22 +695,27 @@ u3m_bail(u3_noun how) abort(); } - /* Printf some metadata. - */ - if ( c3__exit != how && (_(u3ud(how)) || 1 != u3h(how)) ) { - if ( _(u3ud(how)) ) { - c3_c str_c[5]; + // printf some metadata + // + switch ( how ) { + case c3__evil: + case c3__exit: break; - str_c[0] = ((how >> 0) & 0xff); - str_c[1] = ((how >> 8) & 0xff); - str_c[2] = ((how >> 16) & 0xff); - str_c[3] = ((how >> 24) & 0xff); - str_c[4] = 0; - fprintf(stderr, "\r\nbail: %s\r\n", str_c); - } - else { - c3_assert(_(u3ud(u3h(how)))); - fprintf(stderr, "\r\nbail: %d\r\n", u3h(how)); + default: { + if ( _(u3ud(how)) ) { + c3_c str_c[5]; + + str_c[0] = ((how >> 0) & 0xff); + str_c[1] = ((how >> 8) & 0xff); + str_c[2] = ((how >> 16) & 0xff); + str_c[3] = ((how >> 24) & 0xff); + str_c[4] = 0; + fprintf(stderr, "\r\nbail: %s\r\n", str_c); + } + else if ( 1 != u3h(how) ) { + c3_assert(_(u3ud(u3h(how)))); + fprintf(stderr, "\r\nbail: %d\r\n", u3h(how)); + } } } @@ -803,6 +813,7 @@ u3m_leap(c3_w pad_w) u3R->cap_p -= len_w; rod_u = _pave_south(u3a_into(bot_p), c3_wiseof(u3a_road), len_w); + u3e_ward(rod_u->cap_p, rod_u->hat_p); #if 0 fprintf(stderr, "leap: from north %p (cap 0x%x), to south %p\r\n", u3R, @@ -815,6 +826,7 @@ u3m_leap(c3_w pad_w) u3R->cap_p += len_w; rod_u = _pave_north(u3a_into(bot_p), c3_wiseof(u3a_road), len_w); + u3e_ward(rod_u->hat_p, rod_u->cap_p); #if 0 fprintf(stderr, "leap: from south %p (cap 0x%x), to north %p\r\n", u3R, @@ -1713,16 +1725,53 @@ _cm_signals(void) # endif } -extern void u3je_secp_init(void); -extern void u3je_secp_stop(void); +/* _cm_malloc_ssl(): openssl-shaped malloc +*/ +static void* +_cm_malloc_ssl(size_t len_i +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + , const char* file, int line +#endif + ) +{ + return u3a_malloc(len_i); +} +/* _cm_realloc_ssl(): openssl-shaped realloc. +*/ +static void* +_cm_realloc_ssl(void* lag_v, size_t len_i +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + , const char* file, int line +#endif + ) +{ + return u3a_realloc(lag_v, len_i); +} + +/* _cm_free_ssl(): openssl-shaped free. +*/ +static void +_cm_free_ssl(void* tox_v +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + , const char* file, int line +#endif + ) +{ + return u3a_free(tox_v); +} + +extern void u3je_secp_init(void); + +/* _cm_crypto(): initialize openssl and crypto jets. +*/ static void _cm_crypto() { /* Initialize OpenSSL with loom allocation functions. */ - if ( 0 == CRYPTO_set_mem_functions(&u3a_malloc_ssl, - &u3a_realloc_ssl, - &u3a_free_ssl) ) { + if ( 0 == CRYPTO_set_mem_functions(&_cm_malloc_ssl, + &_cm_realloc_ssl, + &_cm_free_ssl) ) { u3l_log("%s\r\n", "openssl initialization failed"); abort(); } @@ -1730,53 +1779,81 @@ _cm_crypto() u3je_secp_init(); } +/* _cm_realloc2(): gmp-shaped realloc. +*/ +static void* +_cm_realloc2(void* lag_v, size_t old_i, size_t new_i) +{ + return u3a_realloc(lag_v, new_i); +} + +/* _cm_free2(): gmp-shaped free. +*/ +static void +_cm_free2(void* tox_v, size_t siz_i) +{ + return u3a_free(tox_v); +} + /* u3m_init(): start the environment. */ void -u3m_init(void) +u3m_init(size_t len_i) { _cm_limits(); _cm_signals(); _cm_crypto(); - /* Make sure GMP uses our malloc. - */ - mp_set_memory_functions(u3a_malloc, u3a_realloc2, u3a_free2); + // make sure GMP uses our malloc. + // + mp_set_memory_functions(u3a_malloc, _cm_realloc2, _cm_free2); - /* Map at fixed address. - */ + // make sure that [len_i] is a fully-addressible non-zero power of two. + // + if ( !len_i + || (len_i & (len_i - 1)) + || (len_i < (1 << (u3a_page + 2))) + || (len_i > u3a_bytes) ) { - c3_w len_w = u3a_bytes; - void* map_v; + u3l_log("loom: bad size: %zu\r\n", len_i); + exit(1); + } - map_v = mmap((void *)u3_Loom, - len_w, - (PROT_READ | PROT_WRITE), - (MAP_ANON | MAP_FIXED | MAP_PRIVATE), - -1, 0); + // map at fixed address. + // + { + void* map_v = mmap((void *)u3_Loom, + len_i, + (PROT_READ | PROT_WRITE), + (MAP_ANON | MAP_FIXED | MAP_PRIVATE), + -1, 0); if ( -1 == (c3_ps)map_v ) { - void* dyn_v = mmap((void *)0, - len_w, - PROT_READ, - MAP_ANON | MAP_PRIVATE, - -1, 0); + map_v = mmap((void *)0, + len_i, + (PROT_READ | PROT_WRITE), + (MAP_ANON | MAP_PRIVATE), + -1, 0); - u3l_log("boot: mapping %dMB failed\r\n", (len_w / (1024 * 1024))); + u3l_log("boot: mapping %zuMB failed\r\n", len_i >> 20); u3l_log("see urbit.org/using/install/#about-swap-space" " for adding swap space\r\n"); - if ( -1 != (c3_ps)dyn_v ) { + if ( -1 != (c3_ps)map_v ) { u3l_log("if porting to a new platform, try U3_OS_LoomBase %p\r\n", - dyn_v); + map_v); } exit(1); } - u3l_log("loom: mapped %dMB\r\n", len_w >> 20); + u3C.wor_i = len_i >> 2; + u3l_log("loom: mapped %zuMB\r\n", len_i >> 20); } } -/* u3m_stop(): graceful shutdown cleanup. */ +extern void u3je_secp_stop(void); + +/* u3m_stop(): graceful shutdown cleanup. +*/ void u3m_stop() { @@ -1786,13 +1863,13 @@ u3m_stop() /* u3m_boot(): start the u3 system. return next event, starting from 1. */ c3_d -u3m_boot(c3_c* dir_c) +u3m_boot(c3_c* dir_c, size_t len_i) { c3_o nuu_o; /* Activate the loom. */ - u3m_init(); + u3m_init(len_i); /* Activate the storage system. */ @@ -1825,7 +1902,6 @@ u3m_boot(c3_c* dir_c) if ( c3n == nuu_o ) { u3j_ream(); u3n_ream(); - return u3A->eve_d; } else { @@ -1839,11 +1915,11 @@ u3m_boot(c3_c* dir_c) /* u3m_boot_lite(): start without checkpointing. */ c3_d -u3m_boot_lite(void) +u3m_boot_lite(size_t len_i) { /* Activate the loom. */ - u3m_init(); + u3m_init(len_i); /* Activate tracing. */ @@ -1856,6 +1932,10 @@ u3m_boot_lite(void) */ u3m_pave(c3y); + /* Place the guard page. + */ + u3e_init(); + /* Initialize the jet system. */ u3j_boot(c3y); diff --git a/pkg/urbit/noun/nock.c b/pkg/urbit/noun/nock.c index 3722f1d61..dda8a4921 100644 --- a/pkg/urbit/noun/nock.c +++ b/pkg/urbit/noun/nock.c @@ -388,102 +388,107 @@ _n_nock_on(u3_noun bus, u3_noun fol) // the opcode's enum name, string representation, and computed goto into a // single structure. #define OPCODES \ - /* general purpose */ \ - X(HALT, "halt", &&do_halt), /* 0 */ \ - X(BAIL, "bail", &&do_bail), /* 1 */ \ + /* non-nock bytecodes */ \ + X(HALT, "halt", &&do_halt), /* 0: terminator, end of bytcode program */ \ + X(BAIL, "bail", &&do_bail), /* 1: deterministic crash */ \ + /* stack manipulation */ \ X(COPY, "copy", &&do_copy), /* 2 */ \ X(SWAP, "swap", &&do_swap), /* 3 */ \ X(TOSS, "toss", &&do_toss), /* 4 */ \ - X(AUTO, "auto", &&do_auto), /* 5 */ \ - X(AULT, "ault", &&do_ault), /* 6 */ \ - X(SNOC, "snoc", &&do_snoc), /* 7 */ \ - X(SNOL, "snol", &&do_snol), /* 8 */ \ - X(HEAD, "head", &&do_head), /* 9 */ \ - X(HELD, "held", &&do_held), /* 10 */ \ - X(TAIL, "tail", &&do_tail), /* 11 */ \ - X(TALL, "tall", &&do_tall), /* 12 */ \ - /* fragment (keep) */ \ - X(FABK, "fabk", &&do_fabk), /* 13 */ \ - X(FASK, "fask", &&do_fask), /* 14 */ \ - X(FIBK, "fibk", &&do_fibk), /* 15 */ \ - X(FISK, "fisk", &&do_fisk), /* 16 */ \ - /* fragment (lose) */ \ - X(FABL, "fabl", &&do_fabl), /* 17 */ \ - X(FASL, "fasl", &&do_fasl), /* 18 */ \ - X(FIBL, "fibl", &&do_fibl), /* 19 */ \ - X(FISL, "fisl", &&do_fisl), /* 20 */ \ - /* literal (keep) */ \ - X(LIT0, "lit0", &&do_lit0), /* 21 */ \ - X(LIT1, "lit1", &&do_lit1), /* 22 */ \ - X(LITB, "litb", &&do_litb), /* 23 */ \ - X(LITS, "lits", &&do_lits), /* 24 */ \ - X(LIBK, "libk", &&do_libk), /* 25 */ \ - X(LISK, "lisk", &&do_lisk), /* 26 */ \ - /* literal (lose) */ \ - X(LIL0, "lil0", &&do_lil0), /* 27 */ \ - X(LIL1, "lil1", &&do_lil1), /* 28 */ \ - X(LILB, "lilb", &&do_lilb), /* 29 */ \ - X(LILS, "lils", &&do_lils), /* 30 */ \ - X(LIBL, "libl", &&do_libl), /* 31 */ \ - X(LISL, "lisl", &&do_lisl), /* 32 */ \ - /* nock */ \ + /* auto-cons */ \ + X(AUTO, "auto", &&do_auto), /* 5: keep */ \ + X(AULT, "ault", &&do_ault), /* 6: lose */ \ + /* general purposes */ \ + X(SNOC, "snoc", &&do_snoc), /* 7: keep */ \ + X(SNOL, "snol", &&do_snol), /* 8: lose */ \ + /* nock 0: head */ \ + X(HEAD, "head", &&do_head), /* 9: keep */ \ + X(HELD, "held", &&do_held), /* 10: lose */ \ + /* nock 0: tail */ \ + X(TAIL, "tail", &&do_tail), /* 11: keep */ \ + X(TALL, "tall", &&do_tall), /* 12: lose */ \ + /* nock 0: fragment (keep) */ \ + X(FABK, "fabk", &&do_fabk), /* 13: c3_y */ \ + X(FASK, "fask", &&do_fask), /* 14: c3_s */ \ + X(FIBK, "fibk", &&do_fibk), /* 15: c3_y */ \ + X(FISK, "fisk", &&do_fisk), /* 16: c3_s */ \ + /* nock 0: fragment (lose) */ \ + X(FABL, "fabl", &&do_fabl), /* 17: c3_y */ \ + X(FASL, "fasl", &&do_fasl), /* 18: c3_s */ \ + X(FIBL, "fibl", &&do_fibl), /* 19: c3_y */ \ + X(FISL, "fisl", &&do_fisl), /* 20: c3_s */ \ + /* nock 1: literal (keep) */ \ + X(LIT0, "lit0", &&do_lit0), /* 21: a literal 0 */ \ + X(LIT1, "lit1", &&do_lit1), /* 22: a literal 1 */ \ + X(LITB, "litb", &&do_litb), /* 23: c3_y */ \ + X(LITS, "lits", &&do_lits), /* 24: c3_s */ \ + X(LIBK, "libk", &&do_libk), /* 25: c3_y */ \ + X(LISK, "lisk", &&do_lisk), /* 26: c3_s */ \ + /* nock 1: literal (lose) */ \ + X(LIL0, "lil0", &&do_lil0), /* 27: a literal 0 */ \ + X(LIL1, "lil1", &&do_lil1), /* 28: a literal 1 */ \ + X(LILB, "lilb", &&do_lilb), /* 29: c3_y */ \ + X(LILS, "lils", &&do_lils), /* 30: c3_s */ \ + X(LIBL, "libl", &&do_libl), /* 31: c3_y */ \ + X(LISL, "lisl", &&do_lisl), /* 32: c3_s */ \ + /* nock 2: nock (lose) */ \ X(NOLK, "nolk", &&do_nolk), /* 33 */ \ X(NOCT, "noct", &&do_noct), /* 34 */ \ X(NOCK, "nock", &&do_nock), /* 35 */ \ - /* 3 & 4 */ \ + /* nock 3 & 4 */ \ X(DEEP, "deep", &&do_deep), /* 36 */ \ X(BUMP, "bump", &&do_bump), /* 37 */ \ - /* equality */ \ - X(SAM0, "sam0", &&do_sam0), /* 38 */ \ - X(SAM1, "sam1", &&do_sam1), /* 39 */ \ - X(SAMB, "samb", &&do_samb), /* 40 */ \ - X(SAMS, "sams", &&do_sams), /* 41 */ \ - X(SANB, "sanb", &&do_sanb), /* 42 */ \ - X(SANS, "sans", &&do_sans), /* 43 */ \ + /* nock 5: equality */ \ + X(SAM0, "sam0", &&do_sam0), /* 38: test that it is equal to 0 */ \ + X(SAM1, "sam1", &&do_sam1), /* 39: test that it is equal to 1 */ \ + X(SAMB, "samb", &&do_samb), /* 40: test equality for vars size c3_b */ \ + X(SAMS, "sams", &&do_sams), /* 41: test equality for vars size c3_s */ \ + X(SANB, "sanb", &&do_sanb), /* 42: test equality for vars size c3_b */ \ + X(SANS, "sans", &&do_sans), /* 43: test equality for vars size c3_s */ \ X(SAME, "same", &&do_same), /* 44 */ \ X(SALM, "salm", &&do_salm), /* 45 */ \ X(SAMC, "samc", &&do_samc), /* 46 */ \ - /* unconditional skips */ \ - X(SBIP, "sbip", &&do_sbip), /* 47 */ \ - X(SIPS, "sips", &&do_sips), /* 48 */ \ - X(SWIP, "swip", &&do_swip), /* 49 */ \ - /* conditional skips */ \ - X(SBIN, "sbin", &&do_sbin), /* 50 */ \ - X(SINS, "sins", &&do_sins), /* 51 */ \ - X(SWIN, "swin", &&do_swin), /* 52 */ \ + /* related to nock 6: unconditional skips */ \ + X(SBIP, "sbip", &&do_sbip), /* 47: c3_b */ \ + X(SIPS, "sips", &&do_sips), /* 48: c3_s */ \ + X(SWIP, "swip", &&do_swip), /* 49: c3_l */ \ + /* related to nock 6: conditional skips */ \ + X(SBIN, "sbin", &&do_sbin), /* 50: c3_b */ \ + X(SINS, "sins", &&do_sins), /* 51: c3_s */ \ + X(SWIN, "swin", &&do_swin), /* 52: c3_l */ \ /* nock 9 */ \ - X(KICB, "kicb", &&do_kicb), /* 53 */ \ - X(KICS, "kics", &&do_kics), /* 54 */ \ - X(TICB, "ticb", &&do_ticb), /* 55 */ \ - X(TICS, "tics", &&do_tics), /* 56 */ \ - /* nock 12 */ \ + X(KICB, "kicb", &&do_kicb), /* 53: c3_b */ \ + X(KICS, "kics", &&do_kics), /* 54: c3_s */ \ + X(TICB, "ticb", &&do_ticb), /* 55: c3_b */ \ + X(TICS, "tics", &&do_tics), /* 56: c3_s */ \ + /* nock 12: scry (only defined in arvo, not in base nock spec) */ \ X(WILS, "wils", &&do_wils), /* 57 */ \ X(WISH, "wish", &&do_wish), /* 58 */ \ - /* hint processing */ \ - X(BUSH, "bush", &&do_bush), /* 59 */ \ - X(SUSH, "sush", &&do_sush), /* 60 */ \ + /* nock 11: hint processing */ \ + X(BUSH, "bush", &&do_bush), /* 59: c3_b */ \ + X(SUSH, "sush", &&do_sush), /* 60: c3_s */ \ X(DROP, "drop", &&do_drop), /* 61 */ \ X(HECK, "heck", &&do_heck), /* 62 */ \ X(SLOG, "slog", &&do_slog), /* 63 */ \ - /* fast (keep) */ \ - X(BAST, "bast", &&do_bast), /* 64 */ \ - X(SAST, "sast", &&do_sast), /* 65 */ \ - /* fast (lose) */ \ - X(BALT, "balt", &&do_balt), /* 66 */ \ - X(SALT, "salt", &&do_salt), /* 67 */ \ - /* memo (keep) */ \ - X(SKIB, "skib", &&do_skib), /* 68 */ \ - X(SKIS, "skis", &&do_skis), /* 69 */ \ - /* memo (lose) */ \ - X(SLIB, "slib", &&do_slib), /* 70 */ \ - X(SLIS, "slis", &&do_slis), /* 71 */ \ + /* nock 11: fast (keep) */ \ + X(BAST, "bast", &&do_bast), /* 64: c3_b */ \ + X(SAST, "sast", &&do_sast), /* 65: c3_s */ \ + /* nock 11: fast (lose) */ \ + X(BALT, "balt", &&do_balt), /* 66: c3_b */ \ + X(SALT, "salt", &&do_salt), /* 67: c3_s */ \ + /* nock 11: memo (keep) */ \ + X(SKIB, "skib", &&do_skib), /* 68: c3_b */ \ + X(SKIS, "skis", &&do_skis), /* 69: c3_s */ \ + /* nock 11: memo (lose) */ \ + X(SLIB, "slib", &&do_slib), /* 70: c3_b */ \ + X(SLIS, "slis", &&do_slis), /* 71: c3_s */ \ X(SAVE, "save", &&do_save), /* 72 */ \ - /* before formula */ \ + /* nock 11: before formula */ \ X(HILB, "hilb", &&do_hilb), /* 73: atomic, byte */ \ X(HILS, "hils", &&do_hils), /* 74: atomic, short */ \ X(HINB, "hinb", &&do_hinb), /* 75: arbitrary, byte */ \ X(HINS, "hins", &&do_hins), /* 76: arbitrary, short */ \ - /* after formula */ \ + /* nock 11: after formula */ \ X(HILK, "hilk", &&do_hilk), /* 77: atomic, keep */ \ X(HILL, "hill", &&do_hill), /* 78: atomic, lose */ \ X(HINK, "hink", &&do_hink), /* 79: arbitrary, keep */ \ @@ -495,14 +500,14 @@ _n_nock_on(u3_noun bus, u3_noun fol) X(KUTT, "kutt", &&do_kutt), /* 84 */ \ X(MUSM, "musm", &&do_musm), /* 85 */ \ X(KUSM, "kusm", &&do_kusm), /* 86 */ \ - X(MUTB, "mutb", &&do_mutb), /* 87 */ \ - X(MUTS, "muts", &&do_muts), /* 88 */ \ - X(MITB, "mitb", &&do_mitb), /* 89 */ \ - X(MITS, "mits", &&do_mits), /* 90 */ \ - X(KUTB, "kutb", &&do_kutb), /* 91 */ \ - X(KUTS, "kuts", &&do_kuts), /* 92 */ \ - X(KITB, "kitb", &&do_kitb), /* 93 */ \ - X(KITS, "kits", &&do_kits), /* 94 */ \ + X(MUTB, "mutb", &&do_mutb), /* 87: c3_b */ \ + X(MUTS, "muts", &&do_muts), /* 88: c3_s */ \ + X(MITB, "mitb", &&do_mitb), /* 89: c3_b */ \ + X(MITS, "mits", &&do_mits), /* 90: c3_s */ \ + X(KUTB, "kutb", &&do_kutb), /* 91: c3_b */ \ + X(KUTS, "kuts", &&do_kuts), /* 92: c3_s */ \ + X(KITB, "kitb", &&do_kitb), /* 93: c3_b */ \ + X(KITS, "kits", &&do_kits), /* 94: c3_s */ \ X(LAST, NULL, NULL), /* 95 */ // Opcodes. Define X to select the enum name from OPCODES. @@ -522,6 +527,7 @@ _n_arg(c3_y cod_y) case SLIB: case SKIB: case KICB: case TICB: case BUSH: case BAST: case BALT: case MUTB: case KUTB: case MITB: case KITB: + case HILB: case HINB: return sizeof(c3_y); case FASK: case FASL: case FISL: case FISK: @@ -530,6 +536,7 @@ _n_arg(c3_y cod_y) case SLIS: case SKIS: case KICS: case TICS: case SUSH: case SAST: case SALT: case MUTS: case KUTS: case MITS: case KITS: + case HILS: case HINS: return sizeof(c3_s); case SWIP: case SWIN: @@ -779,7 +786,7 @@ _n_prog_asm(u3_noun ops, u3n_prog* pog_u, u3_noun sip) if ( c3y == u3ud(op) ) { switch ( op ) { default: - buf_y[i_w] = (c3_y) u3h(ops); + buf_y[i_w] = (c3_y) op; break; /* registration site index args */ @@ -956,12 +963,10 @@ static void _n_print_stack(u3p(u3_noun) empty) { } #endif -#ifdef VERBOSE_BYTECODE // Define X to select the opcode string representation from OPCODES. # define X(opcode, name, indirect_jump) name static c3_c* opcode_names[] = { OPCODES }; # undef X -#endif /* _n_apen(): emit the instructions contained in src to dst */ @@ -998,6 +1003,7 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o) default: { return _n_comp(ops, nef, los_o, tel_o); } + case c3__xray: case c3__nara: case c3__hela: case c3__bout: { @@ -1034,6 +1040,7 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o) ++tot_w; _n_emit(ops, TOSS); tot_w += _n_comp(ops, nef, los_o, tel_o); } break; + case c3__xray: case c3__nara: case c3__hela: case c3__bout: { @@ -1665,6 +1672,144 @@ u3n_find(u3_noun key, u3_noun fol) return pog_p; } +/* _cn_prog_free(): free memory retained by program pog_u +*/ +static void +_cn_prog_free(u3n_prog* pog_u) +{ + c3_w dex_w; + for (dex_w = 0; dex_w < pog_u->lit_u.len_w; ++dex_w) { + u3z(pog_u->lit_u.non[dex_w]); + } + for (dex_w = 0; dex_w < pog_u->mem_u.len_w; ++dex_w) { + u3z(pog_u->mem_u.sot_u[dex_w].key); + } + for (dex_w = 0; dex_w < pog_u->cal_u.len_w; ++dex_w) { + u3j_site_lose(&(pog_u->cal_u.sit_u[dex_w])); + } + for (dex_w = 0; dex_w < pog_u->reg_u.len_w; ++dex_w) { + u3j_rite_lose(&(pog_u->reg_u.rit_u[dex_w])); + } + u3a_free(pog_u); +} + +/* _cn_intlen(): find the number of characters num_w would take to print. +** num_w: an int we want to later serialize to a string +*/ +c3_w +_cn_intlen(c3_w num_w) +{ + c3_w len_w=0; + while(num_w){ + num_w/=10; + len_w++; + } + return len_w; +} + +/* _cn_is_indexed(): return true if bop_w is an opcodes that uses pog_u->lit_u.non +** bop_w: opcode (assumed 0-94) +*/ +c3_b +_cn_is_indexed(c3_w bop_w) +{ + switch (bop_w) { + case FIBK: case FISK: + case FIBL: case FISL: + case LIBK: case LISK: + case LIBL: case LISL: + case BUSH: case SUSH: + case SANB: case SANS: + case KITB: case KITS: + case MITB: case MITS: + case HILB: case HILS: + case HINB: case HINS: + return 1; + default: + return 0; + } +} + +/* _cn_pog_to_num(): read a bytecode from the steam and advance the index +** par_w: c3_w: can be 0, 2, 4 +** pog_y: c3_y*: a bytecode stream +** ip_w: c3_w: an index into pog +*/ +#define _cn_pog_to_num(par_w, pog_y, ip_w) (\ + par_w == 4 ? _n_rewo(pog_y, &ip_w): \ + par_w == 2 ? _n_resh(pog_y, &ip_w): \ + pog_y[ip_w++]) + +/* _cn_etch_bytecode(): render a nock program as string of bytecodes +** fol: a nock formula to compile and render +** returns: a u3i_string noun of the rendered bytecode +*/ +u3_noun +_cn_etch_bytecode(u3_noun fol) { + u3n_prog* pog_u = _n_bite(fol); + c3_y* pog_y = pog_u->byc_u.ops_y; + c3_w len_w = pog_u->byc_u.len_w; + c3_w ip_w=0, num_w=0, bop_w=0, dex_w=0; + c3_w len_c = 1; // opening "{" + // set par_w (parameter flag) to an invalid value, + // so we can break imeadately if needed + c3_w par_w = 5; + // lets count the chars in this string + while ( ip_w < len_w ) { + par_w = _n_arg(pog_y[ip_w]); + bop_w = pog_y[ip_w++]; // move ip_w for reading a opcode name + dex_w = _cn_is_indexed(bop_w); // is this an indexed bytecode argument + len_c += 5; // a leading space, and opcode name + if (par_w > 0) { // if pair: "[bytecode arg]" else "bytecode" + len_c += 3; // "[", space between opcode & arg, "]" + if ( dex_w ) len_c += 2; // 'i:' + len_c += _cn_intlen( // length of the bytecode argument + _cn_pog_to_num(par_w, pog_y, ip_w) + ); + } + } + // reset so we can loop again + ip_w=0, num_w=0, bop_w=0, dex_w=0, par_w=5; + // init our string, and give it a trailing null + c3_c str_c[len_c]; + str_c[0] = 0; + // lets print this string + while ( ip_w < len_w ) { + par_w = _n_arg(pog_y[ip_w]); + bop_w = pog_y[ip_w++]; // move ip_w for reading a opcode name + dex_w = _cn_is_indexed(bop_w); // is this an indexed bytecode argument + strcat(str_c, " "); // leading space + if (par_w > 0) strcat(str_c, "["); // add "[" if the opcode pairs + strncat(str_c, opcode_names[bop_w], 4); // add the opcode name + if (par_w > 0) { // finish the pair + strcat(str_c, " "); // add the space between byt and arg + if ( dex_w ) strcat(str_c, "i:"); // indexed args are labeled as "index of arg" + num_w = _cn_pog_to_num(par_w, pog_y, ip_w); // the bytecode argument + if (num_w == 0) { // + strcat(str_c, "0"); // handle a literal zero + } // + else { // + c3_w x = 0; // + for (x = _cn_intlen(num_w); x > 0; x--) { // + strcat(str_c, "_"); // prefill the buffer + } // + c3_w f = strlen(str_c)-1; // get the index of the last prefill + while (num_w > 0) { // stringify number in LSB order + str_c[f--] = (num_w%10)+'0'; // .. stringify the tail of num into tail of buf + num_w /= 10; // .. turncate num by one digit + } // + } // + strcat(str_c, "]"); // add the closing brace + } + } + // replace the first leading space and append the last char to the string + str_c[0] = '{'; + strcat(str_c, "}"); + _cn_prog_free(pog_u); + return u3i_string(str_c); +} + + /* _n_hilt_fore(): literal (atomic) dynamic hint, before formula evaluation. ** hin: [hint-atom, formula]. TRANSFER ** bus: subject. RETAIN @@ -1695,6 +1840,11 @@ _n_hilt_fore(u3_noun hin, u3_noun bus, u3_noun* out) *out = u3_nul; } break; + case c3__xray : { + u3t_slog(u3nc(0, _cn_etch_bytecode(fol))); + *out = u3_nul; + } break; + default: { *out = u3_nul; } break; @@ -1769,6 +1919,16 @@ _n_hint_fore(u3_cell hin, u3_noun bus, u3_noun* clu) *clu = u3_nul; } break; + case c3__xray : { + u3_noun pri, tan; + if ( c3y == u3r_cell(*clu, &pri, &tan) ) { + c3_l pri_l = c3y == u3a_is_cat(pri) ? pri : 0; + u3t_slog_cap(pri_l, u3k(tan), _cn_etch_bytecode(fol)); + } + u3z(*clu); + *clu = u3_nul; + } break; + default: { u3z(*clu); *clu = u3_nul; @@ -2646,32 +2806,6 @@ u3n_nock_on(u3_noun bus, u3_noun fol) return pro; } -/* _n_prog_free(): free memory retained by program -*/ -static void -_n_prog_free(u3n_prog* pog_u) -{ - c3_w i_w; - - for ( i_w = 0; i_w < pog_u->lit_u.len_w; ++i_w ) { - u3z(pog_u->lit_u.non[i_w]); - } - - for ( i_w = 0; i_w < pog_u->mem_u.len_w; ++i_w ) { - u3z(pog_u->mem_u.sot_u[i_w].key); - } - - for ( i_w = 0; i_w < pog_u->cal_u.len_w; ++i_w ) { - u3j_site_lose(&(pog_u->cal_u.sit_u[i_w])); - } - - for ( i_w = 0; i_w < pog_u->reg_u.len_w; ++i_w ) { - u3j_rite_lose(&(pog_u->reg_u.rit_u[i_w])); - } - - u3a_free(pog_u); -} - /* _cn_take_prog_dat(): take references from junior u3n_prog. */ static void @@ -2920,7 +3054,7 @@ u3n_rewrite_compact() static void _n_feb(u3_noun kev) { - _n_prog_free(u3to(u3n_prog, u3t(kev))); + _cn_prog_free(u3to(u3n_prog, u3t(kev))); } /* u3n_free(): free bytecode cache diff --git a/pkg/urbit/noun/retrieve.c b/pkg/urbit/noun/retrieve.c index c207c7f47..06a9fb2fe 100644 --- a/pkg/urbit/noun/retrieve.c +++ b/pkg/urbit/noun/retrieve.c @@ -1023,10 +1023,11 @@ u3r_hext(u3_noun a, ** (1 << a_y). ** ** For example, (a_y == 3) returns the size in bytes. +** NB: (a_y) must be < 37. */ c3_w -u3r_met(c3_y a_y, - u3_atom b) +u3r_met(c3_y a_y, + u3_atom b) { c3_assert(u3_none != b); c3_assert(_(u3a_is_atom(b))); @@ -1061,19 +1062,23 @@ u3r_met(c3_y a_y, */ c3_w bif_w, col_w; + if ( gal_w > ((UINT32_MAX - 35) >> 5) ) { + return u3m_bail(c3__fail); + } + col_w = c3_bits_word(daz_w); bif_w = col_w + (gal_w << 5); return (bif_w + ((1 << a_y) - 1)) >> a_y; } - case 3: { - return (gal_w << 2) - + ((daz_w >> 24) ? 4 : (daz_w >> 16) ? 3 : (daz_w >> 8) ? 2 : 1); - } - case 4: { - return (gal_w << 1) - + ((daz_w >> 16) ? 2 : 1); - } + + STATIC_ASSERT((UINT32_MAX > ((c3_d)u3a_maximum << 2)), + "met overflow"); + + case 3: return (gal_w << 2) + ((c3_bits_word(daz_w) + 7) >> 3); + + case 4: return (gal_w << 1) + ((c3_bits_word(daz_w) + 15) >> 4); + default: { c3_y gow_y = (a_y - 5); @@ -1448,79 +1453,201 @@ u3r_safe_chub(u3_noun dat, c3_d* out_d) return c3y; } +/* u3r_chop_bits(): +** +** XOR `wid_d` bits from`src_w` at `bif_g` to `dst_w` at `bif_g` +** +** NB: [dst_w] must have space for [bit_g + wid_d] bits +*/ +void +u3r_chop_bits(c3_g bif_g, + c3_d wid_d, + c3_g bit_g, + c3_w* dst_w, + const c3_w* src_w) +{ + c3_y fib_y = 32 - bif_g; + c3_y tib_y = 32 - bit_g; + + // we need to chop words + // + if ( wid_d >= tib_y ) { + // align *dst_w + // + if ( bit_g ) { + c3_w low_w = src_w[0] >> bif_g; + + if ( bif_g > bit_g ) { + low_w ^= src_w[1] << fib_y; + } + + *dst_w++ ^= low_w << bit_g; + + wid_d -= tib_y; + bif_g += tib_y; + src_w += !!(bif_g >> 5); + bif_g &= 31; + fib_y = 32 - bif_g; + } + + { + size_t i_i, byt_i = wid_d >> 5; + + if ( !bif_g ) { + for ( i_i = 0; i_i < byt_i; i_i++ ) { + dst_w[i_i] ^= src_w[i_i]; + } + } + else { + for ( i_i = 0; i_i < byt_i; i_i++ ) { + dst_w[i_i] ^= (src_w[i_i] >> bif_g) ^ (src_w[i_i + 1] << fib_y); + } + } + + src_w += byt_i; + dst_w += byt_i; + wid_d &= 31; + bit_g = 0; + } + } + + // we need to chop (more) bits + // + if ( wid_d ) { + c3_w hig_w = src_w[0] >> bif_g; + + if ( wid_d > fib_y ) { + hig_w ^= src_w[1] << fib_y; + } + + *dst_w ^= (hig_w & ((1 << wid_d) - 1)) << bit_g; + } +} + +/* u3r_chop_words(): +** +** Into the bloq space of `met`, from position `fum` for a +** span of `wid`, to position `tou`, XOR from `src_w` +** into `dst_w`. +** +** NB: [dst_w] must have space for [tou_w + wid_w] bloqs +*/ +void +u3r_chop_words(c3_g met_g, + c3_w fum_w, + c3_w wid_w, + c3_w tou_w, + c3_w* dst_w, + c3_w len_w, + const c3_w* src_w) +{ + // operate on words + // + if ( met_g >= 5 ) { + size_t i_i, wid_i; + + { + c3_g hut_g = met_g - 5; + size_t fum_i = (size_t)fum_w << hut_g; + size_t tou_i = (size_t)tou_w << hut_g; + size_t tot_i; + + wid_i = (size_t)wid_w << hut_g; + tot_i = fum_i + wid_i; + + // since [dst_w] must have space for (tou_w + wid_w) bloqs, + // neither conversion can overflow + // + if ( (fum_i >> hut_g != fum_w) || (tot_i - wid_i != fum_i) ) { + u3m_bail(c3__fail); + return; + } + else if ( fum_i >= len_w ) { + return; + } + + if ( tot_i > len_w ) { + wid_i -= tot_i - len_w; + } + + src_w += fum_i; + dst_w += tou_i; + } + + for ( i_i = 0; i_i < wid_i; i_i++ ) { + dst_w[i_i] ^= src_w[i_i]; + } + } + // operate on bits + // + else { + c3_d wid_d = (c3_d)wid_w << met_g; + c3_g bif_g, bit_g; + + { + c3_d len_d = (c3_d)len_w << 5; + c3_d fum_d = (c3_d)fum_w << met_g; + c3_d tou_d = (c3_d)tou_w << met_g; + c3_d tot_d = fum_d + wid_d; + + // see above + // + if ( (fum_d >> met_g != fum_w) || (tot_d - wid_d != fum_d) ) { + u3m_bail(c3__fail); + return; + } + else if ( fum_d > len_d ) { + return; + } + + if ( tot_d > len_d ) { + wid_d -= tot_d - len_d; + } + + src_w += fum_d >> 5; + dst_w += tou_d >> 5; + bif_g = fum_d & 31; + bit_g = tou_d & 31; + } + + u3r_chop_bits(bif_g, wid_d, bit_g, dst_w, src_w); + } +} + /* u3r_chop(): ** ** Into the bloq space of `met`, from position `fum` for a ** span of `wid`, to position `tou`, XOR from atom `src` ** into `dst_w`. +** +** NB: [dst_w] must have space for [tou_w + wid_w] bloqs */ void -u3r_chop(c3_g met_g, - c3_w fum_w, - c3_w wid_w, - c3_w tou_w, - c3_w* dst_w, - u3_atom src) +u3r_chop(c3_g met_g, + c3_w fum_w, + c3_w wid_w, + c3_w tou_w, + c3_w* dst_w, + u3_atom src) { - c3_w i_w; + c3_w* src_w; c3_w len_w; - c3_w* buf_w; - - c3_assert(u3_none != src); - c3_assert(_(u3a_is_atom(src))); if ( _(u3a_is_cat(src)) ) { len_w = src ? 1 : 0; - buf_w = &src; + src_w = &src; } else { u3a_atom* src_u = u3a_to_ptr(src); + c3_assert(u3_none != src); + c3_assert(_(u3a_is_atom(src))); + len_w = src_u->len_w; - buf_w = src_u->buf_w; + src_w = src_u->buf_w; } - if ( met_g < 5 ) { - c3_w san_w = (1 << met_g); - c3_w mek_w = ((1 << san_w) - 1); - c3_w baf_w = (fum_w << met_g); - c3_w bat_w = (tou_w << met_g); - - // XX: efficiency: poor. Iterate by words. - // - for ( i_w = 0; i_w < wid_w; i_w++ ) { - c3_w waf_w = (baf_w >> 5); - c3_g raf_g = (baf_w & 31); - c3_w wat_w = (bat_w >> 5); - c3_g rat_g = (bat_w & 31); - c3_w hop_w; - - hop_w = (waf_w >= len_w) ? 0 : buf_w[waf_w]; - hop_w = (hop_w >> raf_g) & mek_w; - - dst_w[wat_w] ^= (hop_w << rat_g); - - baf_w += san_w; - bat_w += san_w; - } - } - else { - c3_g hut_g = (met_g - 5); - c3_w san_w = (1 << hut_g); - c3_w j_w; - - for ( i_w = 0; i_w < wid_w; i_w++ ) { - c3_w wuf_w = (fum_w + i_w) << hut_g; - c3_w wut_w = (tou_w + i_w) << hut_g; - - for ( j_w = 0; j_w < san_w; j_w++ ) { - dst_w[wut_w + j_w] ^= - ((wuf_w + j_w) >= len_w) - ? 0 - : buf_w[wuf_w + j_w]; - } - } - } + u3r_chop_words(met_g, fum_w, wid_w, tou_w, dst_w, len_w, src_w); } /* u3r_string(): `a` as malloced C string. @@ -1676,9 +1803,7 @@ u3r_mug_words(const c3_w* key_w, c3_w len_w) c3_w gal_w = len_w - 1; c3_w daz_w = key_w[gal_w]; - byt_w = (gal_w << 2) - + ((daz_w >> 24) ? 4 : (daz_w >> 16) ? 3 : (daz_w >> 8) ? 2 : 1); - + byt_w = (gal_w << 2) + ((c3_bits_word(daz_w) + 7) >> 3); } // XX: assumes little-endian diff --git a/pkg/urbit/noun/vortex.c b/pkg/urbit/noun/vortex.c index 03d174e1f..016588ea8 100644 --- a/pkg/urbit/noun/vortex.c +++ b/pkg/urbit/noun/vortex.c @@ -216,6 +216,32 @@ u3v_peek(u3_noun sam) return u3n_slam_on(fun, sam); } +/* u3v_soft_peek(): softly query the reck namespace. +*/ +u3_noun +u3v_soft_peek(c3_w mil_w, u3_noun sam) +{ + u3_noun gon = u3m_soft(mil_w, u3v_peek, sam); + u3_noun tag, dat; + u3x_cell(gon, &tag, &dat); + + // read failed, produce trace + // + // NB, reads *should not* fail deterministically + // + if ( u3_blip != tag ) { + return u3nc(c3n, gon); + } + + // read succeeded, produce result + // + { + u3_noun pro = u3nc(c3y, u3k(dat)); + u3z(gon); + return pro; + } +} + /* u3v_poke(): insert and apply an input ovum (protected). */ u3_noun diff --git a/pkg/urbit/tests/ames_tests.c b/pkg/urbit/tests/ames_tests.c index 69ed7b9b9..0907898d4 100644 --- a/pkg/urbit/tests/ames_tests.c +++ b/pkg/urbit/tests/ames_tests.c @@ -6,7 +6,7 @@ static void _setup(void) { - u3m_init(); + u3m_init(1 << 22); u3m_pave(c3y); } diff --git a/pkg/urbit/tests/boot_tests.c b/pkg/urbit/tests/boot_tests.c new file mode 100644 index 000000000..1897bbe93 --- /dev/null +++ b/pkg/urbit/tests/boot_tests.c @@ -0,0 +1,68 @@ +#include "all.h" +#include "ur/ur.h" +#include "vere/ivory.h" +#include "vere/vere.h" + +/* _setup(): prepare for tests. +*/ +static void +_setup(void) +{ + c3_d len_d = u3_Ivory_pill_len; + c3_y* byt_y = u3_Ivory_pill; + u3_cue_xeno* sil_u; + u3_weak pil; + + u3C.wag_w |= u3o_hashless; + u3m_boot_lite(1 << 26); + sil_u = u3s_cue_xeno_init_with(ur_fib27, ur_fib28); + if ( u3_none == (pil = u3s_cue_xeno_with(sil_u, len_d, byt_y)) ) { + printf("*** fail _setup 1\n"); + exit(1); + } + u3s_cue_xeno_done(sil_u); + if ( c3n == u3v_boot_lite(pil) ) { + printf("*** fail _setup 2\n"); + exit(1); + } +} + +/* _test_lily(): test small noun parsing. +*/ +static void +_test_lily() +{ + c3_l lit_l; + c3_w big_w[] = {0, 0, 1}; + u3_noun big = u3i_words(3, big_w); + u3_noun cod = u3dc("scot", c3__uv, big); + + if ( c3y == u3v_lily(c3__uv, cod, &lit_l) ) { + printf("*** fail _test_lily-1\n"); + exit(1); + } + cod = u3dc("scot", c3__ud, 0x7fffffff); + if ( (c3n == u3v_lily(c3__ud, cod, &lit_l)) || + (0x7fffffff != lit_l) ) { + printf("*** fail _test_lily-2a\n"); + exit(1); + } + cod = u3dc("scot", c3__ux, u3i_word(0x80000000)); + if ( c3y == u3v_lily(c3__ux, cod, &lit_l) ) { + printf("*** fail _test_lily-2b\n"); + exit(1); + } +} + +/* main(): run all test cases. +*/ +int +main(int argc, char* argv[]) +{ + _setup(); + + _test_lily(); + + fprintf(stderr, "test boot: ok\n"); + return 0; +} diff --git a/pkg/urbit/tests/hashtable_tests.c b/pkg/urbit/tests/hashtable_tests.c index 6322a331c..3b36dc887 100644 --- a/pkg/urbit/tests/hashtable_tests.c +++ b/pkg/urbit/tests/hashtable_tests.c @@ -9,7 +9,7 @@ c3_w _ch_skip_slot(c3_w mug_w, c3_w lef_w); static void _setup(void) { - u3m_init(); + u3m_init(1 << 26); u3m_pave(c3y); } diff --git a/pkg/urbit/tests/jam_tests.c b/pkg/urbit/tests/jam_tests.c index eebc27fc1..fd416945d 100644 --- a/pkg/urbit/tests/jam_tests.c +++ b/pkg/urbit/tests/jam_tests.c @@ -6,8 +6,9 @@ static void _setup(void) { - u3m_init(); + u3m_init(1 << 24); u3m_pave(c3y); + u3e_init(); } static void diff --git a/pkg/urbit/tests/jet_tests.c b/pkg/urbit/tests/jet_tests.c index 2e96f2305..4904a959d 100644 --- a/pkg/urbit/tests/jet_tests.c +++ b/pkg/urbit/tests/jet_tests.c @@ -5,7 +5,7 @@ static void _setup(void) { - u3m_init(); + u3m_init(1 << 20); u3m_pave(c3y); } diff --git a/pkg/urbit/tests/mug_tests.c b/pkg/urbit/tests/mug_tests.c index 7ac9783d2..ffd051674 100644 --- a/pkg/urbit/tests/mug_tests.c +++ b/pkg/urbit/tests/mug_tests.c @@ -5,7 +5,7 @@ static void _setup(void) { - u3m_init(); + u3m_init(1 << 20); u3m_pave(c3y); } diff --git a/pkg/urbit/tests/newt_tests.c b/pkg/urbit/tests/newt_tests.c index 043151784..6fdbdb759 100644 --- a/pkg/urbit/tests/newt_tests.c +++ b/pkg/urbit/tests/newt_tests.c @@ -6,7 +6,7 @@ static void _setup(void) { - u3m_init(); + u3m_init(1 << 20); u3m_pave(c3y); } diff --git a/pkg/urbit/tests/nock_tests.c b/pkg/urbit/tests/nock_tests.c index 19c7ef200..a96ed09bd 100644 --- a/pkg/urbit/tests/nock_tests.c +++ b/pkg/urbit/tests/nock_tests.c @@ -5,7 +5,10 @@ static void _setup(void) { - u3m_init(); + // XX at 1<<24, this succeeds on mac, but bail:exit's on linux. + // investigate possible u3n_prog corruption + // + u3m_init(1 << 25); u3m_pave(c3y); u3e_init(); } diff --git a/pkg/urbit/tests/noun_tests.c b/pkg/urbit/tests/noun_tests.c index b84b61865..af54cd289 100644 --- a/pkg/urbit/tests/noun_tests.c +++ b/pkg/urbit/tests/noun_tests.c @@ -1,7 +1,4 @@ #include "all.h" -#include "ur/ur.h" -#include "vere/ivory.h" -#include "vere/vere.h" #define TRUE 1 #define FALSE 0 @@ -11,23 +8,358 @@ static void _setup(void) { - c3_d len_d = u3_Ivory_pill_len; - c3_y* byt_y = u3_Ivory_pill; - u3_cue_xeno* sil_u; - u3_weak pil; + u3m_init(1 << 20); + u3m_pave(c3y); +} - u3C.wag_w |= u3o_hashless; - u3m_boot_lite(); - sil_u = u3s_cue_xeno_init_with(ur_fib27, ur_fib28); - if ( u3_none == (pil = u3s_cue_xeno_with(sil_u, len_d, byt_y)) ) { - printf("*** fail _setup 1\n"); - exit(1); +/* _test_u3r_chop: "extract bit slices from atom" +*/ +static c3_i +_test_u3r_chop() +{ + c3_i ret_i = 1; + c3_w dst_w = 0; + u3_atom src = 0b11011; + + // bloq 0 + // + { + // read 1 bit from pos=0 (far right) + // + dst_w = 0; + u3r_chop(0, 0, 1, 0, &dst_w, src); + if ( 0x1 != dst_w ) { + fprintf(stderr, "test: u3r_chop: bloq 0, 0\r\n"); + ret_i = 0; + } + + // read 1 bit from pos=1 + // + dst_w = 0; + u3r_chop(0, 1, 1, 0, &dst_w, src); + if ( 0x1 != dst_w ) { + fprintf(stderr, "test: u3r_chop: bloq 0, 1\r\n"); + ret_i = 0; + } + + // read 1 bit from pos=2 + // + dst_w = 0; + u3r_chop(0, 2, 1, 0, &dst_w, src); + if ( 0x0 != dst_w ) { + fprintf(stderr, "test: u3r_chop: bloq 0, 2\r\n"); + ret_i = 0; + } + + // read 4 x 1 bit bloq from pos=0 + // + dst_w = 0; + u3r_chop(0, 0, 4, 0, &dst_w, src); + if ( 0b1011 != dst_w ) { + fprintf(stderr, "test: u3r_chop: bloq 0, 3\r\n"); + ret_i = 0; + } + + // read 4 x 1 bit bloq from pos=0 into offset 1 + // + dst_w = 0; + u3r_chop(0, 0, 4, 1, &dst_w, src); + if ( 0b10110 != dst_w ) { + fprintf(stderr, "test: u3r_chop: bloq 0, 4\r\n"); + ret_i = 0; + } } - u3s_cue_xeno_done(sil_u); - if ( c3n == u3v_boot_lite(pil) ) { - printf("*** fail _setup 2\n"); - exit(1); + + // bloq 1 + // + { + // read 2 bit from pos=0 (far right) + // + dst_w = 0; + u3r_chop(1, 0, 1, 0, &dst_w, src); + if ( 0b11 != dst_w ) { + fprintf(stderr, "test: u3r_chop: bloq 1, 0\r\n"); + ret_i = 0; + } + + // read 2 bit from pos=1 + // + dst_w = 0; + u3r_chop(1, 1, 1, 0, &dst_w, src); + if ( 0b10 != dst_w ) { + fprintf(stderr, "test: u3r_chop: bloq 1, 1\r\n"); + ret_i = 0; + } + + // read 2 bit from pos=2 (2 bloq over) + dst_w = 0; + u3r_chop(1, 2, 1, 0, &dst_w, src); + if ( 0b01 != dst_w ) { + fprintf(stderr, "test: u3r_chop: bloq 1, 2\r\n"); + ret_i = 0; + } } + + // bloq 3 + { + dst_w = 0; + u3r_chop(3, 0, 1, 0, &dst_w, src); + if ( 0b11011 != dst_w ) { + fprintf(stderr, "test: u3r_chop: bloq 3, 0\r\n"); + ret_i = 0; + } + } + + // read 1,8,16 bit bloqs from an indirect atom + // + { + src = u3i_string("abcdefghij"); + + // 1 bit pos=0 (far right) + // + dst_w = 0; + u3r_chop(0, 0, 1, 0, &dst_w, src); + if ( 0b1 != dst_w ) { + fprintf(stderr, "test: u3r_chop: indirect 0\r\n"); + ret_i = 0; + } + + // 8 bits pos=0 + // + dst_w = 0; + u3r_chop(0, 0, 8, 0, &dst_w, src); + if ( 0b1100001 != dst_w ) { + fprintf(stderr, "test: u3r_chop: indirect 1\r\n"); + ret_i = 0; + } + + // 1 byte pos=0 + // + dst_w = 0; + u3r_chop(3, 0, 1, 0, &dst_w, src); + if ( 0b1100001 != dst_w ) { + fprintf(stderr, "test: u3r_chop: indirect 2\r\n"); + ret_i = 0; + } + + // 1 short pos=0 + // + dst_w = 0; + u3r_chop(4, 0, 1, 0, &dst_w, src); + if ( 0b0110001001100001 != dst_w ) { + fprintf(stderr, "test: u3r_chop: indirect 3\r\n"); + ret_i = 0; + } + + u3z(src); + } + + // read lots of bits from a direct noun which holds 64 bits of data + // makes sure that we handle top 32 / bottom 32 correctly + { + c3_y inp_y[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; + src = u3i_bytes(8, inp_y); + + c3_w dst_w[2] = {0}; + u3r_chop(0, 0, 63, 0, dst_w, src); + if ( (0x3020100 != dst_w[0]) || (0x7060504 != dst_w[1]) ) { + fprintf(stderr, "test: u3r_chop: indirect 4\r\n"); + ret_i = 0; + } + + u3z(src); + } + + // as above (read lots of bits from a direct noun which holds 64 bits of data + // makes sure that we handle top 32 / bottom 32 correctly) + // but with a bit more nuance + { + c3_y inp_y[8] = { 0x0, 0x0, 0x0, 0xaa, 0xff, 0x0, 0x0, 0x0 }; + src = u3i_bytes(8, (c3_y*)inp_y); + + dst_w = 0; + u3r_chop(0, 24, 16, 0, &dst_w, src); + if ( 0b1111111110101010 != dst_w ) { + fprintf(stderr, "test: u3r_chop: indirect 5\r\n"); + ret_i = 0; + } + + u3z(src); + } + + return ret_i; +} + +/* _test_chop_slow(): "golden master" for chop tests (formerly u3r_chop()) +*/ +void +_test_chop_slow(c3_g met_g, + c3_w fum_w, + c3_w wid_w, + c3_w tou_w, + c3_w* dst_w, + c3_w len_w, + c3_w* buf_w) +{ + c3_w i_w; + + if ( met_g < 5 ) { + c3_w san_w = (1 << met_g); + c3_w mek_w = ((1 << san_w) - 1); + c3_w baf_w = (fum_w << met_g); + c3_w bat_w = (tou_w << met_g); + + // XX: efficiency: poor. Iterate by words. + // + for ( i_w = 0; i_w < wid_w; i_w++ ) { + c3_w waf_w = (baf_w >> 5); + c3_g raf_g = (baf_w & 31); + c3_w wat_w = (bat_w >> 5); + c3_g rat_g = (bat_w & 31); + c3_w hop_w; + + hop_w = (waf_w >= len_w) ? 0 : buf_w[waf_w]; + hop_w = (hop_w >> raf_g) & mek_w; + + dst_w[wat_w] ^= (hop_w << rat_g); + + baf_w += san_w; + bat_w += san_w; + } + } + else { + c3_g hut_g = (met_g - 5); + c3_w san_w = (1 << hut_g); + c3_w j_w; + + for ( i_w = 0; i_w < wid_w; i_w++ ) { + c3_w wuf_w = (fum_w + i_w) << hut_g; + c3_w wut_w = (tou_w + i_w) << hut_g; + + for ( j_w = 0; j_w < san_w; j_w++ ) { + dst_w[wut_w + j_w] ^= + ((wuf_w + j_w) >= len_w) + ? 0 + : buf_w[wuf_w + j_w]; + } + } + } +} + +/* _test_chop_smol(): test permuations of chop from bloq 0-4 +*/ +static c3_i +_test_chop_smol(c3_c* cap_c, c3_y val_y) +{ + c3_i ret_i = 1; + c3_g met_g; + c3_w fum_w, wid_w, tou_w; + c3_w len_w = 34; // (rsh [0 5] (mul 2 (mul 34 (bex 4)))) + c3_w src_w[len_w]; + c3_w a_w[len_w]; + c3_w b_w[len_w]; + + memset(src_w, val_y, len_w << 2); + + for ( met_g = 0; met_g < 5; met_g++ ) { + for ( fum_w = 0; fum_w <= len_w; fum_w++ ) { + for ( wid_w = 0; wid_w <= len_w; wid_w++ ) { + for ( tou_w = 0; tou_w <= len_w; tou_w++ ) { + memset(a_w, 0, len_w << 2); + memset(b_w, 0, len_w << 2); + u3r_chop_words(met_g, fum_w, wid_w, tou_w, a_w, len_w, src_w); + _test_chop_slow(met_g, fum_w, wid_w, tou_w, b_w, len_w, src_w); + + if ( 0 != memcmp(a_w, b_w, len_w << 2) ) { + c3_g sif_g = 5 - met_g; + c3_w mas_w = (1 << met_g) - 1; + c3_w out_w = tou_w >> sif_g; + c3_w max_w = out_w + !!(fum_w & mas_w) + + (wid_w >> sif_g) + !!(wid_w & mas_w); + + fprintf(stderr, "%s (0x%x): met_g=%u fum_w=%u wid_w=%u tou_w=%u\r\n", + cap_c, val_y, + met_g, fum_w, wid_w, tou_w); + + + fprintf(stderr, "%u-%u: ", out_w, max_w - 1); + for ( ; out_w < max_w; out_w++ ) { + fprintf(stderr, "[0x%x 0x%x] ", a_w[out_w], b_w[out_w]); + } + fprintf(stderr, "\r\n"); + } + } + } + } + } + + return ret_i; +} + +/* _test_chop_huge(): test permuations of chop from bloq 5+ +*/ +static c3_i +_test_chop_huge(c3_c* cap_c, c3_y val_y) +{ + c3_i ret_i = 1; + c3_g met_g; + c3_w fum_w, wid_w, tou_w; + c3_w len_w = 192; // (rsh [0 5] (mul 2 (mul 3 (bex 10)))) + c3_w src_w[len_w]; + c3_w a_w[len_w]; + c3_w b_w[len_w]; + + memset(src_w, val_y, len_w << 2); + + for ( met_g = 5; met_g <= 10; met_g++ ) { + for ( fum_w = 0; fum_w <= 3; fum_w++ ) { + for ( wid_w = 0; wid_w <= 2; wid_w++ ) { + for ( tou_w = 0; tou_w <= 1; tou_w++ ) { + memset(a_w, 0, len_w << 2); + memset(b_w, 0, len_w << 2); + u3r_chop_words(met_g, fum_w, wid_w, tou_w, a_w, len_w, src_w); + _test_chop_slow(met_g, fum_w, wid_w, tou_w, b_w, len_w, src_w); + + if ( 0 != memcmp(a_w, b_w, len_w << 2) ) { + c3_g sif_g = met_g - 5; + c3_w mas_w = (1 << met_g) - 1; + c3_w out_w = tou_w << sif_g; + c3_w max_w = out_w + !!(fum_w & mas_w) + + (wid_w << sif_g) + !!(wid_w & mas_w); + + fprintf(stderr, "%s (0x%x): met_g=%u fum_w=%u wid_w=%u tou_w=%u\r\n", + cap_c, val_y, + met_g, fum_w, wid_w, tou_w); + + + fprintf(stderr, "%u-%u: ", out_w, max_w - 1); + for ( ; out_w < max_w; out_w++ ) { + fprintf(stderr, "[0x%x 0x%x] ", a_w[out_w], b_w[out_w]); + } + fprintf(stderr, "\r\n"); + } + } + } + } + } + + return ret_i; +} + +/* _test_u3r_chop(): bit slice XOR +*/ +static c3_i +_test_chop() +{ + return _test_u3r_chop() + & _test_chop_smol("chop smol zeros", 0x0) + & _test_chop_smol("chop smol ones", 0xff) + & _test_chop_smol("chop smol alt 1", 0xaa) + & _test_chop_smol("chop smol alt 2", 0x55) + & _test_chop_huge("chop huge zeros", 0x0) + & _test_chop_huge("chop huge ones", 0xff) + & _test_chop_huge("chop huge alt 1", 0xaa) + & _test_chop_huge("chop huge alt 2", 0x55); } /* _util_rand_string(): dynamically allocated len_w random string @@ -1265,256 +1597,6 @@ _test_u3r_at() if (bignum != ret) { printf("*** u3r_at \n"); } } -/* _test_u3r_chop: "extract bit slices from atom" -*/ -static void -_test_u3r_chop() -{ - c3_w dst_w = 0; - - // read 1 bit bloq - { - // read 1 bit from pos=0 (far right) - u3_atom src = 0b11011; - - c3_g bloqsize_g = 0; - - - dst_w = 0; - u3r_chop(bloqsize_g, /// bloq size - 0, // start index - 1, // count of bloqs - 0, // end index - & dst_w, // where bytes go to - src); // where bytes come from - - if (0x1 != dst_w) { printf("*** test_u3r_chop \n"); } - - - // read 1 bit from pos=1 - dst_w = 0; - u3r_chop(bloqsize_g, /// bloq size - 1, // start index - 1, // count of bloqs - 0, // end index - & dst_w, // where bytes go to - src); // where bytes come from - - if (0x1 != dst_w) { printf("*** test_u3r_chop 2\n"); } - - // read 1 bit from pos=2 - dst_w = 0; - u3r_chop(bloqsize_g, /// bloq size - 2, // start index - 1, // count of bloqs - 0, // end index - & dst_w, // where bytes go to - src); // where bytes come from - - if (0x0 != dst_w) { printf("*** test_u3r_chop 3\n"); } - - // read 4 x 1 bit bloq from pos=0 - dst_w = 0; - u3r_chop(bloqsize_g, /// bloq size - 0, // start index - 4, // count of bloqs - 0, // end index - & dst_w, // where bytes go to - src); // where bytes come from - - if (0b1011 != dst_w) { printf("*** test_u3r_chop 4\n"); } - - - // read 1 x 1 bit bloq from pos=0 into offset 1 - dst_w = 0; - u3r_chop(bloqsize_g, /// bloq size - 0, // start index - 4, // count of bloqs - 1, // end index - & dst_w, // where bytes go to - src); // where bytes come from - - if (0b10110 != dst_w) { printf("*** test_u3r_chop 5\n"); } - - - - } - - // read 2 bit bloq - { - u3_atom src = 0b11011; - - c3_g bloqsize_g = 1; - - // read 2 bit from pos=0 (far right) - - dst_w = 0; - u3r_chop(bloqsize_g, /// bloq size - 0, // start index - 1, // count of bloqs - 0, // end index - & dst_w, // where bytes go to - src); // where bytes come from - - if (0b11 != dst_w) { printf("*** test_u3r_chop 2.1\n"); } - - - // read 2 bit from pos=1 (1 bloq over ) - dst_w = 0; - u3r_chop(bloqsize_g, /// bloq size - 1, // start index - 1, // count of bloqs - 0, // end index - & dst_w, // where bytes go to - src); // where bytes come from - - if (0b10 != dst_w) { printf("*** test_u3r_chop 2.2\n"); } - - // read 2 bit from pos=2 (2 bloq over) - dst_w = 0; - u3r_chop(bloqsize_g, /// bloq size - 2, // start index - 1, // count of bloqs - 0, // end index - & dst_w, // where bytes go to - src); // where bytes come from - - if (0b01 != dst_w) { printf("*** test_u3r_chop 2.3\n"); } - - } - - // read 8 bit bloq - { - u3_atom src = 0b11011; - - c3_g bloqsize_g = 3; // 2^3 = 8 bits - - // pos=0 (far right) - - dst_w = 0; - u3r_chop(bloqsize_g, /// bloq size - 0, // start index - 1, // count of bloqs - 0, // end index - & dst_w, // where bytes go to - src); // where bytes come from - - if (0b11011 != dst_w) { printf("*** test_u3r_chop 8.1\n"); } - } - - // read 1,8,16 bit bloqs from an indirect atom - { - // build an indirect noun 'src' - - c3_c* input_c = "abcdefghij"; - u3_noun src = u3i_bytes(10, (c3_y*)input_c); - - - c3_g bloqsize_g = 0; // 2^0 = 1 bit - - // 1 x 1 bit pos=0 (far right) - dst_w = 0; - u3r_chop(bloqsize_g, /// bloq size - 0, // start index - 1, // count of bloqs - 0, // end index - & dst_w, // where bytes go to - src); // where bytes come from - - if (0b1 != dst_w) { - printf("*** test_u3r_chop indirect.1\n"); - } - - // 8 x 1 bit pos=0 (far right) - dst_w = 0; - u3r_chop(bloqsize_g, /// bloq size - 0, // start index - 8, // count of bloqs - 0, // end index - & dst_w, // where bytes go to - src); // where bytes come from - - if (0b1100001 != dst_w) { - printf("*** test_u3r_chop indirect.2\n"); - } - - // 1 x 1 byte = 8 bit, pos=0 (far right) - bloqsize_g = 3; // 2^3 = 1 byte - dst_w = 0; - u3r_chop(bloqsize_g, /// bloq size - 0, // start index - 1, // count of bloqs - 0, // end index - & dst_w, // where bytes go to - src); // where bytes come from - - if (0b1100001 != dst_w) { - printf("*** test_u3r_chop indirect.3\n"); - } - - // 1 x 16 bit bloq, pos = 0 - bloqsize_g = 4; // 2^4 = 2 bytes - - dst_w = 0; - u3r_chop(bloqsize_g, /// bloq size - 0, // start index - 1, // count of bloqs - 0, // end index - & dst_w, // where bytes go to - src); // where bytes come from - - if (0b0110001001100001 != dst_w) { - printf("*** test_u3r_chop indirect.4\n"); - } - } - - // read lots of bits from a direct noun which holds 64 bits of data - // makes sure that we handle top 32 / bottom 32 correctly - { - // build an indirect noun 'src' - - c3_c input_c[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; - u3_noun src = u3i_bytes(8, (c3_y*)input_c); - - c3_g bloqsize_g = 0; // 2^0 = 1 bit - - c3_w dst_w[2]; - memset(dst_w, 0, 2 * sizeof(c3_w)); - - u3r_chop(bloqsize_g, /// bloq size - 0, // start index - 63, // count of bloqs - 0, // offset on out index - dst_w, // where bytes go to - src); // where bytes come from - - } - - // as above (read lots of bits from a direct noun which holds 64 bits of data - // makes sure that we handle top 32 / bottom 32 correctly) - // but with a bit more nuance - { - // least significant most - c3_c input_c[8] = { 0x0, 0x0, 0x0, 0xaa, 0xff, 0x0, 0x0, 0x0 }; - u3_noun src = u3i_bytes(8, (c3_y*)input_c); - - c3_g bloqsize_g = 0; // 2^0 = 1 bit - - c3_w dst_w = 0; - - u3r_chop(bloqsize_g, /// bloq size - 24, // start index - 16, // count of bloqs - 0, // offset on out index - & dst_w, // where bytes go to - src); // where bytes come from - - if (0b1111111110101010 != dst_w) { - printf("*** test_u3r_chop indirect. 6\n"); - } - } -} - // XX disabled, static functions // #if 0 @@ -1652,31 +1734,17 @@ _test_nvm_stack() #endif } -/* _test_lily(): test small noun parsing. -*/ -static void -_test_lily() +static c3_i +_test_noun(void) { - c3_l lit_l; - c3_w big_w[] = {0, 0, 1}; - u3_noun big = u3i_words(3, big_w); - u3_noun cod = u3dc("scot", c3__uv, big); + c3_i ret_i = 1; - if ( c3y == u3v_lily(c3__uv, cod, &lit_l) ) { - printf("*** fail _test_lily-1\n"); - exit(1); - } - cod = u3dc("scot", c3__ud, 0x7fffffff); - if ( (c3n == u3v_lily(c3__ud, cod, &lit_l)) || - (0x7fffffff != lit_l) ) { - printf("*** fail _test_lily-2a\n"); - exit(1); - } - cod = u3dc("scot", c3__ux, u3i_word(0x80000000)); - if ( c3y == u3v_lily(c3__ux, cod, &lit_l) ) { - printf("*** fail _test_lily-2b\n"); - exit(1); + if ( !_test_chop() ) { + fprintf(stderr, "test noun: chop failed\r\n"); + ret_i = 0; } + + return ret_i; } /* main(): run all test cases. @@ -1686,9 +1754,20 @@ main(int argc, char* argv[]) { _setup(); + if ( !_test_noun() ) { + fprintf(stderr, "test noun: failed\r\n"); + exit(1); + } + + // GC + // + u3m_grab(u3_none); + + // XX the following tests leak memory + // fix and move to _test_noun() + // _test_noun_bits_set(); _test_noun_bits_read(); - _test_u3r_chop(); _test_imprison(); _test_imprison_complex(); _test_sing(); @@ -1698,7 +1777,6 @@ main(int argc, char* argv[]) _test_cells_complex(); _test_u3r_at(); _test_nvm_stack(); - _test_lily(); fprintf(stderr, "test_noun: ok\n"); diff --git a/pkg/urbit/ur/bitstream.c b/pkg/urbit/ur/bitstream.c index dfc42393b..5d69e3f9e 100644 --- a/pkg/urbit/ur/bitstream.c +++ b/pkg/urbit/ur/bitstream.c @@ -411,25 +411,21 @@ ur_bsr_bytes_any(ur_bsr_t *bsr, uint64_t len, uint8_t *out) // else { uint8_t rest = 8 - off; - uint8_t mask = (1 << off) - 1; - uint8_t byt, l, m = *b >> off; uint64_t last = left - 1; + uint64_t max = ur_min(last, len_byt); + uint8_t m, l; // loop over all the bytes we need (or all that remain) // - // [l] holds [off] bits - // [m] holds [rest] bits - // { - uint64_t max = ur_min(last, len_byt); uint64_t i; for ( i = 0; i < max; i++ ) { - byt = *++b; - l = byt & mask; - out[i] = m ^ (l << rest); - m = byt >> off; + out[i] = (b[i] >> off) ^ (b[i + 1] << rest); } + + b += max; + m = *b >> off; } // we're reading into or beyond the last byte [bsr] @@ -441,13 +437,13 @@ ur_bsr_bytes_any(ur_bsr_t *bsr, uint64_t len, uint8_t *out) uint8_t bits = len - (last << 3); if ( bits < rest ) { - out[last] = m & ((1 << bits) - 1); + out[max] = m & ((1 << len_bit) - 1); bsr->bytes = b; left = 1; off += len_bit; } else { - out[last] = m; + out[max] = m; bsr->bytes = 0; left = 0; off = 0; @@ -465,11 +461,11 @@ ur_bsr_bytes_any(ur_bsr_t *bsr, uint64_t len, uint8_t *out) if ( len_bit ) { if ( len_bit <= rest ) { - out[len_byt] = m & ((1 << len_bit) - 1); + out[max] = m & ((1 << len_bit) - 1); } else { l = *++b & ((1 << off) - 1); - out[len_byt] = m ^ (l << rest); + out[max] = (m ^ (l << rest)) & ((1 << len_bit) - 1); } } } @@ -1035,67 +1031,60 @@ ur_bsw64(ur_bsw_t *bsw, uint8_t len, uint64_t val) } static inline void -_bsw_bytes_unsafe(ur_bsw_t *bsw, uint64_t len, uint8_t *byt) +_bsw_bytes_unsafe(ur_bsw_t *bsw, const uint64_t len, const uint8_t* src) { - uint64_t len_byt = len >> 3; - uint8_t len_bit = ur_mask_3(len); - uint64_t fill = bsw->fill; - uint8_t off = bsw->off; + uint64_t fill = bsw->fill; + uint8_t off = bsw->off; + uint8_t *dst = bsw->bytes + fill; if ( !off ) { - memcpy(bsw->bytes + fill, byt, len_byt); - fill += len_byt; - off = len_bit; + const uint64_t len_byt = len >> 3; + const uint8_t len_bit = ur_mask_3(len); - if ( off ) { - bsw->bytes[fill] = byt[len_byt] & ((1 << off) - 1); + memcpy(dst, src, len_byt); + bsw->fill = fill + len_byt; + + if ( len_bit ) { + dst[len_byt] = src[len_byt] & ((1 << len_bit) - 1); + bsw->off = len_bit; } } - // the least-significant bits of the input become the - // most-significant bits of a byte in the output stream, and vice-versa - // - else { - uint8_t rest = 8 - off; - uint8_t mask = (1 << rest) - 1; - uint8_t l, m = bsw->bytes[fill]; - uint64_t i; + else { + const uint8_t rest = 8 - off; - for ( i = 0; i < len_byt; i++ ) { - l = byt[i] & mask; - bsw->bytes[fill++] = m ^ (l << off); - m = byt[i] >> rest; - } + if ( rest >= len ) { + uint16_t ful = off + len; - // no trailing bits; we need only write the rest of the last byte. - // - // NB: while semantically equivalent to the subsequent block, - // this case must be separate to avoid reading off the end of [byt] - // - if ( !len_bit ) { - bsw->bytes[fill] = m; + *dst ^= (*src & ((1 << len) - 1)) << off; + + if ( ful >> 3 ) { + bsw->fill = fill + 1; + } + + bsw->off = ur_mask_3(ful); } - // trailing bits fit into the current output byte. - // - else if ( len_bit < rest ) { - l = byt[len_byt] & ((1 << len_bit) - 1); - bsw->bytes[fill] = m ^ (l << off); - off += len_bit; - } - // trailing bits extend into the next output byte. - // else { - l = byt[len_byt] & mask; - bsw->bytes[fill++] = m ^ (l << off); + const uint64_t nel = len - rest; + const uint64_t len_byt = nel >> 3; + const uint8_t len_bit = ur_mask_3(nel); - m = byt[len_byt] >> rest; + *dst++ ^= *src << off; - off = len_bit - rest; - bsw->bytes[fill] = m & ((1 << off) - 1); + for ( uint64_t i = 0; i < len_byt; i++ ) { + dst[i] = (src[i] >> rest) ^ (src[i + 1] << off); + } + + { + uint8_t tal = (src[len_byt] >> rest) + ^ (( off > len_bit ) ? 0 : (src[len_byt + 1] << off)); + dst[len_byt] = tal & ((1 << len_bit) - 1); + } + + bsw->fill = fill + len_byt + 1; + bsw->off = len_bit; } } - bsw->off = off; - bsw->fill = fill; bsw->bits += len; } diff --git a/pkg/urbit/vere/disk.c b/pkg/urbit/vere/disk.c index 730d5da82..eb4a27533 100644 --- a/pkg/urbit/vere/disk.c +++ b/pkg/urbit/vere/disk.c @@ -617,7 +617,15 @@ u3_disk_acquire(c3_c* pax_c) else if (pid_w != getpid()) { c3_w i_w; - if ( -1 != kill(pid_w, SIGTERM) ) { + int ret = kill(pid_w, SIGTERM); + + if ( -1 == ret && errno == EPERM ) { + u3l_log("disk: permission denied when trying to kill process %d!\n", pid_w); + kill(getpid(), SIGTERM); + sleep(1); c3_assert(0); + } + + if ( -1 != ret ) { u3l_log("disk: stopping process %d, live in %s...\n", pid_w, pax_c); diff --git a/pkg/urbit/vere/king.c b/pkg/urbit/vere/king.c index 142afddb5..44a8cd502 100644 --- a/pkg/urbit/vere/king.c +++ b/pkg/urbit/vere/king.c @@ -577,7 +577,7 @@ _boothack_doom(void) if ( u3_nul == whu ) { u3l_log("boot: malformed -F ship %s\r\n", u3_Host.ops_u.fak_c); - exit(1); + u3_king_bail(); } bot = u3nc(c3__fake, u3k(u3t(whu))); diff --git a/pkg/urbit/vere/lord.c b/pkg/urbit/vere/lord.c index cc7af14f6..205190848 100644 --- a/pkg/urbit/vere/lord.c +++ b/pkg/urbit/vere/lord.c @@ -1157,11 +1157,12 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u) // spawn new process and connect to it // { - c3_c* arg_c[8]; + c3_c* arg_c[10]; c3_c key_c[256]; c3_c wag_c[11]; c3_c hap_c[11]; c3_c cev_c[11]; + c3_c lom_c[11]; c3_i err_i; sprintf(key_c, "%" PRIx64 ":%" PRIx64 ":%" PRIx64 ":%" PRIx64 "", @@ -1174,30 +1175,34 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u) sprintf(hap_c, "%u", u3_Host.ops_u.hap_w); + sprintf(lom_c, "%u", u3_Host.ops_u.lom_y); + arg_c[0] = god_u->bin_c; // executable arg_c[1] = "serf"; // protocol arg_c[2] = god_u->pax_c; // path to checkpoint directory arg_c[3] = key_c; // disk key arg_c[4] = wag_c; // runtime config arg_c[5] = hap_c; // hash table size + arg_c[6] = lom_c; // loom bex if ( u3_Host.ops_u.roc_c ) { // XX validate // - arg_c[6] = u3_Host.ops_u.roc_c; + arg_c[7] = u3_Host.ops_u.roc_c; } else { - arg_c[6] = "0"; + arg_c[7] = "0"; } #ifdef U3_OS_mingw sprintf(cev_c, "%" PRIu64, u3_Host.cev_u); - arg_c[7] = cev_c; - arg_c[8] = 0; + arg_c[8] = cev_c; #else - arg_c[7] = 0; + arg_c[8] = 0; #endif + arg_c[9] = 0; + uv_pipe_init(u3L, &god_u->inn_u.pyp_u, 0); uv_timer_init(u3L, &god_u->out_u.tim_u); uv_pipe_init(u3L, &god_u->out_u.pyp_u, 0); diff --git a/pkg/urbit/vere/pier.c b/pkg/urbit/vere/pier.c index 0930f21a4..9f1fd00e0 100644 --- a/pkg/urbit/vere/pier.c +++ b/pkg/urbit/vere/pier.c @@ -492,8 +492,12 @@ _pier_on_scry_done(void* ptr_v, u3_noun nun) { u3_atom puf = u3i_string(u3_Host.ops_u.puf_c); if ( c3y == u3r_sing(c3__jam, puf) ) { - out = u3qe_jam(res); + c3_d len_d; + c3_y* byt_y; + u3s_jam_xeno(res, &len_d, &byt_y); + out = u3i_bytes(len_d, byt_y); ext_c = "jam"; + free(byt_y); } else if ( c3y == u3a_is_atom(res) ) { out = u3dc("scot", u3k(puf), u3k(res)); @@ -669,8 +673,8 @@ _pier_wyrd_fail(u3_pier* pir_u, u3_ovum* egg_u, u3_noun lud) // XX organizing version constants // #define VERE_NAME "vere" -#define VERE_ZUSE 418 -#define VERE_LULL 329 +#define VERE_ZUSE 417 +#define VERE_LULL 328 /* _pier_wyrd_aver(): check for %wend effect and version downgrade. RETAIN */ diff --git a/pkg/urbit/version b/pkg/urbit/version index 578c71bd5..07fe6f6c9 100644 --- a/pkg/urbit/version +++ b/pkg/urbit/version @@ -1 +1 @@ -1.10 \ No newline at end of file +1.15 \ No newline at end of file diff --git a/pkg/webterm/sys.kelvin b/pkg/webterm/sys.kelvin index e77a3de08..b7bcb9ecd 100644 --- a/pkg/webterm/sys.kelvin +++ b/pkg/webterm/sys.kelvin @@ -1 +1 @@ -[%zuse 418] +[%zuse 417]