Merge branch 'philip/inline-thread' into philip/agent-clay-wip

This commit is contained in:
Philip Monk 2022-09-01 19:03:17 -08:00
commit 093f0ae9de
81 changed files with 2595 additions and 1056 deletions

View File

@ -232,9 +232,7 @@ jobs:
after:
runs-on: ubuntu-latest
needs: [urbit, mingw]
# XX disabled due to missing storage.objects.delete access
if: false
# if: inputs.upload
if: inputs.upload
steps:
- uses: google-github-actions/setup-gcloud@v0.2.0
with:

View File

@ -1,10 +1,10 @@
.PHONY: build build-all install cross release test pills ropsten-pills clean
build:
nix-build -A urbit -A herb --no-out-link
nix-build -A urbit --no-out-link
install:
nix-env -f . -iA urbit -iA herb
nix-env -f . -iA urbit
release:
sh/release

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fc6ca562b15bec33467dd9ca8bc24d7cde4108d03f3695abb417781dd6769453
size 22891931
oid sha256:b604b45df0496baf94ac38145c3fc8d4fa9429ae02b49b33a7af4e32ad770db4
size 5896517

18
nix/sources-openssl.json Normal file
View File

@ -0,0 +1,18 @@
{
"openssl": {
"branch": "1_1_1n",
"homepage": "https://www.openssl.org/",
"pmnsh": {
"include": "build/include",
"lib": "build",
"prepare": "./config --prefix=`mkdir -p build && readlink -f ./build` --libdir=. no-shared no-tests",
"make": "install_dev"
},
"owner": "openssl",
"repo": "openssl",
"rev": "OpenSSL_1_1_1n",
"type": "tarball",
"url": "https://github.com/openssl/openssl/archive/refs/tags/OpenSSL_1_1_1n.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/refs/tags/<rev>.tar.gz"
}
}

View File

@ -4,6 +4,11 @@
"description": "A command line tool and library for transferring data with URL syntax",
"homepage": "http://curl.se/",
"pmnsh": {
"compat": {
"openbsd": {
"prepare": "autoreconf -vfi && ./configure --disable-shared --disable-ldap --disable-rtsp --without-brotli --without-libidn2 --without-libpsl --without-nghttp2 --with-openssl=`readlink -f ../openssl/build`"
}
},
"include": "include",
"lib": "lib/.libs",
"prepare": "autoreconf -vfi && ./configure --disable-shared --disable-ldap --disable-rtsp --without-brotli --without-libidn2 --without-libpsl --without-nghttp2 --with-openssl",
@ -76,6 +81,13 @@
},
"urcrypt": {
"pmnsh": {
"compat": {
"openbsd": {
"make": "install prefix=`readlink -f .` exec_prefix=`readlink -f .`",
"include": "include",
"lib": "lib"
}
},
"prepare": "./autogen.sh && ./configure --disable-shared PKG_CONFIG_PATH=../secp256k1 CFLAGS=\"-I../secp256k1/include -I../libaes_siv\" LDFLAGS=-L../libaes_siv",
"make": "install"
}

View File

@ -8,6 +8,9 @@
"compat": {
"mingw": {
"prepare": "cmake -G\"MSYS Makefiles\" -DCMAKE_INSTALL_PREFIX=. ."
},
"openbsd": {
"prepare": "cmake -DOPENSSL_ROOT_DIR=`readlink -f ../openssl/build` ."
}
},
"include": "include",
@ -35,6 +38,10 @@
"mingw": {
"make": "aes_siv_static",
"prepare": "cmake -G\"MSYS Makefiles\" -DDISABLE_DOCS:BOOL=ON ."
},
"openbsd": {
"make": "aes_siv_static",
"prepare": "cmake -DDISABLE_DOCS:BOOL=ON -DOPENSSL_ROOT_DIR=`readlink -f ../openssl/build` ."
}
}
},
@ -98,6 +105,10 @@
"mingw": {
"lib": "build/Win64-MinGW-w64",
"make": "-C build/Win64-MinGW-w64 libsoftfloat3.a"
},
"openbsd": {
"lib": "build/template-FAST_INT64",
"make": "-C build/template-FAST_INT64 libsoftfloat3.a"
}
},
"include": "source/include"

View File

@ -249,6 +249,7 @@
spo.state sponsors.snap.poke
url.state 'http://eth-mainnet.urbit.org:8545'
sap.state snap.poke
logs.state ~
==
$(poke [%kick ~])
::
@ -268,12 +269,14 @@
|((~(has in dudes) [%eth-watcher &]) (~(has in dudes) [%eth-watcher |]))
:_ this
=/ cards=(list card)
:- :: %jael will re-subscribe to get all azimuth diffs
::
(listen-to-azimuth ~ [%| dap.bowl])
:: we poke eth-watcher to retrieve logs from the latest we have
?: installed
~
:: reinstall %base desk
::
%*(start do number.id.sap.state last-block)
=+ spo=(sein:title [our now our]:bowl)
~& >> re-installing-base-from+spo
=/ fresh=[desk ship desk] [%base spo %kids]
[%pass /fresh %agent [our.bowl %hood] %poke kiln-install+!>(fresh)]~
=? cards !running
:: restart %eth-watcher
::
@ -281,20 +284,19 @@
=/ rein=[desk rein] [%base [%eth-watcher %&] ~ ~]
:_ cards
[%pass /rein %agent [our.bowl %hood] %poke kiln-rein+!>(rein)]
=? cards !installed
:: reinstall %base desk
=. cards
:: we poke eth-watcher to retrieve logs from the latest we have
::
=+ spo=(sein:title [our now our]:bowl)
~& >> re-installing-base-from+spo
=/ fresh=[desk ship desk] [%base spo %kids]
:_ cards
[%pass /fresh %agent [our.bowl %hood] %poke kiln-install+!>(fresh)]
:: resubscribe if we somehow get unsubscribed from eth-watcher
::
?: (~(has by wex.bowl) [/eth-watcher our.bowl %eth-watcher])
cards
:: ~& >> %resubscribing-to-eth-watcher
[(subscribe-to-eth-watcher bowl) cards]
(weld %*(start do number.id.sap.state last-block) cards)
=? cards !(~(has by wex.bowl) [/eth-watcher our.bowl %eth-watcher])
:: resubscribe if we somehow get unsubscribed from eth-watcher
::
[(subscribe-to-eth-watcher bowl) cards]
=. cards
:: %jael will re-subscribe to get all azimuth diffs
::
[(listen-to-azimuth ~ [%| dap.bowl]) cards]
(flop cards)
::
%watch
=: nas.state ?:(?=(%default net.poke) nas.sap.state *^state:naive)
@ -340,13 +342,14 @@
^- (unit (unit cage))
|^
?+ path (on-peek:def path)
[%x %logs ~] ``noun+!>(logs.state)
[%x %nas ~] ``noun+!>(nas.state)
[%x %dns ~] ``noun+!>(dns.nas.state)
[%x %own ~] ``noun+!>(own.state)
[%x %spo ~] ``noun+!>(spo.state)
[%x %refresh ~] ``atom+!>(refresh.state)
[%x %point @ ~] ``noun+(point i.t.t.path)
[%x %logs ~] ``noun+!>(logs.state)
[%x %nas ~] ``noun+!>(nas.state)
[%x %dns ~] ``noun+!>(dns.nas.state)
[%x %own ~] ``noun+!>(own.state)
[%x %spo ~] ``noun+!>(spo.state)
[%x %refresh ~] ``atom+!>(refresh.state)
[%x %point @ ~] ``noun+(point i.t.t.path)
[%x %last-snap ~] ``noun+!>(sap.state)
==
::
++ point

View File

@ -532,10 +532,11 @@
?: ?=([%show %3] -.mad)
(dy-rash %tan (dy-show-source q.mad) ~)
?: ?=(%brev -.mad)
?: ?=(?(%eny %now %our) p.mad)
(dy-rash %tan (cat 3 p.mad ' is immutable') ~)
=. var (~(del by var) p.mad)
=< dy-amok
?+ p.mad .
$?(%eny %now %our) !!
%lib .(lib ~)
%sur .(sur ~)
%dir .(dir [[our.hid %base ud+0] /])
@ -543,13 +544,12 @@
=+ cay=(~(got by rez) p.q.mad)
?- -.p.mad
%verb
?: ?=(?(%eny %now %our) p.p.mad)
(dy-rash %tan (cat 3 p.p.mad ' is immutable') ~)
=. var (~(put by var) p.p.mad cay)
~| bad-set+[p.p.mad p.q.cay]
=< dy-amok
?+ p.p.mad .
%eny ~|(%entropy-is-eternal !!)
%now ~|(%time-is-immutable !!)
%our ~|(%self-is-immutable !!)
%lib
%_ .
lib
@ -568,6 +568,8 @@
?: ?=([@ ~] 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))]
@ -735,9 +737,9 @@
^+ +>+>
=^ dat say (~(transceive sole say) cal)
?: |(?=(^ per) ?=(^ pux) ?=(~ pro))
~& %dy-edit-busy
=^ lic say (~(transmit sole say) dat)
(dy-diff %mor [%det lic] [%bel ~] ~)
=/ tip=@t 'dojo: busy (press backspace to abort)'
(dy-diff %mor [%det lic] [%bel ~] [%tan [tip ~]] ~)
=> .(per `dat)
=/ res (mule |.((slam u.pro !>((tufa buf.say)))))
?: ?=(%| -.res)

View File

@ -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-thread 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
@ -356,16 +378,18 @@
|= [=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-thread yarn p.res)
::
++ begin-thread
|= [=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

View File

@ -0,0 +1,46 @@
:: print [len] %ames flows, sorted by number-per-ship
::
:- %say
|= [[now=@da eny=@uvJ bec=beak] arg=$@(~ [len=@ ~]) ~]
:- %noun
::
=; flows
^- (list [=ship open=[out-open=@ out-closing=@ in=@ nax=@] corked=@])
=/ len ?^(arg len.arg 50)
(scag len (sort flows |=([[@ [a=@ud *] *] @ [b=@ud *] *] (gth a b))))
::
=/ peers-map
.^ (map ship ?(%alien %known))
%ax /(scot %p p.bec)//(scot %da now)/peers
==
=/ peers=(list ship)
%+ murn ~(tap by peers-map)
|= [=ship val=?(%alien %known)]
?: =(ship p.bec)
~ :: this is weird, but we saw it
?- val
%alien ~
%known (some ship)
==
::
^- (list [=ship open=[out-open=@ out-closing=@ in=@ nax=@] corked=@])
%+ turn peers
|= =ship
=+ .^ =ship-state:ames
%ax /(scot %p p.bec)//(scot %da now)/peers/(scot %p ship)
==
=/ =peer-state:ames ?>(?=(%known -.ship-state) +.ship-state)
=/ corked ~(wyt in corked.peer-state)
=- [ship - corked]
::
=+ %+ roll ~(tap in ~(key by snd.peer-state))
|= [b=bone [out=(list bone) in=(list bone) nax=(list bone)]]
=/ m (mod b 4)
?+ m ~|([%odd-bone b] !!)
%0 [[b out] in nax]
%1 [out [b in] nax]
%3 [out in [b nax]]
==
=/ [out-closing=(list bone) out-open=(list bone)]
(skid out ~(has ^in closing.peer-state))
[(lent out-open) (lent out-closing) (lent in) (lent nax)]

View File

@ -0,0 +1,20 @@
:: print [len] %ames message-pump timers, sorted by number-per-ship
::
:- %say
|= [[now=@da eny=@uvJ bec=beak] arg=$@(~ [len=@ ~]) ~]
:- %noun
::
=; who
^- (list [@ta @ud])
=/ len ?^(arg len.arg 50)
(scag len (sort ~(tap by who) |=([[@ a=@ud] @ b=@ud] (gth a b))))
::
=| who=(map @ta @ud)
=/ tim .^((list (pair @da duct)) bx+/(scot %p p.bec)//(scot %da now)/debug/timers)
|- ^+ who
?~ tim who
?. &(?=(^ q.i.tim) ?=([%ames %pump ^] i.q.i.tim))
$(tim t.tim)
=* her i.t.t.i.q.i.tim
=/ i (~(gut by who) her 0)
$(tim t.tim, who (~(put by who) her +(i)))

View File

@ -1,5 +0,0 @@
:: Kick azimuth
::
:- %say
|= *
[%azimuth-poke %kick ~]

View File

@ -0,0 +1,10 @@
:: +gall-nonces: print %gall agent subscription nonces, highest-last
::
:- %say
|= [[now=@da eny=@uvJ bec=beak] ~ ~]
:- %noun
^- (list [dude:gall @ud])
%+ sort
%~ tap by
.^((map dude:gall @ud) %gf /(scot %p p.bec)//(scot %da now))
|=([[* a=@ud] [* b=@ud]] (lth a b))

View File

@ -0,0 +1,8 @@
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
~
[dude=_`dude:gall`%$ ship=_`@p`(bex 128)]
==
=/ darg=(unit dude:gall) ?:(=(%$ dude) ~ `dude)
=/ sarg=(unit ^ship) ?:(=((bex 128) ship) ~ `ship)
[%helm-doff darg sarg]

View File

@ -0,0 +1,8 @@
:: Helm: Set Gall Verbosity by Agent
::
/? 310
::
:- %say
|= [^ dudes=(list dude:gall) ~]
:- %helm-gall-sift
dudes

View File

@ -0,0 +1,11 @@
:: Helm: Adjust Gall verbosity
::
:: List of diagnostic flags is in verb:gall in zuse.hoon, documented in
:: gall.hoon
::
/? 310
::
:- %say
|= [^ veb=(list verb:gall) ~]
:- %helm-gall-verb
veb

View File

@ -9,7 +9,9 @@
:- %kiln-rein
:- desk
%+ roll arg
=| =rein:hood
=/ =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))

View File

@ -77,7 +77,8 @@
::
++ de-gill :: gill from wire
|= way=wire ^- gill:gall
?>(?=([@ @ ~] way) [(slav %p i.way) i.t.way])
~| way
?>(?=([@ @ *] way) [(slav %p i.way) i.t.way])
--
:: TODO: remove .ost
::

View File

@ -230,6 +230,14 @@
|= veb=(list verb:ames) =< abet
(emit %pass /helm %arvo %a %spew veb)
::
++ poke-gall-sift
|= dudes=(list dude:gall) =< abet
(emit %pass /helm %arvo %g %sift dudes)
::
++ poke-gall-verb
|= veb=(list verb:gall) =< abet
(emit %pass /helm %arvo %g %spew veb)
::
++ poke-ames-wake
|= ~ =< abet
(emit %pass /helm %arvo %a %stir '')
@ -252,6 +260,11 @@
=< abet
(emit %pass /helm/cors/reject %arvo %e %reject-origin origin)
::
++ poke-doff
|= [dude=(unit dude:gall) ship=(unit ship)]
=< abet
(emit %pass /helm/doff %arvo %g %doff dude ship)
::
++ poke
|= [=mark =vase]
?> ?| ?=(%helm-hi mark)
@ -269,6 +282,9 @@
%helm-code =;(f (f !<(_+<.f vase)) poke-code)
%helm-cors-approve =;(f (f !<(_+<.f vase)) poke-cors-approve)
%helm-cors-reject =;(f (f !<(_+<.f vase)) poke-cors-reject)
%helm-doff =;(f (f !<(_+<.f vase)) poke-doff)
%helm-gall-sift =;(f (f !<(_+<.f vase)) poke-gall-sift)
%helm-gall-verb =;(f (f !<(_+<.f vase)) poke-gall-verb)
%helm-hi =;(f (f !<(_+<.f vase)) poke-hi)
%helm-knob =;(f (f !<(_+<.f vase)) poke-knob)
%helm-pans =;(f (f !<(_+<.f vase)) poke-pans)

View File

@ -0,0 +1,12 @@
/- *aquarium
|_ af=aqua-effect
++ grad %noun
++ grow
|%
++ noun af
--
++ grab
|%
++ noun aqua-effect
--
--

View File

@ -8,5 +8,14 @@
++ grab
|%
+$ noun [ship binding]
++ json
=, dejs:format
|= jon=json
%. jon
%- ot
:~ [%ship |=(j=json ?>(?=([%s *] j) (rash +.j fed:ag)))]
[%address |=(j=json ?>(?=([%s *] j) [%if (rash +.j ip4:eyre)]))]
[%turf (ar so)]
==
--
--

View File

@ -0,0 +1,16 @@
/- *dns
|_ r=request
++ grad %noun
++ grow
|%
++ json
%- pairs:enjs:format
:~ ['ship' (ship:enjs:format ship.r)]
['address' s+(rsh 3 (scot %if +.address.r))]
==
--
++ grab
|%
++ noun request
--
--

View File

@ -1,6 +1,6 @@
:: /sys/lull
:: %lull: arvo structures
::
!:
=> ..part
|%
++ lull %329
@ -351,6 +351,7 @@
:: %hear: packet from unix
:: %heed: track peer's responsiveness; gives %clog if slow
:: %jilt: stop tracking peer's responsiveness
:: %cork: request to delete message flow
:: %plea: request to send message
::
:: System and Lifecycle Tasks
@ -367,6 +368,7 @@
$% [%hear =lane =blob]
[%heed =ship]
[%jilt =ship]
[%cork =ship]
$>(%plea vane-task)
::
$>(%born vane-task)
@ -511,6 +513,9 @@
:: entry and emit a nack to the local vane that asked us to send
:: the message.
:: heeds: listeners for %clog notifications
:: closing: bones closed on the sender side
:: corked: bones closed on both sender and receiver
:: krocs: bones that need to be sent again to the publisher
::
+$ peer-state
$: $: =symmetric-key
@ -526,6 +531,9 @@
rcv=(map bone message-sink-state)
nax=(set [=bone =message-num])
heeds=(set duct)
closing=(set bone)
corked=(set bone)
krocs=(set bone)
==
:: $qos: quality of service; how is our connection to a peer doing?
::
@ -1744,15 +1752,18 @@
[%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
$>(%init vane-task) :: set owner
$>(%trim vane-task) :: trim state
$>(%vega vane-task) :: report upgrade
$>(%plea vane-task) :: network request
[%spew veb=(list verb)] :: set verbosity
[%sift dudes=(list dude)] :: per agent
== ::
+$ bitt (map duct (pair ship path)) :: incoming subs
+$ boat :: outgoing subs
%+ map [=wire =ship =term] ::
[acked=? =path] ::
+$ boat (map [=wire =ship =term] [acked=? =path]) :: outgoing subs
+$ boar (map [=wire =ship =term] nonce=@) :: and their nonces
+$ bowl :: standard app state
$: $: our=ship :: host
src=ship :: guest
@ -1789,6 +1800,9 @@
$% [%raw-fact =mark =noun]
sign:agent
==
:: TODO: add more flags?
::
+$ verb ?(%odd)
::
:: +agent: app core
::
@ -2206,10 +2220,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
== ::
@ -2218,8 +2233,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 {<mark>}" 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
@ -2296,9 +2503,6 @@
:: %eyre: cancel request
::
[%cancel-request ~]
:: %khan: fire thread
::
$>(%fyrd task:khan)
:: %dill: reset terminal configuration
::
$>(%hail task:dill)

File diff suppressed because it is too large Load Diff

View File

@ -45,161 +45,112 @@
|= [[now=@da =duct] state=behn-state]
::
|%
:: %entry-points
::
:: +born: urbit restarted; refresh :next-wake and store wakeup timer duct
+| %helpers
::
++ born set-unix-wake(next-wake.state ~, unix-duct.state duct)
:: +crud: handle failure of previous arvo event
::
++ crud
|= [tag=@tas error=tang]
++ this .
++ emit |=(m=move this(moves [m moves]))
++ abet
^+ [moves state]
:: behn must get activated before other vanes in a %wake
:: moves are statefully pre-flopped to ensure that
:: any prepended %doze is emitted first
::
?. =(%wake tag)
~& %behn-crud-not-wake^tag
[[duct %slip %d %flog %crud tag error]~ state]
=. moves (flop moves)
=/ new=(unit @da) (bind (pry:timer-map timers.state) head)
:: emit %doze if needed
::
?: =(~ timers.state)
~|(%behn-crud-no-timer^tag^error !!)
=? ..this
?~ unix-duct.state |
=/ dif=[old=(unit @da) new=(unit @da)] [next-wake.state new]
?+ dif ~|([%unpossible dif] !!)
[~ ~] | :: no-op
[~ ^] & :: set
[^ ~] & :: clear
[^ ^] !=(u.old.dif u.new.dif) :: set if changed
==
(emit(next-wake.state new) [unix-duct.state %give %doze new])
::
(wake `error)
:: +rest: cancel the timer at :date, then adjust unix wakeup
:: +wait: set a new timer at :date, then adjust unix wakeup
[moves state]
::
++ rest |=(date=@da set-unix-wake(timers.state (unset-timer [date duct])))
++ wait |=(date=@da set-unix-wake(timers.state (set-timer [date duct])))
:: +huck: give back immediately
+| %entry-points
::
:: Useful if you want to continue working after other moves finish.
++ call
|= [=task error=(unit tang)]
^+ this
?: ?& ?=(^ error)
!?=(%wake -.task)
==
:: XX more and better error handling
::
~& %behn-crud-not-wake^-.task
(emit [duct %slip %d %flog %crud -.task u.error])
::
?- -.task
%born this(next-wake.state ~, unix-duct.state duct)
%drip (drip p.task)
%huck (emit [duct %give %heck syn.task])
%rest this(timers.state (unset-timer [p.task duct]))
%trim this
%vega this
%wait this(timers.state (set-timer [p.task duct]))
%wake (wake(next-wake.state ~) error)
==
::
++ huck
|= syn=sign-arvo
=< [moves state]
event-core(moves [duct %give %heck syn]~)
:: +drip: XX
::
++ drip
|= mov=vase
=< [moves state]
^+ event-core
=. moves
[duct %pass /drip/(scot %ud count.drips.state) %b %wait +(now)]~
=. movs.drips.state
(~(put by movs.drips.state) count.drips.state mov)
=. count.drips.state +(count.drips.state)
event-core
:: +take-drip: XX
:: +take-drip: the future is now, %give the deferred move
::
++ take-drip
|= [num=@ud error=(unit tang)]
=< [moves state]
^+ event-core
^+ this
=/ drip (~(got by movs.drips.state) num)
=. movs.drips.state (~(del by movs.drips.state) num)
=/ =move
=/ card [%give %meta drip]
?~ error
[duct card]
=/ =tang
(weld u.error `tang`[leaf/"drip failed" ~])
:: XX should be
:: [duct %hurl fail/tang card]
::
[duct %pass /drip-slog %d %flog %crud %drip-fail tang]
event-core(moves [move moves])
:: +trim: in response to memory pressue
%- emit(movs.drips.state (~(del by movs.drips.state) num))
=/ card [%give %meta drip]
?~ error
[duct card]
=/ =tang
(weld u.error `tang`[leaf/"drip failed" ~])
:: XX should be
:: [duct %hurl fail/tang card]
::
[duct %pass /drip-slog %d %flog %crud %drip-fail tang]
::
++ trim [moves state]
:: +vega: learn of a kernel upgrade
+| %tasks
::
++ vega [moves state]
:: +wake: unix says wake up; process the elapsed timer and set :next-wake
:: +drip: enqueue a future gift (as a vase), %pass ourselves a %wait
::
++ drip
|= vax=vase
^+ this
%. [duct %pass /drip/(scot %ud count.drips.state) %b %wait +(now)]
%= emit
movs.drips.state (~(put by movs.drips.state) count.drips.state vax)
count.drips.state +(count.drips.state)
==
::
:: +wake: unix says wake up; process the elapsed timer (or forward error)
::
++ wake
|= error=(unit tang)
^+ [moves state]
:: no-op on spurious but innocuous unix wakeups
::
^+ this
?: =(~ timers.state)
:: no-op on spurious but innocuous unix wakeups
::
~? ?=(^ error) %behn-wake-no-timer^u.error
[moves state]
:: if we errored, pop the timer and notify the client vane of the error
::
?^ error
=< set-unix-wake
=^ =timer timers.state pop-timer
(emit-vane-wake duct.timer error)
:: if unix woke us too early, retry by resetting the unix wakeup timer
::
this
=/ [=timer later-timers=_timers.state] pop-timer
?: (gth date.timer now)
set-unix-wake(next-wake.state ~)
:: pop first timer, tell vane it has elapsed, and adjust next unix wakeup
:: no-op if timer is early, (+abet will reset)
::
this
:: pop the first timer and notify client vane,
:: forwarding error if present
::
=< set-unix-wake
(emit-vane-wake(timers.state later-timers) duct.timer ~)
:: %utilities
:: XX %wake errors should be signaled out-of-band
:: [duct.timer %hurl goof %give %wake ~]
::
(emit(timers.state later-timers) [duct.timer %give %wake error])
::
::+|
+| %implementation
::
++ event-core .
:: +emit-vane-wake: produce a move to wake a vane; assumes no prior moves
::
++ emit-vane-wake
|= [=^duct error=(unit tang)]
event-core(moves [duct %give %wake error]~)
:: +emit-doze: set new unix wakeup timer in state and emit move to unix
::
:: We prepend the unix %doze event so that it is handled first. Arvo must
:: handle this first because the moves %behn emits will get handled in
:: depth-first order. If we're handling a %wake which causes a move to a
:: different vane and a %doze event to send to unix, Arvo needs to process
:: the %doze first because otherwise if the move to the other vane calls
:: back into %behn and emits a second %doze, the second %doze would be
:: handled by unix first which is incorrect.
::
++ emit-doze
|= =date=(unit @da)
^+ event-core
:: no-op if .unix-duct has not yet been set
::
?~ unix-duct.state
event-core
:: make sure we don't try to wake up in the past
::
=? date-unit ?=(^ date-unit) `(max now u.date-unit)
::
%_ event-core
next-wake.state date-unit
moves [[unix-duct.state %give %doze date-unit] moves]
==
:: +set-unix-wake: set or unset next unix wakeup timer based on :i.timers
::
++ set-unix-wake
=< [moves state]
~% %set-unix-wake ..part ~ |-
^+ event-core
::
=* next-wake next-wake.state
=* timers timers.state
:: if no timers, cancel existing wakeup timer or no-op
::
=/ first=(unit [date=@da *]) (pry:timer-map timers.state)
?~ first
?~ next-wake
event-core
(emit-doze ~)
:: if :next-wake is in the past or not soon enough, reset it
::
?^ next-wake
?: &((gte date.u.first u.next-wake) (lte now u.next-wake))
event-core
(emit-doze `date.u.first)
:: there was no unix wakeup timer; set one
::
(emit-doze `date.u.first)
:: +pop-timer: dequeue and produce earliest timer
::
++ pop-timer
@ -267,27 +218,10 @@
wrapped-task=(hobo task)
==
^- [(list move) _behn-gate]
::
=/ =task ((harden task) wrapped-task)
=/ event-core (per-event [now hen] state)
::
=^ moves state
::
:: handle error notifications
::
?^ dud
(crud:event-core -.task tang.u.dud)
::
?- -.task
%born born:event-core
%rest (rest:event-core date=p.task)
%drip (drip:event-core move=p.task)
%huck (huck:event-core syn.task)
%trim trim:event-core
%vega vega:event-core
%wait (wait:event-core date=p.task)
%wake (wake:event-core error=~)
==
abet:(call:event-core task ?~(dud ~ `tang.u.dud))
[moves behn-gate]
:: +load: migrate an old state to a new behn version
::
@ -378,6 +312,6 @@
?> ?=([%drip @ ~] tea)
=/ event-core (per-event [now hen] state)
=^ moves state
(take-drip:event-core (slav %ud i.t.tea) error.hin)
abet:(take-drip:event-core (slav %ud i.t.tea) error.hin)
[moves behn-gate]
--

View File

@ -251,7 +251,7 @@
;meta(charset "utf-8");
;meta(name "viewport", content "width=device-width, initial-scale=1, shrink-to-fit=no");
;link(rel "icon", type "image/svg+xml", href (weld "data:image/svg+xml;utf8," favicon));
;title:"OS1"
;title:"Urbit"
;style:'''
@import url("https://rsms.me/inter/inter.css");
@font-face {
@ -2178,7 +2178,7 @@
:: XX cancel active too if =(0 trim-priority) ?
::
?: ?=(%trim -.task)
=/ event-args [[eny duct now rof] server-state.ax]
=* event-args [[eny duct now rof] server-state.ax]
=* by-channel by-channel:(per-server-event event-args)
=* channel-state channel-state.server-state.ax
::

View File

@ -4,17 +4,47 @@
::
::::
|= our=ship
:: veb: verbosity flags
::
=/ veb-all-off
:: TODO: add more flags?
::
:* odd=`?`%.n :: unusual events
==
=, gall
=>
|%
+| %helpers
:: +trace: print if .verb is set and we're tracking .dude
::
++ trace
|= [verb=? =dude dudes=(set dude) print=tang]
^+ same
?. verb
same
?. => [dude=dude dudes=dudes in=in]
~+ |(=(~ dudes) (~(has in dudes) dude))
same
(slog print)
::
:: $bug: debug printing configuration
::
:: veb: verbosity toggles
:: dudes: app filter; if ~, print for all
::
+$ bug
$: veb=_veb-all-off
dudes=(set dude)
==
::
+| %main
::
:: $move: Arvo-level move
::
+$ move [=duct move=(wind note-arvo gift-arvo)]
:: $state-9: overall gall state, versioned
:: $state-10: overall gall state, versioned
::
+$ state-9 [%9 state]
+$ state-10 [%10 state]
:: $state: overall gall state
::
:: system-duct: TODO document
@ -22,6 +52,7 @@
:: contacts: other ships we're in communication with
:: yokes: running agents
:: blocked: moves to agents that haven't been started yet
:: bug: debug printing configuration
::
+$ state
$: system-duct=duct
@ -29,13 +60,8 @@
contacts=(set ship)
yokes=(map term yoke)
blocked=(map term (qeu blocked-move))
=bug
==
:: $watches: subscribers and publications
::
:: TODO: rename this, to $ties?
:: TODO: rename $boat and $bitt and document
::
+$ watches [inbound=bitt outbound=boat]
:: $routes: new cuff; TODO: document
::
+$ routes
@ -45,8 +71,12 @@
:: $yoke: agent runner state
::
:: control-duct: TODO document
:: run-nonce: unique for each rebuild
:: sub-nonce: app-wide global %watch nonce
:: stats: TODO document
:: watches: incoming and outgoing subscription state
:: bitt: incoming subscriptions
:: boat: outgoing subscriptions
:: boar: and their nonces
:: code: most recently loaded code
:: agent: agent core
:: beak: compilation source
@ -54,9 +84,12 @@
::
+$ yoke
$: control-duct=duct
nonce=@t
run-nonce=@t
sub-nonce=_1
=stats
=watches
=bitt
=boat
=boar
code=*
agent=(each agent vase)
=beak
@ -108,6 +141,7 @@
%poke
%leave
%missing
%cork
==
:: |migrate: data structures for upgrades
::
@ -116,20 +150,24 @@
:: $spore: structures for update, produced by +stay
::
+$ spore
$: %9
$: %10
system-duct=duct
outstanding=(map [wire duct] (qeu remote-request))
contacts=(set ship)
eggs=(map term egg)
blocked=(map term (qeu blocked-move))
=bug
==
:: $egg: migratory agent state; $yoke with .old-state instead of .agent
::
+$ egg
$: control-duct=duct
nonce=@t
run-nonce=@t
sub-nonce=@
=stats
=watches
=bitt
=boat
=boar
code=~
old-state=[%| vase]
=beak
@ -138,7 +176,7 @@
--
:: adult gall vane interface, for type compatibility with pupa
::
=| state=state-9
=| state=state-10
|= [now=@da eny=@uvJ rof=roof]
=* gall-payload .
~% %gall-top ..part ~
@ -151,6 +189,12 @@
++ mo
~% %gall-mo +> ~
|_ [hen=duct moves=(list move)]
::
++ trace
|= [verb=? =dude print=tang]
^+ same
(^trace verb dude dudes.bug.state print)
::
:: +mo-abed: initialise state with the provided duct
:: +mo-abet: finalize, reversing moves
:: +mo-pass: prepend a standard %pass to the current list of moves
@ -159,8 +203,9 @@
++ mo-core .
++ mo-abed |=(hun=duct mo-core(hen hun))
++ mo-abet [(flop moves) gall-payload]
++ mo-pass |=(p=[wire note-arvo] mo-core(moves [[hen pass+p] moves]))
++ mo-give |=(g=gift mo-core(moves [[hen give+g] moves]))
++ mo-pass |=(p=[wire note-arvo] mo-core(moves [[hen pass+p] moves]))
++ mo-slip |=(p=note-arvo mo-core(moves [[hen slip+p] moves]))
++ mo-past
|= =(list [wire note-arvo])
?~ list
@ -175,6 +220,30 @@
=/ =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
|= [dude=(unit dude) ship=(unit ship)]
^+ mo-core
=/ apps=(list (pair term yoke))
?~ dude ~(tap by yokes.state)
(drop (bind (~(get by yokes.state) u.dude) (lead u.dude)))
|- ^+ mo-core
?~ apps mo-core
=/ ap-core (ap-yoke:ap p.i.apps [~ our] q.i.apps)
$(apps t.apps, mo-core ap-abet:(ap-doff:ap-core ship))
:: +mo-rake: send %cork's for old subscriptions if needed
::
++ mo-rake
|= [dude=(unit dude) all=?]
^+ mo-core
=/ apps=(list (pair term yoke))
?~ dude ~(tap by yokes.state)
(drop (bind (~(get by yokes.state) u.dude) (lead u.dude)))
|- ^+ mo-core
?~ apps mo-core
=/ ap-core (ap-yoke:ap p.i.apps [~ our] q.i.apps)
$(apps t.apps, mo-core ap-abet:(ap-rake:ap-core all))
:: +mo-receive-core: receives an app core built by %ford.
::
:: Presuming we receive a good core, we first check to see if the agent
@ -219,7 +288,7 @@
beak bek
code agent
agent &+agent
nonce (scot %uw (end 5 (shas %yoke-nonce eny)))
run-nonce (scot %uw (end 5 (shas %yoke-nonce eny)))
==
::
=/ old mo-core
@ -265,8 +334,12 @@
=. outstanding.state
=/ stand
(~(gut by outstanding.state) [wire hen] *(qeu remote-request))
(~(put by outstanding.state) [wire hen] (~(put to stand) -.deal))
(mo-pass wire note-arvo)
%+ ~(put by outstanding.state) [wire hen]
(~(gas to stand) ?.(?=(%leave -.deal) ~[-.deal] ~[%leave %cork]))
=. mo-core (mo-pass wire note-arvo)
?. ?=(%leave -.deal)
mo-core
(mo-pass wire [%a [%cork ship]])
:: +mo-track-ship: subscribe to ames and jael for notices about .ship
::
++ mo-track-ship
@ -434,7 +507,12 @@
(~(put to *(qeu remote-request)) %missing)
~| [full-wire=full-wire hen=hen stand=stand]
=^ rr stand ~(get to stand)
[rr (~(put by outstanding.state) [full-wire hen] stand)]
~? &(=(rr %cork) ?=(^ stand))
[%outstanding-queue-not-empty wire hen]
:- rr
?: ?=(%cork rr)
(~(del by outstanding.state) [full-wire hen])
(~(put by outstanding.state) [full-wire hen] stand)
:: non-null case of wire is old, remove on next breach after
:: 2019/12
::
@ -450,7 +528,8 @@
%watch (mo-give %unto %watch-ack err)
%poke (mo-give %unto %poke-ack err)
%leave mo-core
%missing (mo-give:(mo-give %unto %watch-ack err) %unto %poke-ack err)
%cork mo-core
%missing ~>(%slog.[3 'gall: missing'] mo-core)
==
::
[%ames %boon *]
@ -459,7 +538,19 @@
::
!!
=/ =ames-response ;;(ames-response payload.sign-arvo)
(mo-handle-ames-response ames-response)
:: %d: diff; ask clay to validate .noun as .mark
:: %x: kick; tell agent the publisher canceled the subscription, and
:: cork; tell ames to close the associated flow.
::
?- -.ames-response
%d (mo-give %unto %raw-fact mark.ames-response noun.ames-response)
%x =. mo-core (mo-give %unto %kick ~)
=. outstanding.state
=/ key [[%sys wire] hen]
%+ ~(put by outstanding.state) key
(~(put to (~(gut by outstanding.state) key ~)) %cork)
(mo-pass [%sys wire] %a %cork ship)
==
::
[%ames %lost *]
:: note this should only happen on reverse bones, so only facts
@ -492,9 +583,18 @@
?~ yoke
%- (slog leaf+"gall: {<dap>} dead, got {<+<.sign-arvo>}" ~)
mo-core
?. =(nonce.u.yoke i.t.wire)
?. =(run-nonce.u.yoke i.t.wire)
%- (slog leaf+"gall: got old {<+<.sign-arvo>} for {<dap>}" ~)
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)
%- (slog leaf+"gall: {<dap>} dozing, dropping {<+<.sign-arvo>}" ~)
@ -690,19 +790,27 @@
=/ running (~(get by yokes.state) agent)
=/ is-running ?~(running %| ?=(%& -.agent.u.running))
=/ is-blocked (~(has by blocked.state) agent)
:: agent is running; deliver move normally
::
?: |(!is-running is-blocked)
=/ blocked=(qeu blocked-move)
=/ waiting (~(get by blocked.state) agent)
=/ deals (fall waiting *(qeu blocked-move))
=/ deal [hen routes &+deal]
(~(put to deals) deal)
::
%- (slog leaf+"gall: not running {<agent>} yet, got {<-.deal>}" ~)
%_ mo-core
blocked.state (~(put by blocked.state) agent blocked)
==
(mo-apply agent routes deal)
?. |(!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)
=/ deals (fall waiting *(qeu blocked-move))
=/ deal [hen routes &+deal]
(~(put to deals) deal)
::
%- (slog leaf+"gall: not running {<agent>} yet, got {<-.deal>}" ~)
%_ mo-core
blocked.state (~(put by blocked.state) agent blocked)
==
:: +mo-handle-ames-request: handle %ames request message.
::
++ mo-handle-ames-request
@ -723,18 +831,28 @@
%u [%leave ~]
==
(mo-pass wire %g %deal [ship our] agent-name deal)
:: +mo-handle-ames-response: handle ames response message.
:: +mo-spew: handle request to set verbosity toggles on debug output
::
++ mo-handle-ames-response
|= =ames-response
++ mo-spew
|= verbs=(list verb)
^+ mo-core
:: %d: diff; ask clay to validate .noun as .mark
:: %x: kick; tell agent the publisher canceled the subscription
::
?- -.ames-response
%d (mo-give %unto %raw-fact mark.ames-response noun.ames-response)
%x (mo-give %unto %kick ~)
==
:: start from all %.n's, then flip requested toggles
::
=. veb.bug.state
%+ roll verbs
|= [=verb acc=_veb-all-off]
^+ veb.bug.state
?- verb
%odd acc(odd %.y)
==
mo-core
:: +mo-sift: handle request to filter debug output by agent
::
++ mo-sift
|= dudes=(list dude)
^+ mo-core
=. dudes.bug.state (sy dudes)
mo-core
:: +ap: agent engine
::
:: An inner, agent-level core. The sample refers to the agent we're
@ -749,6 +867,19 @@
agent-config=(list (each suss tang))
=yoke
==
::
++ trace
|= [verb=? print=tang]
^+ same
(^trace verb agent-name print)
::
++ ap-nonce-wire
|= [=wire =dock]
^+ wire
=/ nonce=@ (~(got by boar.yoke) wire dock)
?: =(0 nonce) wire
[(scot %ud nonce) wire]
::
++ ap-core .
:: +ap-abed: initialise state for an agent, with the supplied routes.
::
@ -796,11 +927,9 @@
::
++ ap-nuke
^+ ap-core
=/ out=(list [[=wire =ship =term] ? =path])
~(tap by outbound.watches.yoke)
=/ inbound-paths=(set path)
%- silt
%+ turn ~(tap by inbound.watches.yoke)
%+ turn ~(tap by bitt.yoke)
|= [=duct =ship =path]
path
=/ will=(list card:agent)
@ -808,9 +937,9 @@
?: =(~ inbound-paths)
~
[%give %kick ~(tap in inbound-paths) ~]~
%+ turn ~(tap by outbound.watches.yoke)
|= [[=wire =ship =term] ? =path]
[%pass wire %agent [ship term] %leave ~]
%+ turn ~(tap by boat.yoke)
|= [[=wire =dock] ? =path]
[%pass (ap-nonce-wire wire dock) %agent dock %leave ~]
=^ maybe-tang ap-core (ap-ingest ~ |.([will *agent]))
ap-core
:: +ap-from-internal: internal move to move.
@ -893,12 +1022,13 @@
tang.neet
==
=. wire
:^ %use agent-name run-nonce.yoke
?- -.neet
%agent [%out (scot %p ship.neet) name.neet wire]
%huck [%out (scot %p ship.neet) name.neet wire]
%arvo [(scot %p attributing.agent-routes) wire]
==
=. wire [%use agent-name nonce.yoke wire]
::
=/ =note-arvo
?- -.neet
%arvo note-arvo.neet
@ -912,8 +1042,7 @@
++ ap-breach
|= =ship
^+ ap-core
=/ in=(list [=duct =^ship =path])
~(tap by inbound.watches.yoke)
=/ in=(list [=duct =^ship =path]) ~(tap by bitt.yoke)
|- ^+ ap-core
?^ in
=? ap-core =(ship ship.i.in)
@ -921,15 +1050,16 @@
core(agent-duct agent-duct)
$(in t.in)
::
=/ out=(list [[=wire =^ship =term] ? =path])
~(tap by outbound.watches.yoke)
=/ out=(list [=wire =^ship =term])
~(tap ^in ~(key by boat.yoke))
|- ^+ ap-core
?~ out
ap-core
=? ap-core =(ship ship.i.out)
=/ core
=. agent-duct system-duct.state
=/ way [%out (scot %p ship) term.i.out wire.i.out]
=. wire.i.out (ap-nonce-wire i.out)
=/ way [%out (scot %p ship) term.i.out wire.i.out]
(ap-specific-take way %kick ~)
core(agent-duct agent-duct)
$(out t.out)
@ -944,8 +1074,7 @@
|= =ship
^+ ap-core
::
=/ in=(list [=duct =^ship =path])
~(tap by inbound.watches.yoke)
=/ in=(list [=duct =^ship =path]) ~(tap by bitt.yoke)
|- ^+ ap-core
?~ in ap-core
::
@ -966,7 +1095,7 @@
?~ target-paths
?~ target-ship
~[agent-duct]
%+ murn ~(tap by inbound.watches.yoke)
%+ murn ~(tap by bitt.yoke)
|= [=duct =ship =path]
^- (unit ^duct)
?: =(target-ship `ship)
@ -981,7 +1110,7 @@
++ ap-ducts-from-path
|= [target-path=path target-ship=(unit ship)]
^- (list duct)
%+ murn ~(tap by inbound.watches.yoke)
%+ murn ~(tap by bitt.yoke)
|= [=duct =ship =path]
^- (unit ^duct)
?: ?& =(target-path path)
@ -1044,15 +1173,6 @@
?: ?=(%& -.res)
``want^p.res
((slog leaf+"peek failed tube from {(trip have)} to {(trip want)}" ~) ~)
:: +ap-update-subscription: update subscription.
::
++ ap-update-subscription
~/ %ap-update-subscription
|= [is-ok=? =other=ship other-agent=term =wire]
^+ ap-core
?: is-ok
ap-core
(ap-kill-down wire [other-ship other-agent])
:: +ap-move: send move
::
++ ap-move
@ -1076,8 +1196,8 @@
attributing.agent-routes :: guest
agent-name :: agent
== ::
:* wex=outbound.watches.yoke :: outgoing
sup=inbound.watches.yoke :: incoming
:* wex=boat.yoke :: outgoing
sup=bitt.yoke :: incoming
== ::
:* act=change.stats.yoke :: tick
eny=eny.stats.yoke :: nonce
@ -1112,9 +1232,8 @@
~/ %ap-subscribe
|= pax=path
^+ ap-core
=/ incoming [attributing.agent-routes pax]
=. inbound.watches.yoke
(~(put by inbound.watches.yoke) agent-duct incoming)
=/ incoming [attributing.agent-routes pax]
=. bitt.yoke (~(put by bitt.yoke) agent-duct incoming)
=^ maybe-tang ap-core
%+ ap-ingest %watch-ack |.
(on-watch:ap-agent-core pax)
@ -1164,6 +1283,7 @@
=/ other-agent i.t.t.wire
=/ =dock [other-ship other-agent]
=/ agent-wire t.t.t.wire
=/ nonce=@ 0
::
=^ =sign:agent ap-core
?. ?=(%raw-fact -.unto)
@ -1184,48 +1304,106 @@
%- ap-move :_ ~
:^ hen %pass /nowhere
[%c %warp our q.beak.yoke ~ %sing %b case /[mark.unto]]
|^ ^+ ap-core
:: %poke-ack has no nonce; ingest directly
::
?: ?=(%poke-ack -.sign)
ingest-and-check-error
:: if .agent-wire matches, it's an old pre-nonce subscription
::
?: (~(has by boat.yoke) sub-key)
run-sign
:: if an app happened to use a null wire, no-op
::
?: =(~ agent-wire)
on-missing
=/ has-nonce=(unit @ud) (slaw %ud (head agent-wire))
?: &(?=(~ has-nonce) ?=(%kick -.sign))
on-weird-kick
:: pop nonce off .agent-wire and match against stored subscription
::
?> ?=(^ has-nonce)
=: nonce u.has-nonce
agent-wire (tail agent-wire)
==
?~ got=(~(get by boar.yoke) sub-key)
on-missing
?: =(nonce.u.got nonce)
run-sign
(on-bad-nonce nonce.u.got)
::
:: if subscription ack or close, handle before calling user code
::
=? outbound.watches.yoke ?=(%kick -.sign)
%- ~(del by outbound.watches.yoke)
[agent-wire dock]
?: ?& ?=(%watch-ack -.sign)
!(~(has by outbound.watches.yoke) [agent-wire dock])
==
%- %: slog
++ sub-key [agent-wire dock]
++ ingest (ap-ingest ~ |.((on-agent:ap-agent-core agent-wire sign)))
++ run-sign
?- -.sign
%poke-ack !!
%fact
=^ tan ap-core ingest
?~ tan ap-core
=. ap-core (ap-kill-down sub-key)
(ap-error -.sign leaf/"take %fact failed, closing subscription" u.tan)
::
%kick
=: boar.yoke (~(del by boar.yoke) sub-key)
boat.yoke (~(del by boat.yoke) sub-key)
==
ingest-and-check-error
::
%watch-ack
?. (~(has by boat.yoke) sub-key)
%. ap-core
%+ trace odd.veb.bug.state :~
leaf+"{<agent-name>}: got ack for nonexistent subscription"
leaf+"{<dock>}: {<agent-wire>}"
>wire=wire<
~
==
ap-core
=? boar.yoke ?=(^ p.sign) (~(del by boar.yoke) sub-key)
::
=. boat.yoke
?^ p.sign (~(del by boat.yoke) sub-key)
::
%+ ~(jab by boat.yoke) sub-key
|= val=[acked=? =path]
%. val(acked &)
%^ trace &(odd.veb.bug.state acked.val)
leaf/"{<agent-name>} 2nd watch-ack on {<val>}" ~
::
ingest-and-check-error
==
::
=? outbound.watches.yoke ?=(%watch-ack -.sign)
?^ p.sign
%- ~(del by outbound.watches.yoke)
[agent-wire dock]
%+ ~(jab by outbound.watches.yoke) [agent-wire dock]
|= [acked=? =path]
=. .
?. acked
.
%- =/ =tape
"{<agent-name>}: received 2nd watch-ack on {<wire dock path>}"
(slog leaf+tape ~)
.
[& path]
++ on-missing
%. ap-core
%+ trace odd.veb.bug.state :~
leaf+"{<agent-name>}: got {<-.sign>} for nonexistent subscription"
leaf+"{<dock>}: {<[nonce=nonce agent-wire]>}"
>wire=wire<
==
::
=^ maybe-tang ap-core
%+ ap-ingest ~ |.
(on-agent:ap-agent-core agent-wire sign)
:: if failed %fact handling, kill subscription
++ on-weird-kick
%. run-sign
%+ trace odd.veb.bug.state :~
leaf+"{<agent-name>}: got %kick for nonexistent subscription"
leaf+"{<dock>}: {<agent-wire>}"
>wire=wire<
==
::
=? ap-core ?=(%fact -.sign)
(ap-update-subscription =(~ maybe-tang) p.dock q.dock agent-wire)
?^ maybe-tang
(ap-error -.sign leaf/"closing subscription" u.maybe-tang)
ap-core
++ on-bad-nonce
|= stored-nonce=@
%. ap-core
%- slog :~
=/ nonces [expected=stored-nonce got=nonce]
=/ ok |(?=(?(%fact %kick) -.sign) =(~ p.sign))
leaf+"{<agent-name>}: stale {<-.sign>} {<nonces>} ok={<ok>}"
::
leaf+"{<dock>}: {<agent-wire>}"
>wire=wire<
==
::
++ ingest-and-check-error
^+ ap-core
=^ tan ap-core ingest
?~(tan ap-core (ap-error -.sign leaf/"take {<-.sign>} failed" u.tan))
--
:: +ap-install: install wrapper.
::
++ ap-install
@ -1259,24 +1437,18 @@
::
++ ap-silent-delete
^+ ap-core
::
%= ap-core
inbound.watches.yoke
(~(del by inbound.watches.yoke) agent-duct)
==
ap-core(bitt.yoke (~(del by bitt.yoke) agent-duct))
:: +ap-load-delete: load delete.
::
++ ap-load-delete
^+ ap-core
::
=/ maybe-incoming
(~(get by inbound.watches.yoke) agent-duct)
=/ maybe-incoming (~(get by bitt.yoke) agent-duct)
?~ maybe-incoming
ap-core
::
=/ incoming u.maybe-incoming
=. inbound.watches.yoke
(~(del by inbound.watches.yoke) agent-duct)
=/ incoming u.maybe-incoming
=. bitt.yoke (~(del by bitt.yoke) agent-duct)
::
=^ maybe-tang ap-core
%+ ap-ingest ~ |.
@ -1310,12 +1482,76 @@
:: Must process leave first in case kick handler rewatches.
::
++ ap-kill-down
|= [=wire =dock]
|= [sub-wire=wire =dock]
^+ ap-core
::
=. ap-core
(ap-pass wire %agent dock %leave ~)
(ap-pass wire %huck dock %b %huck `sign-arvo`[%gall %unto %kick ~])
:: we take care to include the nonce in the "kernel-facing" wire
::
(ap-pass (ap-nonce-wire sub-wire dock) %agent dock %leave ~)
(ap-pass sub-wire %huck dock %b %huck `sign-arvo`[%gall %unto %kick ~])
:: +ap-doff: kill old-style outgoing subscriptions
::
++ ap-doff
|= ship=(unit ship)
^+ ap-core
=/ subs ~(tap in ~(key by boat.yoke))
|- ^+ ap-core
?~ subs ap-core
=+ [wyr dok]=i.subs
?: &(?=(^ ship) !=(u.ship ship.dok))
$(subs t.subs)
:: if we haven't created new-style (nonced) subscriptions yet,
:: kick the old-style (nonceless) one that's in use right now.
::
::NOTE yes, still safe for pre-release ships with nonce=1,
:: this makes a new flow but cleans it up right away.
::
=? ap-core (gte 1 (~(got by boar.yoke) wyr dok))
(ap-pass wyr %agent dok %leave ~)
$(subs t.subs)
:: +ap-rake: clean up the dead %leave's
::
++ ap-rake
|= all=?
=/ subs ~(tap in ~(key by boat.yoke))
|^ ^+ ap-core
?~ subs ap-core
=/ [=wire =dock] i.subs
=/ non (~(got by boar.yoke) wire dock)
?: &(!all =(0 non))
$(subs t.subs)
?~ per=(scry-peer-state p.dock)
$(subs t.subs)
::
=/ dud=(set duct)
=/ mod=^wire
:* %gall %use agent-name run-nonce.yoke
%out (scot %p p.dock) q.dock
'0' wire
==
%- ~(rep by by-duct.ossuary.u.per)
|= [[=duct =bone] out=(set duct)]
^+ out
?. ?& ?=([* [%gall %use @ @ %out @ @ @ *] *] duct)
=(mod i.t.duct(i.t.t.t.t.t.t.t '0'))
==
out
?: (~(has in closing.u.per) bone) out
~> %slog.0^leaf+"gall: rake {<i.t.duct>}"
(~(put in out) duct)
::
%- ap-move
(turn ~(tap in dud) |=(d=duct [+.d %pass -.d %a %cork p.dock]))
::
++ scry-peer-state
|= her=ship
~+ ^- (unit peer-state:ames)
=/ sky (rof [~ ~] %ax [our %$ da+now] /peers/(scot %p her))
?: |(?=(~ sky) ?=(~ u.sky))
~
=/ sat !<(ship-state:ames q.u.u.sky)
?>(?=(%known -.sat) (some +.sat))
--
:: +ap-mule: run virtualized with intercepted scry, preserving type
::
:: Compare +mute and +mule. Those pass through scry, which
@ -1381,11 +1617,10 @@
`ap-core
::
=. agent.yoke &++.p.result
=/ moves (zing (turn -.p.result ap-from-internal))
=. inbound.watches.yoke
(ap-handle-kicks moves)
=/ moves (zing (turn -.p.result ap-from-internal))
=. bitt.yoke (ap-handle-kicks moves)
(ap-handle-peers moves)
:: +ap-handle-kicks: handle cancels of inbound.watches
:: +ap-handle-kicks: handle cancels of bitt.watches
::
++ ap-handle-kicks
~/ %ap-handle-kicks
@ -1401,8 +1636,8 @@
::
=/ quit-map=bitt
(malt (turn quits |=(=duct [duct *[ship path]])))
(~(dif by inbound.watches.yoke) quit-map)
:: +ap-handle-peers: handle new outbound.watches
(~(dif by bitt.yoke) quit-map)
:: +ap-handle-peers: handle new boat.watches
::
++ ap-handle-peers
~/ %ap-handle-peers
@ -1416,34 +1651,59 @@
?: ?=([* %pass * %g %deal * * %leave *] move)
=/ =wire p.move.move
?> ?=([%use @ @ %out @ @ *] wire)
=/ short-wire t.t.t.t.t.t.wire
=/ =dock [q.p q]:q.move.move
=. outbound.watches.yoke
(~(del by outbound.watches.yoke) [short-wire dock])
=/ =dock [q.p q]:q.move.move
=/ sys-wire=^wire (scag 6 `^wire`wire)
=/ sub-wire=^wire (slag 6 `^wire`wire)
::
?. (~(has by boat.yoke) sub-wire dock)
%. $(moves t.moves)
%^ trace odd.veb.bug.state
leaf/"gall: {<agent-name>} missing subscription, got %leave" ~
=/ nonce=@ (~(got by boar.yoke) sub-wire dock)
=. p.move.move
%+ weld sys-wire
(ap-nonce-wire sub-wire dock)
=: boat.yoke (~(del by boat.yoke) [sub-wire dock])
boar.yoke (~(del by boar.yoke) [sub-wire dock])
==
:: if nonce = 0, this was a pre-nonce subscription so later
:: subscriptions need to start subscribing on the next nonce
::
=? sub-nonce.yoke =(nonce 0) +(sub-nonce.yoke)
$(moves t.moves, new-moves [move new-moves])
?. ?=([* %pass * %g %deal * * ?(%watch %watch-as) *] move)
$(moves t.moves, new-moves [move new-moves])
=/ =wire p.move.move
?> ?=([%use @ @ %out @ @ *] wire)
=/ short-wire t.t.t.t.t.t.wire
=/ =dock [q.p q]:q.move.move
=/ =path
?- -.r.q.move.move
%watch path.r.q.move.move
%watch-as path.r.q.move.move
==
?: (~(has by outbound.watches.yoke) short-wire dock)
=/ sys-wire=^wire (scag 6 `^wire`wire)
=/ sub-wire=^wire (slag 6 `^wire`wire)
=/ [=dock =deal] [[q.p q] r]:q.move.move
::
?: (~(has by boat.yoke) sub-wire dock)
=. ap-core
=/ =tang
~[leaf+"subscribe wire not unique" >agent-name< >short-wire< >dock<]
=/ have
(~(got by outbound.watches.yoke) short-wire dock)
~[leaf+"subscribe wire not unique" >agent-name< >sub-wire< >dock<]
=/ have (~(got by boat.yoke) sub-wire dock)
%- (slog >out=have< tang)
(ap-error %watch-not-unique tang) :: reentrant, maybe bad?
$(moves t.moves)
=. outbound.watches.yoke
(~(put by outbound.watches.yoke) [short-wire dock] [| path])
$(moves t.moves, new-moves [move new-moves])
::
::NOTE 0-check guards against pre-release bug
=? p.move.move !=(0 sub-nonce.yoke)
(weld sys-wire [(scot %ud sub-nonce.yoke) sub-wire])
%_ $
moves t.moves
new-moves [move new-moves]
sub-nonce.yoke +(sub-nonce.yoke)
::
boat.yoke
%+ ~(put by boat.yoke) [sub-wire dock]
:- acked=|
path=?+(-.deal !! %watch path.deal, %watch-as path.deal)
::
boar.yoke
(~(put by boar.yoke) [sub-wire dock] sub-nonce.yoke)
==
--
--
:: +call: request
@ -1487,6 +1747,10 @@
%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)
%spew mo-abet:(mo-spew:mo-core veb.task)
%sift mo-abet:(mo-sift:mo-core dudes.task)
%trim [~ gall-payload]
%vega [~ gall-payload]
==
@ -1494,14 +1758,35 @@
::
++ load
|^ |= old=spore-any
=? old ?=(%7 -.old)
(spore-7-to-8 old)
=? old ?=(%8 -.old)
(spore-8-to-9 old)
?> ?=(%9 -.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)
gall-payload(state old)
::
+$ spore-any $%(spore spore-7 spore-8)
+$ spore-any $%(spore spore-7 spore-8 spore-9)
+$ spore-9
$: %9
system-duct=duct
outstanding=(map [wire duct] (qeu remote-request))
contacts=(set ship)
eggs=(map term egg-9)
blocked=(map term (qeu blocked-move))
=bug
==
+$ egg-9
$: control-duct=duct
run-nonce=@t
sub-nonce=@
live=?
=stats
=bitt
=boat
=boar
old-state=(each vase vase)
=beak
marks=(map duct mark)
==
+$ spore-8
$: %8
system-duct=duct
@ -1512,14 +1797,16 @@
==
+$ egg-8
$: control-duct=duct
nonce=@t
run-nonce=@t
live=?
=stats
=watches
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
@ -1542,20 +1829,42 @@
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-9
=/ [=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))]
::
:: removed live
:: changed old-state from (each vase vase) to [%| vase]
:: added code
::
++ spore-8-to-9
|= old=spore-8
++ spore-9-to-10
|= old=spore-9
^- spore
%= old
- %9
- %10
eggs
%- ~(urn by eggs.old)
|= [a=term e=egg-8]
|= [a=term e=egg-9]
^- egg
e(|2 |3.e(|2 `|5.e(old-state [%| p.old-state.e])))
e(|3 |4.e(|4 `|8.e(old-state [%| p.old-state.e])))
==
--
:: +scry: standard scry
@ -1623,6 +1932,28 @@
acc
(~(put in acc) [dude -.agent.yoke])
::
?: ?& =(%f care)
=(~ path)
=([%$ %da now] coin)
=(our ship)
==
:+ ~ ~
:- %nonces !> ^- (map dude @)
(~(run by yokes.state) |=(yoke sub-nonce))
::
?: ?& =(%n care)
?=([@ @ ^] path)
=([%$ %da now] coin)
=(our ship)
==
?~ yok=(~(get by yokes.state) dap)
[~ ~]
=/ [=^ship =term =wire]
[(slav %p i.path) i.t.path t.t.path]
?~ nonce=(~(get by boar.u.yok) [wire ship term])
[~ ~]
[~ ~ atom+!>(u.nonce)]
::
?. =(our ship)
~
?. =([%$ %da now] coin)

View File

@ -102,10 +102,10 @@
=/ =beam (need (de-beam t.wire))
?>(?=([@ ~] s.beam) beam(s i.s.beam))
::
++ start-spider
|= =vase
++ poke-spider
|= =cage
^- note
[%g %deal [our our] %spider %poke %spider-start vase]
[%g %deal [our our] %spider %poke cage]
::
++ watch-spider
|= =path
@ -146,7 +146,7 @@
:_ khan-gate
%+ turn
:~ (watch-spider /thread-result/[tid])
(start-spider !>(args))
(poke-spider %spider-start !>(args))
==
|=(=note ^-(move [hen %pass //g note]))
::
@ -159,6 +159,21 @@
(slap (vale.dais q.q.args.fyd) !,(*hoon [~ u=.]))
=- [[hen %pass wire -]~ khan-gate]
[%k %fard bear.fyd name.fyd p.q.args.fyd vase]
::
%lard
=/ tid=@ta
%^ cat 3
'khan-lard--'
(scot %uv (sham (mix tic eny)))
=. tic +(tic)
=/ =beak (get-beak bear.task now)
=/ args [~ `tid beak shed.task]
:_ khan-gate
%+ turn
:~ (watch-spider /thread-result/[tid])
(poke-spider %spider-inline !>(args))
==
|=(=note ^-(move [hen %pass //g note]))
==
:: +load: migrate an old state to a new khan version
::

View File

@ -25,7 +25,7 @@
|= if=@if
=/ m (strand ,~)
^- form:m
=/ collector-app `dock`[~zod %dns-collector]
=/ collector-app `dock`[~deg %dns-collector]
;< good=? bind:m (self-check-http:libdns |+if 2)
?. good
%+ strand-fail:strandio %bail-early-self-check

View File

@ -353,10 +353,14 @@
!> [~[/g/talk] %give %boon [%post 'first1']]
!> (snag 0 `(list move:ames)`moves6)
==
:: +test-comet-message-flow: galaxy<->comet comms
::
:: same as test-message-flow, but ~nec will send a sendkeys packet to
:: request comet's self-attestation directly
::
++ test-comet-message-flow ^- tang
:: same as test-message-flow, but ~nec will send a sendkeys packet to request
:: comet's self-attestation directly
::=^ * nec (call nec ~[//nemo] %spew ~[%snd %rcv %odd %msg])
::=^ * comet (call comet ~[//nemo] %spew ~[%snd %rcv %odd %msg])
::
=^ moves0 nec (call nec ~[/g/talk] %plea our-comet %g /talk [%get %post])
=^ moves1 comet (call comet ~[//unix] %hear (snag-packet 0 moves0))
@ -371,27 +375,34 @@
:^ comet /public-keys ~[//unix]
^- sign:ames
[%jael %public-keys %full [n=[~nec point] ~ ~]]
:: give comet's self-attestation to ~nec; at this point, we have established
:: a channel, and can proceed as usual
:: give comet's self-attestation to ~nec; at this point, we have
:: established a channel, and can proceed as usual
::
=/ post [%post 'first1!!']
=^ moves3 nec (call nec ~[//unix] %hear (snag-packet 0 moves2))
%+ weld
%- expect-fail |.
(call nec ~[//unix] %hear (snag-packet 1 moves2))
::
=^ moves4 comet (call comet ~[//unix] %hear (snag-packet 0 moves3))
=^ moves5 comet (take comet /bone/~nec/0/1 ~[//unix] %g %done ~)
=^ moves5 comet (take comet /bone/~nec/1/1 ~[//unix] %g %done ~)
=^ moves6 nec (call nec ~[//unix] %hear (snag-packet 0 moves5))
=^ moves7 comet (take comet /bone/~nec/0/1 ~[//unix] %g %boon [%post 'first1!!'])
=^ moves7 comet (take comet /bone/~nec/1/1 ~[//unix] %g %boon post)
=^ moves8 nec (call nec ~[//unix] %hear (snag-packet 0 moves7))
::
;: weld
%+ expect-eq
!> [~[//unix] %pass /qos %d %flog %text "; ~nec is your neighbor"]
!> =- [~[//unix] %pass /qos %d %flog %text -]
"; ~nec is your neighbor"
!> (snag 0 `(list move:ames)`moves4)
::
%+ expect-eq
!> [~[//unix] %pass /qos %d %flog %text "; {<our-comet>} is your neighbor"]
!> =- [~[//unix] %pass /qos %d %flog %text -]
"; {<our-comet>} is your neighbor"
!> (snag 0 `(list move:ames)`moves6)
::
%+ expect-eq
!> [~[/g/talk] %give %boon [%post 'first1!!']]
!> [~[/g/talk] %give %boon post]
!> (snag 0 `(list move:ames)`moves8)
==
::

View File

@ -0,0 +1,234 @@
/+ *test
/= behn-raw /sys/vane/behn
=/ behn-gate (behn-raw ~bus)
=/ scry *roof
=* move move:behn-gate
::
|%
++ test-wake-no
^- tang
=/ wen ~1111.1.1
=/ arg [~[/vere] [%wake ~]]
-:(call ~ wen arg ~)
::
++ test-wake-no-wait
^- tang
=/ wen ~1111.1.1
::
=/ a-arg [~[/vere] [%born ~]]
=/ a-out ~
=^ a behn-gate (call `%a wen a-arg a-out)
::
=/ b-arg [~[/vere] [%wake ~]]
=/ b-out ~
=^ b behn-gate (call `%b wen b-arg b-out)
::
(weld a b)
::
++ test-wake-no-born
^- tang
=/ wen ~1111.1.1
::
=/ a-arg [~[/foo] [%wait +(wen)]]
=/ a-out ~
=^ a behn-gate (call `%a wen a-arg a-out)
::
=/ b-arg [~[/vere] [%wake ~]]
=/ b-out ~
=^ b behn-gate (call `%b wen b-arg b-out)
::
(weld a b)
::
++ test-wake
^- tang
=/ wen ~1111.1.1
::
=/ a-arg [~[/vere] [%born ~]]
=/ a-out ~
=^ a behn-gate
(call ~ wen a-arg a-out)
::
=/ b-arg [~[/foo] [%wait +(wen)]]
=/ b-out=(list move) [~[/vere] [%give [%doze `+(wen)]]]~
=^ b behn-gate (call `%b wen b-arg b-out)
::
=/ c-arg [~[/vere] [%wake ~]]
=/ c-out=(list move) [~[/foo] [%give [%wake ~]]]~
=^ c behn-gate (call `%c +(wen) c-arg c-out)
::
:(weld a b c)
::
++ test-born
^- tang
=/ wen ~1111.1.1
::
=/ a-arg [~[/foo] [%wait +(wen)]]
=/ a-out ~
=^ a behn-gate (call `%a wen a-arg a-out)
::
=/ b-arg [~[/vere] [%born ~]]
=/ b-out=(list move) [~[/vere] [%give [%doze `+(wen)]]]~
=^ b behn-gate (call `%b wen b-arg b-out)
::
(weld a b)
::
++ test-many-ordered
^- tang
=/ wen ~1111.1.1
::
=/ a-arg [~[/vere] [%born ~]]
=/ a-out ~
=^ a behn-gate (call `%a wen a-arg a-out)
::
=/ b-arg [~[/foo] [%wait +(wen)]]
=/ b-out=(list move) [~[/vere] [%give [%doze `+(wen)]]]~
=^ b behn-gate (call `%b wen b-arg b-out)
::
=/ c-arg [~[/foo] [%wait (add 2 wen)]]
=/ c-out ~
=^ c behn-gate (call `%c wen c-arg c-out)
::
=/ d-arg [~[/foo] [%wait (add 3 wen)]]
=/ d-out ~
=^ d behn-gate (call `%d wen d-arg d-out)
::
=/ e-arg [~[/vere] [%wake ~]]
=/ e-out=(list move)
:~ [~[/vere] [%give [%doze `(add 2 wen)]]]
[~[/foo] [%give [%wake ~]]]
==
=^ e behn-gate (call `%e (add 4 wen) e-arg e-out)
::
:(weld a b c d e)
::
++ test-many-ordered-lag
^- tang
=/ wen ~1111.1.1
::
=/ a-arg [~[/vere] [%born ~]]
=/ a-out ~
=^ a behn-gate (call `%a wen a-arg a-out)
::
=/ b-arg [~[/foo] [%wait +(wen)]]
=/ b-out=(list move) [~[/vere] [%give [%doze `+(wen)]]]~
=^ b behn-gate (call `%b wen b-arg b-out)
::
=/ c-arg [~[/foo] [%wait (add 2 wen)]]
=/ c-out ~
=^ c behn-gate (call `%c wen c-arg c-out)
::
=/ d-arg [~[/foo] [%wait (add 3 wen)]]
=/ d-out ~
=^ d behn-gate (call `%d wen d-arg d-out)
::
=/ e-arg [~[/vere] [%wake ~]]
=/ e-out=(list move)
:~ [~[/vere] [%give [%doze `(add 2 wen)]]]
[~[/foo] [%give [%wake ~]]]
==
=^ e behn-gate (call `%e +(wen) e-arg e-out)
::
:(weld a b c d e)
::
++ test-many-unordered
^- tang
=/ wen ~1111.1.1
::
=/ a-arg [~[/vere] [%born ~]]
=/ a-out ~
=^ a behn-gate (call `%a wen a-arg a-out)
::
=/ b-arg [~[/foo] [%wait (add 2 wen)]]
=/ b-out=(list move) [~[/vere] [%give [%doze `(add 2 wen)]]]~
=^ b behn-gate (call `%b wen b-arg b-out)
::
=/ c-arg [~[/foo] [%wait (add 3 wen)]]
=/ c-out ~
=^ c behn-gate (call `%c wen c-arg c-out)
::
=/ d-arg [~[/foo] [%wait +(wen)]]
=/ d-out=(list move) [~[/vere] [%give [%doze `+(wen)]]]~
=^ d behn-gate (call `%d wen d-arg d-out)
::
=/ e-arg [~[/vere] [%wake ~]]
=/ e-out=(list move)
:~ [~[/vere] [%give [%doze `(add 2 wen)]]]
[~[/foo] [%give [%wake ~]]]
==
=^ e behn-gate (call `%e (add 4 wen) e-arg e-out)
::
:(weld a b c d e)
::
++ test-same-ordered-lag
^- tang
=/ wen ~1111.1.1
::
=/ a-arg [~[/vere] [%born ~]]
=/ a-out ~
=^ a behn-gate (call `%a wen a-arg a-out)
::
=/ b-arg [~[/foo] [%wait (add 2 wen)]]
=/ b-out=(list move) [~[/vere] [%give [%doze `(add 2 wen)]]]~
=^ b behn-gate (call `%b wen b-arg b-out)
::
=/ c-arg [~[/foo] [%wait (add 2 wen)]]
=/ c-out ~
=^ c behn-gate (call `%c wen c-arg c-out)
::
=/ d-arg [~[/foo] [%wait (add 2 wen)]]
=/ d-out ~
=^ d behn-gate (call `%d wen d-arg d-out)
::
=/ e-arg [~[/vere] [%wake ~]]
=/ e-out=(list move)
:~ [~[/vere] [%give [%doze `(add 2 wen)]]]
[~[/foo] [%give [%wake ~]]]
==
=^ e behn-gate (call `%e (add 3 wen) e-arg e-out)
::
:(weld a b c d e)
::
++ test-rest
^- tang
=/ wen ~1111.1.1
::
=/ a-arg [~[/vere] [%born ~]]
=/ a-out ~
=^ a behn-gate (call `%a wen a-arg a-out)
::
=/ b-arg [~[/foo] [%wait (add 2 wen)]]
=/ b-out=(list move) [~[/vere] [%give [%doze `(add 2 wen)]]]~
=^ b behn-gate (call `%b wen b-arg b-out)
::
=/ c-arg [~[/foo] [%wait (add 3 wen)]]
=/ c-out ~
=^ c behn-gate (call `%c wen c-arg c-out)
::
=/ d-arg [~[/foo] [%rest (add 2 wen)]]
=/ d-out=(list move) [~[/vere] [%give [%doze `(add 3 wen)]]]~
=^ d behn-gate (call `%d wen d-arg d-out)
::
=/ e-arg [~[/vere] [%wake ~]]
=/ e-out=(list move) [~[/foo] [%give [%wake ~]]]~
=^ e behn-gate (call `%e (add 4 wen) e-arg e-out)
::
:(weld a b c d e)
::
++ call
=| lac=?
|= $: label=(unit @tas)
now=@da
args=[=duct task=(hobo task:behn)]
expected-moves=(list move)
==
=/ behn-core (behn-gate now=now eny=`@`0xdead.beef scry=scry)
=^ moves behn-gate
(call:behn-core duct.args dud=~ task.args)
::
~? !lac moves
=/ output=tang
%+ expect-eq
!> expected-moves
!> moves
[?~(label output ?~(output ~ [u.label output])) behn-gate]
--

View File

@ -66,7 +66,7 @@
::
++ rest
|= p=@da
(arvo %b %wait p)
(arvo %b %rest p)
::
++ warp
|= [wer=ship =riff:clay]

View File

@ -11,7 +11,7 @@
|%
++ prefixes
^- (map network tape)
(my [[%main "bc"] [%testnet "tb"] ~])
(my [[%main "bc"] [%testnet "tb"] [%regtest "bcrt"] ~])
++ charset "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
+$ raw-decoded [hrp=tape data=(list @) checksum=(list @)]
:: below is a port of: https://github.com/bitcoinjs/bech32/blob/master/index.js

View File

@ -56,6 +56,8 @@
1^0x0
%testnet
1^0x1
%regtest
1^0x1
==
:- (cat:byt ~[1^typ pubkey.h])
%- cat:byt

View File

@ -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 {<mark>}" 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

View File

@ -4,7 +4,7 @@
:: chyg: whether account is (non-)change. 0 or 1
:: bytc: "btc-byts" with dat cast to @ux
|%
+$ network ?(%main %testnet)
+$ network ?(%main %testnet %regtest)
+$ hexb [wid=@ dat=@ux] :: hex byts
+$ bits [wid=@ dat=@ub]
+$ xpub @ta

View File

@ -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
==
--

View File

@ -169,12 +169,17 @@
%+ req-card act
^- action:rpc-types
?- -.act
%address-info [%get-address-info address.act]
%tx-info [%get-tx-vals txid.act]
%raw-tx [%get-raw-tx txid.act]
%broadcast-tx [%broadcast-tx rawtx.act]
%ping [%get-block-info ~]
%block-info [%get-block-info block.act]
%address-info [%get-address-info address.act]
%tx-info [%get-tx-vals txid.act]
%raw-tx [%get-raw-tx txid.act]
%broadcast-tx [%broadcast-tx rawtx.act]
%ping [%get-block-info ~]
%block-info [%get-block-info block.act]
%histogram [%get-histogram ~]
%block-headers [%get-block-headers start.act count.act cp.act]
%tx-from-pos [%get-tx-from-pos height.act pos.act merkle.act]
%fee [%get-fee block.act]
%psbt [%update-psbt psbt.act]
==
::
++ req-card
@ -309,6 +314,31 @@
?> ?=([%get-block-info *] r)
:_ state
~[(send-update:hc [%.y %block-info network.host-info +.r] ship)]
::
%histogram
?> ?=([%get-histogram *] r)
:_ state
~[(send-update:hc [%.y %histogram +.r] ship)]
::
%block-headers
?> ?=([%get-block-headers *] r)
:_ state
~[(send-update:hc [%.y %block-headers +.r] ship)]
::
%tx-from-pos
?> ?=([%get-tx-from-pos *] r)
:_ state
~[(send-update:hc [%.y %tx-from-pos +.r] ship)]
::
%fee
?> ?=([%get-fee *] r)
:_ state
~[(send-update:hc [%.y %fee +.r] ship)]
::
%psbt
?> ?=([%update-psbt *] r)
:_ state
~[(send-update:hc [%.y %psbt +.r] ship)]
==
::
++ connection-error

View File

@ -900,7 +900,7 @@
?: =(~ prov) `state
?. =(host:(need prov) src.bowl) `state
?. ?=(%.y -.upd) `state
?- -.p.upd
?+ -.p.upd `state
%address-info
:: located in the helper in Scan Logic to keep all of that unified
::

View File

@ -5,7 +5,7 @@
glob-http+['https://bootstrap.urbit.org/glob-0v3.7b5q1.gn30e.cpfem.abmqg.qh77v.glob' 0v3.7b5q1.gn30e.cpfem.abmqg.qh77v]
image+'https://urbit.ewr1.vultrobjects.com/hastuc-dibtux/2021.8.24..02.57.38-bitcoin.svg'
base+'bitcoin'
version+[0 0 1]
version+[0 0 2]
license+'MIT'
website+'https://tlon.io'
==

View File

@ -74,6 +74,7 @@
:- ?- network
%main 1^0x0
%testnet 1^0x6f
%regtest 1^0x6f
==
~[(hash-160:bcu pubkey)]
::
@ -84,6 +85,7 @@
:~ ?- network
%main 1^0x5
%testnet 1^0xc4
%regtest 1^0xc4
==
%- hash-160:bcu
(cat:byt:bcu ~[2^0x14 (hash-160:bcu pubkey)])
@ -109,7 +111,8 @@
++ is-base58
|= at=tape
^- ?
?| =("m" (scag 1 at))
?| =("n" (scag 1 at))
=("m" (scag 1 at))
=("1" (scag 1 at))
=("3" (scag 1 at))
=("2" (scag 1 at))
@ -120,6 +123,7 @@
^- ?
?| =("bc1" (scag 3 at))
=("tb1" (scag 3 at))
=("bcrt1" (scag 5 at))
==
--
::

View File

@ -423,6 +423,21 @@
::
%get-block-info
[id.res (block-info res.res)]
::
%get-histogram
[id.res ((ar (ar ni)) res.res)]
::
%get-block-headers
[id.res (block-headers res.res)]
::
%get-tx-from-pos
[id.res (tx-from-pos res.res)]
::
%get-fee
[id.res (ne res.res)]
::
%update-psbt
[id.res (so res.res)]
==
::
++ address-info
@ -433,7 +448,7 @@
[%block ni]
==
++ utxo
%- ot
%- ot
:~ ['tx_pos' ni]
['tx_hash' (cu from-cord:hxb:bcu so)]
[%height ni]
@ -474,11 +489,25 @@
[%blockhash (cu from-cord:hxb:bcu so)]
[%blockfilter (cu from-cord:hxb:bcu so)]
==
++ block-headers
%- ot
:~ [%count ni]
[%hex (cu from-cord:hxb:bcu so)]
[%max ni]
[%root (cu:dejs-soft:format from-cord:hxb:bcu so:dejs-soft:format)]
[%branch (ar (cu from-cord:hxb:bcu so))]
==
++ tx-from-pos
%- ot
:~ [%tx-hash (cu from-cord:hxb:bcu so)]
[%merkle (ar (cu from-cord:hxb:bcu so))]
==
--
--
::
++ rpc-action-to-http
|= [endpoint=@t ract=action:rpc-types:bp]
=, enjs:format
|^ ^- request:http
?- -.ract
%get-address-info
@ -510,6 +539,39 @@
?~(block.ract '' (rsh [3 2] (scot %ui u.block.ract)))
%- get-request
(mk-url '/getblockinfo/' param)
::
%get-histogram
%- get-request
(mk-url '/feehistogram' '')
::
%get-block-headers
%+ post-request
%+ mk-url '/blockheaders' ''
%- pairs
:~ [%start (numb start.ract)]
[%count (numb count.ract)]
[%cp (numb (fall cp.ract 0))]
==
::
%get-tx-from-pos
%+ post-request
%+ mk-url '/txfrompos' ''
%- pairs
:~ [%height (numb height.ract)]
[%pos (numb pos.ract)]
[%merkle %b merkle.ract]
==
::
%get-fee
%- get-request
%+ mk-url '/estimatefee/'
%- crip
%+ scow %ud block.ract
::
%update-psbt
%- get-request
%+ mk-url '/updatepsbt/'
%- en:base64:mimes:html [(lent (trip psbt.ract)) psbt.ract]
==
++ mk-url
|= [base=@t params=@t]

View File

@ -33,6 +33,11 @@
[%broadcast-tx rawtx=hexb]
[%ping ~]
[%block-info block=(unit @ud)]
[%histogram ~]
[%block-headers start=@ud count=@ud cp=(unit @ud)]
[%tx-from-pos height=@ud pos=@ud merkle=?]
[%fee block=@ud]
[%psbt psbt=@t]
==
::
+$ result
@ -41,6 +46,11 @@
[%raw-tx txid=hexb rawtx=hexb]
[%broadcast-tx txid=hexb broadcast=? included=?]
[%block-info =network block=@ud fee=(unit sats) blockhash=hexb blockfilter=hexb]
[%histogram hist=(list (list @ud))]
[%block-headers count=@ud hex=hexb max=@ud root=(unit hexb) branch=(list hexb)]
[%tx-from-pos tx-hash=hexb merkle=(list hexb)]
[%fee fee=@rd]
[%psbt psbt=@t]
==
+$ error
$% [%not-connected status=@ud]
@ -64,6 +74,11 @@
[%broadcast-tx rawtx=hexb]
[%get-block-count ~]
[%get-block-info block=(unit @ud)]
[%get-histogram ~]
[%get-block-headers start=@ud count=@ud cp=(unit @ud)]
[%get-tx-from-pos height=@ud pos=@ud merkle=?]
[%get-fee block=@ud]
[%update-psbt psbt=@t]
==
::
+$ result
@ -74,7 +89,11 @@
[%broadcast-tx txid=hexb broadcast=? included=?]
[%get-block-count block=@ud]
[%get-block-info block=@ud fee=(unit sats) blockhash=hexb blockfilter=hexb]
[%get-histogram hist=(list (list @ud))]
[%get-block-headers count=@ud hex=hexb max=@ud root=(unit hexb) branch=(list hexb)]
[%get-tx-from-pos tx-hash=hexb merkle=(list hexb)]
[%get-fee fee=@rd]
[%update-psbt psbt=@t]
==
--
--

View File

@ -4,7 +4,7 @@
glob-http+['https://bootstrap.urbit.org/glob-0v5.kgrq2.gp725.bo5bk.dmr7d.h41qk.glob' 0v5.kgrq2.gp725.bo5bk.dmr7d.h41qk]
::glob-ames+~zod^0v0
base+'grid'
version+[1 1 3]
version+[1 1 6]
website+'https://tlon.io'
license+'MIT'
==

View File

@ -27,6 +27,7 @@
%da s+(scot %da p.c)
%tas s+(scot %tas p.c)
%ud (numb p.c)
%uv s+(scot %uv p.c)
==
++ foreign-desk
|= [s=^ship =desk]

Binary file not shown.

View File

@ -679,20 +679,19 @@
=/ update-log
(~(get by update-logs) [ship term])
:- ~ :- ~ :- %noun
!>
?+ t.t.t.t.path (on-peek:def path)
~
^- update-log:store
!> ^- update-log:store
?~(update-log *update-log:store u.update-log)
::
[%latest ~]
^- (unit time)
!> ^- (unit time)
%+ biff update-log
|= =update-log:store
(bind (pry:orm-log:store update-log) head)
::
[%subset @ @ ~]
^- update-log:store
!> ^- update-log:store
?~ update-log *update-log:store
=* start i.t.t.t.t.t.path
=* end i.t.t.t.t.t.t.path

View File

@ -1,10 +1,10 @@
:~ title+'Groups'
info+'A suite of applications to communicate on Urbit'
color+0xee.5432
glob-http+['https://bootstrap.urbit.org/glob-0v4.2se6m.fvv67.nn5e8.vfrv9.mmi88.glob' 0v4.2se6m.fvv67.nn5e8.vfrv9.mmi88]
glob-http+['https://bootstrap.urbit.org/glob-0v3.mtkm8.77bad.7j793.jtnl4.pi1mm.glob' 0v3.mtkm8.77bad.7j793.jtnl4.pi1mm]
base+'landscape'
version+[1 0 11]
version+[1 1 0]
website+'https://tlon.io'
license+'MIT'
==

View File

@ -3,3 +3,8 @@
/include/config.h
/include/ca-bundle.h
/include/ivory.h
# indexing
/.cache/
compile_commands.json
tags

View File

@ -1,5 +1,6 @@
include config.mk
include $(foreach dir,$(compat),$(wildcard compat/$(dir)/*.mk))
compat_mks := $(foreach dir,$(compat),$(wildcard compat/$(dir)/*.mk))
include $(compat_mks)
jets = jets/tree.c $(wildcard jets/*/*.c)
noun = $(wildcard noun/*.c)
@ -32,7 +33,7 @@ CFLAGS := $(CFLAGS)
################################################################################
.PHONY: all test clean mrproper
.PHONY: all bench test clean mrproper
################################################################################
@ -53,7 +54,7 @@ clean:
rm -f ./tags $(all_objs) $(all_exes)
mrproper: clean
rm -f config.mk include/config.h
rm -f config.mk include/config.h compile_commands.json
################################################################################
@ -80,3 +81,15 @@ build/urbit: $(common_objs) $(daemon_objs) $(worker_objs)
tags: $(all_srcs) $(headers)
ctags $^
compile_commands.json: Makefile config.mk $(compat_mks)
@echo "[" > $@ && sep= && \
for src in $(all_srcs); do \
echo "$$sep{" >> $@; \
printf '"directory": "%s",\n' $$(pwd) >> $@; \
printf '"command": "%s",\n' "$(CC) -I./include $(CFLAGS) $$src $(CCEXTRA) -c" >> $@; \
printf '"file": "%s",\n' $$src >> $@; \
echo "}" >> $@; \
sep=','; \
done && \
echo "]" >> $@

View File

@ -0,0 +1,12 @@
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,7 @@
# There may be other macros in mdb.c of interest. You should
# read mdb.c before changing any of them.
#
-CC = gcc
+CC = cc
AR = ar
W = -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized
THREADS = -pthread

View File

@ -0,0 +1,13 @@
diff --git a/makefile b/makefile
--- a/makefile
+++ b/makefile
@@ -12,5 +12,9 @@ shared: murmur3.c murmur3.h
$(CC) -fPIC -O3 -c murmur3.c
$(CC) -shared -Wl,--export-dynamic murmur3.o -o libmurmur3.so
+static: murmur3.c murmur3.h
+ $(CC) -fPIC -O3 -c murmur3.c
+ $(AR) rcs libmurmur3.a murmur3.o
+
clean:
rm -rf example *.o *.so

View File

@ -0,0 +1,85 @@
diff --git a/build/template-FAST_INT64/Makefile b/build/template-FAST_INT64/Makefile
--- a/build/template-FAST_INT64/Makefile
+++ b/build/template-FAST_INT64/Makefile
@@ -34,28 +34,27 @@
#
#=============================================================================
-# Edit lines marked with `==>'. See "SoftFloat-source.html".
+SOURCE_DIR ?= ../../source
+SPECIALIZE_TYPE ?= 8086-SSE
-==> SOURCE_DIR ?= ../../source
-==> SPECIALIZE_TYPE ?= 8086
+SOFTFLOAT_OPTS ?= \
+ -DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 -DSOFTFLOAT_FAST_DIV32TO16 \
+ -DSOFTFLOAT_FAST_DIV64TO32
-==> SOFTFLOAT_OPTS ?= \
-==> -DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 -DSOFTFLOAT_FAST_DIV32TO16 \
-==> -DSOFTFLOAT_FAST_DIV64TO32
+DELETE = rm -f
+C_INCLUDES = -I. -I$(SOURCE_DIR)/$(SPECIALIZE_TYPE) -I$(SOURCE_DIR)/include
+COMPILE_C = \
+ cc -c -DSOFTFLOAT_FAST_INT64 $(SOFTFLOAT_OPTS) $(C_INCLUDES) -O2 -o $@
+MAKELIB = ar crs $@
+LIBNAME = libsoftfloat3
-==> DELETE = rm -f
-==> C_INCLUDES = -I. -I$(SOURCE_DIR)/$(SPECIALIZE_TYPE) -I$(SOURCE_DIR)/include
-==> COMPILE_C = \
-==> cc -c -DSOFTFLOAT_FAST_INT64 $(SOFTFLOAT_OPTS) $(C_INCLUDES) -O2 -o $@
-==> MAKELIB = ar crs $@
+OBJ = .o
+LIB = .a
-==> OBJ = .o
-==> LIB = .a
-
-==> OTHER_HEADERS =
+OTHER_HEADERS =
.PHONY: all
-all: softfloat$(LIB)
+all: $(LIBNAME)$(LIB)
OBJS_PRIMITIVES = \
s_eq128$(OBJ) \
@@ -381,11 +380,11 @@ $(OBJS_PRIMITIVES) $(OBJS_OTHERS): %$(OBJ): $(SOURCE_DIR)/%.c
$(OBJS_SPECIALIZE): %$(OBJ): $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/%.c
$(COMPILE_C) $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/$*.c
-softfloat$(LIB): $(OBJS_ALL)
+$(LIBNAME)$(LIB): $(OBJS_ALL)
$(DELETE) $@
$(MAKELIB) $^
.PHONY: clean
clean:
- $(DELETE) $(OBJS_ALL) softfloat$(LIB)
+ $(DELETE) $(OBJS_ALL) $(LIBNAME)$(LIB)
diff --git a/build/template-FAST_INT64/platform.h b/build/template-FAST_INT64/platform.h
--- a/build/template-FAST_INT64/platform.h
+++ b/build/template-FAST_INT64/platform.h
@@ -34,17 +34,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
-// Edit lines marked with `==>'. See "SoftFloat-source.html".
-
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
-==> #define LITTLEENDIAN 1
+#define LITTLEENDIAN 1
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
-==> #define INLINE inline
+#define INLINE inline
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
-==> #define THREAD_LOCAL _Thread_local
+#define THREAD_LOCAL

View File

@ -3,13 +3,18 @@ declare -a ldirs
declare -a pdirs
declare -A hdeps
sources=(../../nix/sources.json ../../nix/sources-pmnsh.json)
[ "yes" == "${build_openssl-no}" ] && sources=(../../nix/sources-openssl.json ${sources[@]})
patches=compat/$1
deriver=urbit-$1-build
markfil=.$1~
depdirs=
nixpath=${NIX_STORE-../build}
: "${MAKE:=make}"
: ${gnutar:=tar}
: ${gnumake:=make}
: ${sha256tool:=sha256sum}
export MAKE=$gnumake
# LDFLAGS doesn't like absolute paths
if [ "${nixpath:0:1}" == "/" ]
@ -71,7 +76,7 @@ buildnixdep () {
fi
mkdir -p $dir
pushd $dir
curl -fL "$url"|(tar --strip $strip -xzf - || true)
curl -fL "$url"|($gnutar --strip $strip -xzf - || true)
popd
fi
else
@ -86,7 +91,7 @@ buildnixdep () {
[ -e $patch ] && patch -d $dir -p 1 <$patch
pushd $dir
eval "$cmdprep"
eval ${MAKE} "$cmdmake"
eval $gnumake "$cmdmake"
touch $markfil
popd
fi
@ -98,13 +103,13 @@ buildnixdep () {
echo Uploading freshly built $hash-$key to binary cache...
tar -C $dir -czf $hash.tar .
local size=$(stat -c '%s' $hash.tar)
read filehash _ < <(sha256sum $hash.tar)
read filehash _ < <($sha256tool $hash.tar)
curl -fL -H "Content-Type: application/gzip" -H "Authorization: Bearer $CACHIX_AUTH_TOKEN" --data-binary @"$hash.tar" "$cache/nar"
curl -fL -H "Content-Type: application/json" -H "Authorization: Bearer $CACHIX_AUTH_TOKEN" --data-binary @- "$cache/${hash}.narinfo" <<EOF
{
"cStoreHash": "$hash",
"cStoreSuffix": "$key",
"cNarHash": "sha256:$(hex2nixbase32 $filehash)",
"cNarHash": "$sha256tool:$(hex2nixbase32 $filehash)",
"cNarSize": $size,
"cFileHash": "$filehash",
"cFileSize": $size,
@ -129,7 +134,7 @@ do
patch=$patches/$key.patch
read hash _ < <((
echo -n $json
[ -e $patch ] && cat $patch)|sha256sum)
[ -e $patch ] && cat $patch)|$sha256tool)
hash=$(hex2nixbase32 $hash)
hdeps[$key]=$hash
depdirs="$depdirs|gsub(\"\\\\.\\\\./$key\";\"\\(\$d)/$hash-$key\")"

26
pkg/urbit/configure vendored
View File

@ -64,6 +64,7 @@ do
shift
done
[ -z "${NO_GUARD_PAGE-}" ] && defmacro U3_GUARD_PAGE 1
[ -n "${MEMORY_DEBUG-}" ] && defmacro U3_MEMORY_DEBUG 1
[ -n "${MEMORY_LOG-}" ] && defmacro U3_MEMORY_LOG 1
[ -n "${CPU_DEBUG-}" ] && defmacro U3_CPU_DEBUG 1
@ -86,7 +87,7 @@ case $(tr A-Z a-z <<< $cpu) in
i686)
defmacro U3_OS_ENDIAN_little 1
;;
x86_64)
x86_64 | amd64)
defmacro U3_OS_ENDIAN_little 1
;;
arm64|aarch64)
@ -110,7 +111,7 @@ case $(tr A-Z a-z <<< $os) in
mpkgs=(cmake curl gcc jq make)
pacman -S --needed autoconf automake-wrapper libtool patch ${mpkgs[@]/#/mingw-w64-x86_64-}
export MAKE=mingw32-make
gnumake=mingw32-make
. compat/poor-mans-nix-shell.sh mingw
compat/create-include-files.sh 'stat -c %s' /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
@ -157,7 +158,28 @@ case $(tr A-Z a-z <<< $os) in
deps="$deps kvm" # XX use new compat.mk pattern
;;
*openbsd*)
# pkg_add bash automake libtool jq gtar cmake gmake libsigsegv gmp
# Tested versions:
# bash-5.1.8 automake-1.16.3 (autoconf-2.69p3) libtool-2.4.2p2
# jq-1.6p0 gtar-1.34-static cmake-3.20.3p0v0 gmake-4.3 libsigsegv-2.12
# gmp-6.2.1p0
gnutar=gtar
gnumake=gmake
sha256tool=sha256
build_openssl=yes
export AUTOCONF_VERSION="${AUTOCONF_VERSION-2.69}"
export AUTOMAKE_VERSION="${AUTOMAKE_VERSION-1.16}"
. compat/poor-mans-nix-shell.sh openbsd
compat/create-include-files.sh 'stat -f %z' /etc/ssl/cert.pem
defmacro U3_OS_bsd 1
defmacro U3_OS_no_ubc 1
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH-}"
deps="$deps aes_siv secp256k1"
compat="${compat-} posix openbsd"
;;
*)
echo "Unknown or unsupported OS: '$os'" >&2

View File

@ -251,7 +251,7 @@ _main_getopt(c3_i argc, c3_c** argv)
break;
}
case 'Y': {
u3_Host.ops_u.puk_c = _main_repath(optarg);
u3_Host.ops_u.puk_c = strdup(optarg);
break;
}
case 'Z': {
@ -681,6 +681,7 @@ u3_ve_usage(c3_i argc, c3_c** argv)
"-Y, --scry-into FILE Optional name of file (for -X)\n",
"-Z, --scry-format FORMAT Optional file format ('jam', or aura, for -X)\n",
" --no-conn Do not run control plane\n",
" --no-dock Skip binary \"docking\" on boot\n",
"\n",
"Development Usage:\n",
" To create a development ship, use a fakezod:\n",

View File

@ -56,6 +56,16 @@
# define c3_max(x, y) ( ((x) > (y)) ? (x) : (y) )
# define c3_min(x, y) ( ((x) < (y)) ? (x) : (y) )
//! Round up/down (respectively).
//!
//! @param[in] x Integer to round.
//! @param[in] n Multiple to round to. Must be power of 2.
//!
//! @return `x` rounded to the nearest multiple of `n`.
# define c3_rop(x, n) (((x) + ((n) - 1)) & (~((n) - 1)))
# define c3_rod(x, n) ((x) & ~((n) - 1))
/* Rotate.
*/
# define c3_rotw(r, x) ( ((x) << (r)) | ((x) >> (32 - (r))) )

View File

@ -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__evil c3_s4('e','v','i','l')
# define c3__ex c3_s2('e','x')
# define c3__exit c3_s4('e','x','i','t')
# define c3__eyre c3_s4('e','y','r','e')

View File

@ -25,7 +25,7 @@
/* u3a_bytes: number of bytes in memory.
*/
# define u3a_bytes (c3_w)((1 << (2 + u3a_bits)))
# define u3a_bytes (sizeof(c3_w) * u3a_words)
/* u3a_cells: number of representable cells.
*/
@ -397,36 +397,33 @@
u3a_push(const u3a_pile* pil_u)
{
u3R->cap_p += pil_u->mov_ws;
return u3a_peek(pil_u);
}
/* u3a_pile_sane(): bail on invalid road stack state.
*/
inline void
u3a_pile_sane(const u3a_pile* pil_u)
{
#ifndef U3_GUARD_PAGE
// !off means we're on a north road
//
if ( !pil_u->off_ws ) {
if( !(u3R->cap_p > u3R->hat_p) ) {
u3m_bail(c3__meme);
}
#ifdef U3_MEMORY_DEBUG
# ifdef U3_MEMORY_DEBUG
c3_assert( pil_u->top_p >= u3R->cap_p );
#endif
# endif
}
else {
if( !(u3R->cap_p < u3R->hat_p) ) {
u3m_bail(c3__meme);
}
#ifdef U3_MEMORY_DEBUG
# ifdef U3_MEMORY_DEBUG
c3_assert( pil_u->top_p <= u3R->cap_p );
#endif
# endif
}
#endif /* ifndef U3_GUARD_PAGE */
#ifdef U3_MEMORY_DEBUG
c3_assert( pil_u->rod_u == u3R );
#endif
return u3a_peek(pil_u);
}
/* u3a_pile_done(): assert valid upon completion.
@ -708,14 +705,6 @@
void (*pat_f)(u3_atom, void*),
c3_o (*cel_f)(u3_noun, void*));
/* u3a_walk_fore_unsafe(): u3a_walk_fore(), without overflow checks
*/
void
u3a_walk_fore_unsafe(u3_noun a,
void* ptr_v,
void (*pat_f)(u3_atom, void*),
c3_o (*cel_f)(u3_noun, void*));
/* u3a_string(): `a` as an on-loom c-string.
*/
c3_c*

View File

@ -84,4 +84,9 @@
void
u3e_foul(void);
/* u3e_init(): initialize page tracking.
*/
void
u3e_init(void);
#endif /* ifndef U3_EVENTS_H */

View File

@ -44,6 +44,11 @@
void
u3m_pave(c3_o nuu_o);
/* u3m_signal(): treat a nock-level exception as a signal interrupt.
*/
void
u3m_signal(u3_noun sig_l);
/* u3m_file(): load file, as atom, or bail.
*/
u3_noun

View File

@ -27,7 +27,6 @@
*top = i;
} while ( u3_nul != t );
u3a_pile_sane(&pil_u);
u3j_gate_prep(&sit_u, u3k(b));
while ( c3n == u3a_pile_done(&pil_u) ) {

View File

@ -149,9 +149,11 @@ _cqea_siv_de(c3_y* key_y,
txt_y = u3r_bytes_alloc(0, txt_w, txt);
out_y = u3a_malloc(txt_w);
ret = ( 0 != (*low_f)(txt_y, txt_w, dat_u, soc_w, key_y, iv_y, out_y) )
? u3_none
: u3nc(0, u3i_bytes(txt_w, out_y));
if ( 0 != (*low_f)(txt_y, txt_w, dat_u, soc_w, key_y, iv_y, out_y) ) {
return u3m_bail(c3__evil);
}
ret = u3nc(0, u3i_bytes(txt_w, out_y));
u3a_free(txt_y);
u3a_free(out_y);

View File

@ -984,10 +984,6 @@
u3j_site raq_u;
u3j_gate_prep(&raq_u, u3k(raq));
// check for stack overflow
//
u3a_pile_sane(&pil_u);
while ( c3n == u3a_pile_done(&pil_u) ) {
p_wag = _last_k(par_u->har, p_wag);
puq_wag = u3j_gate_slam(&raq_u, u3nc(par_u->res, puq_wag));

View File

@ -13,8 +13,6 @@ void*
u3a_pop(const u3a_pile* pil_u);
void*
u3a_push(const u3a_pile* pil_u);
void
u3a_pile_sane(const u3a_pile* pil_u);
c3_o
u3a_pile_done(const u3a_pile* pil_u);
@ -715,12 +713,13 @@ u3a_cellblock(c3_w num_w)
c3_w i_w;
if ( c3y == u3a_is_north(u3R) ) {
if ( u3R->cap_p <= (u3R->hat_p + (num_w * u3a_minimum)) ) {
if ( u3R->cap_p <= (u3R->hat_p + (num_w * u3a_minimum) + (1 << u3a_page)) ) {
return c3n;
}
else {
u3_post hat_p = u3R->hat_p;
u3_post cel_p = u3R->all.cel_p;
u3_post hat_p = u3R->hat_p;
u3R->hat_p += (num_w * u3a_minimum);
for ( i_w = 0; i_w < num_w; i_w++) {
u3_post all_p = hat_p;
@ -744,17 +743,18 @@ u3a_cellblock(c3_w num_w)
u3to(u3a_fbox, fre_p)->nex_p = cel_p;
cel_p = fre_p;
}
u3R->hat_p = hat_p;
u3R->all.cel_p = cel_p;
}
}
else {
if ( (u3R->cap_p + (num_w * u3a_minimum)) >= u3R->hat_p ) {
if ( (u3R->cap_p + (num_w * u3a_minimum) + (1 << u3a_page)) >= u3R->hat_p ) {
return c3n;
}
else {
u3_post hat_p = u3R->hat_p;
u3_post cel_p = u3R->all.cel_p;
u3_post hat_p = u3R->hat_p;
u3R->hat_p -= (num_w * u3a_minimum);
for ( i_w = 0; i_w < num_w; i_w++ ) {
u3_post all_p = (hat_p -= u3a_minimum);
@ -776,7 +776,7 @@ u3a_cellblock(c3_w num_w)
u3to(u3a_fbox, fre_p)->nex_p = cel_p;
cel_p = fre_p;
}
u3R->hat_p = hat_p;
u3R->all.cel_p = cel_p;
}
}
@ -1174,7 +1174,6 @@ _ca_take_next_north(u3a_pile* pil_u, u3_noun veb)
else {
u3a_cell* old_u = (u3a_cell*)veb_u;
_ca_take* fam_u = u3a_push(pil_u);
u3a_pile_sane(pil_u);
fam_u->hed = u3_none;
fam_u->old = veb;
@ -1230,7 +1229,6 @@ _ca_take_next_south(u3a_pile* pil_u, u3_noun veb)
else {
u3a_cell* old_u = (u3a_cell*)veb_u;
_ca_take* fam_u = u3a_push(pil_u);
u3a_pile_sane(pil_u);
fam_u->hed = u3_none;
fam_u->old = veb;
@ -2654,50 +2652,6 @@ u3a_walk_fore(u3_noun a,
else {
*top = u3t(a);
top = u3a_push(&pil_u);
u3a_pile_sane(&pil_u);
*top = u3h(a);
}
a = *top;
}
}
/* u3a_walk_fore_unsafe(): u3a_walk_fore(), without overflow checks
*/
void
u3a_walk_fore_unsafe(u3_noun a,
void* ptr_v,
void (*pat_f)(u3_atom, void*),
c3_o (*cel_f)(u3_noun, void*))
{
u3_noun* top;
u3a_pile pil_u;
// initialize stack control; push argument
//
u3a_pile_prep(&pil_u, sizeof(u3_noun));
top = u3a_push(&pil_u);
*top = a;
while ( c3n == u3a_pile_done(&pil_u) ) {
// visit an atom, then pop the stack
//
if ( c3y == u3a_is_atom(a) ) {
pat_f(a, ptr_v);
top = u3a_pop(&pil_u);
}
// vist a cell, if c3n, pop the stack
//
else if ( c3n == cel_f(a, ptr_v) ) {
top = u3a_pop(&pil_u);
}
// otherwise, push the tail and continue into the head
//
else {
*top = u3t(a);
// NB: overflow check elided here
//
top = u3a_push(&pil_u);
*top = u3h(a);
}

View File

@ -29,6 +29,11 @@
//! handled outside this module).
//! - faults are handled by dirtying the page and switching protections to
//! read/write.
//! - a guard page is initially placed in the approximate middle of the free
//! space between the heap and stack at the time of the first page fault.
//! when a fault is detected in the guard page, the guard page is recentered
//! in the free space of the current road. if the guard page cannot be
//! recentered, then memory exhaustion has occurred.
//!
//! ### updates (u3e_save())
//!
@ -71,6 +76,15 @@
#include <fcntl.h>
#include <sys/stat.h>
// Base loom offset of the guard page.
static u3p(c3_w) gar_pag_p;
//! Urbit page size in 4-byte words.
static const size_t pag_wiz_i = 1 << u3a_page;
//! Urbit page size in bytes.
static const size_t pag_siz_i = sizeof(c3_w) * pag_wiz_i;
#ifdef U3_SNAPSHOT_VALIDATION
/* Image check.
*/
@ -172,6 +186,60 @@ _ce_mapfree(void* map_v)
}
#endif
#ifdef U3_GUARD_PAGE
//! Place a guard page at the (approximate) middle of the free space between
//! the heap and stack of the current road, bailing if memory has been
//! exhausted.
static c3_i
_ce_center_guard_page(void)
{
u3p(c3_w) bot_p, top_p;
if ( !u3R ) {
top_p = u3a_outa(u3_Loom + u3a_words);
bot_p = u3a_outa(u3_Loom);
}
else if ( c3y == u3a_is_north(u3R) ) {
top_p = c3_rod(u3R->cap_p, pag_wiz_i);
bot_p = c3_rop(u3R->hat_p, pag_wiz_i);
}
else {
top_p = c3_rod(u3R->hat_p, pag_wiz_i);
bot_p = c3_rop(u3R->cap_p, pag_wiz_i);
}
if ( top_p < bot_p + pag_wiz_i ) {
fprintf(stderr,
"loom: not enough memory to recenter the guard page\r\n");
goto bail;
}
const u3p(c3_w) old_gar_p = gar_pag_p;
const c3_w mid_p = (top_p - bot_p) / 2;
gar_pag_p = bot_p + c3_rod(mid_p, pag_wiz_i);
if ( old_gar_p == gar_pag_p ) {
fprintf(stderr,
"loom: can't move the guard page to the same location"
" (base address %p)\r\n",
u3a_into(gar_pag_p));
goto bail;
}
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));
goto fail;
}
return 1;
bail:
u3m_signal(c3__meme);
fail:
return 0;
}
#endif /* ifdef U3_GUARD_PAGE */
/* u3e_fault(): handle a memory event with libsigsegv protocol.
*/
c3_i
@ -193,40 +261,38 @@ u3e_fault(void* adr_v, c3_i ser_i)
c3_assert(0);
return 0;
}
else {
c3_w off_w = u3a_outa(adr_w);
c3_w pag_w = off_w >> u3a_page;
c3_w blk_w = (pag_w >> 5);
c3_w bit_w = (pag_w & 31);
#if 0
if ( pag_w == 131041 ) {
u3l_log("dirty page %d (at %p); unprotecting %p to %p\r\n",
pag_w,
adr_v,
(u3_Loom + (pag_w << u3a_page)),
(u3_Loom + (pag_w << u3a_page) + (1 << u3a_page)));
}
#endif
u3p(c3_w) adr_p = u3a_outa(adr_w);
c3_w pag_w = adr_p >> u3a_page;
c3_w blk_w = (pag_w >> 5);
c3_w bit_w = (pag_w & 31);
if ( 0 != (u3P.dit_w[blk_w] & (1 << bit_w)) ) {
fprintf(stderr, "strange page: %d, at %p, off %x\r\n",
pag_w, adr_w, off_w);
c3_assert(0);
return 0;
}
u3P.dit_w[blk_w] |= (1 << bit_w);
if ( -1 == mprotect((void *)(u3_Loom + (pag_w << u3a_page)),
(1 << (u3a_page + 2)),
(PROT_READ | PROT_WRITE)) )
{
fprintf(stderr, "loom: fault mprotect: %s\r\n", strerror(errno));
c3_assert(0);
#ifdef U3_GUARD_PAGE
// The fault happened in the guard page.
if ( gar_pag_p <= adr_p && adr_p < gar_pag_p + pag_wiz_i ) {
if ( 0 == _ce_center_guard_page() ) {
return 0;
}
}
else
#endif /* ifdef U3_GUARD_PAGE */
if ( 0 != (u3P.dit_w[blk_w] & (1 << bit_w)) ) {
fprintf(stderr, "strange page: %d, at %p, off %x\r\n", pag_w, adr_w, adr_p);
c3_assert(0);
return 0;
}
u3P.dit_w[blk_w] |= (1 << bit_w);
if ( -1 == mprotect((void *)(u3_Loom + (pag_w << u3a_page)),
pag_siz_i,
(PROT_READ | PROT_WRITE)) )
{
fprintf(stderr, "loom: fault mprotect: %s\r\n", strerror(errno));
c3_assert(0);
return 0;
}
return 1;
}
@ -262,7 +328,7 @@ _ce_image_open(u3e_image* img_u)
}
else {
c3_d siz_d = buf_u.st_size;
c3_d pgs_d = (siz_d + (c3_d)((1 << (u3a_page + 2)) - 1)) >>
c3_d pgs_d = (siz_d + (c3_d)(pag_siz_i - 1)) >>
(c3_d)(u3a_page + 2);
if ( !siz_d ) {
@ -388,12 +454,12 @@ _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, (1 << (u3a_page + 2))) ) {
if ( -1 == read(pat_u->mem_i, mem_w, pag_siz_i) ) {
fprintf(stderr, "loom: patch read: %s\r\n", strerror(errno));
return c3n;
}
{
c3_w nug_w = u3r_mug_words(mem_w, (1 << u3a_page));
c3_w nug_w = u3r_mug_words(mem_w, pag_wiz_i);
if ( mug_w != nug_w ) {
fprintf(stderr, "loom: patch mug mismatch %d/%d; (%x, %x)\r\n",
@ -476,14 +542,8 @@ _ce_patch_write_page(u3_ce_patch* pat_u,
c3_w pgc_w,
c3_w* mem_w)
{
if ( -1 == lseek(pat_u->mem_i, (pgc_w << (u3a_page + 2)), SEEK_SET) ) {
c3_assert(0);
}
if ( (1 << (u3a_page + 2)) !=
write(pat_u->mem_i, mem_w, (1 << (u3a_page + 2))) )
{
c3_assert(0);
}
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));
}
/* _ce_patch_count_page(): count a page, producing new counter.
@ -515,8 +575,7 @@ _ce_patch_save_page(u3_ce_patch* pat_u,
c3_w* mem_w = u3_Loom + (pag_w << u3a_page);
pat_u->con_u->mem_u[pgc_w].pag_w = pag_w;
pat_u->con_u->mem_u[pgc_w].mug_w = u3r_mug_words(mem_w,
(1 << u3a_page));
pat_u->con_u->mem_u[pgc_w].mug_w = u3r_mug_words(mem_w, pag_wiz_i);
#if 0
u3l_log("protect a: page %d\r\n", pag_w);
@ -524,7 +583,7 @@ _ce_patch_save_page(u3_ce_patch* pat_u,
_ce_patch_write_page(pat_u, pgc_w, mem_w);
if ( -1 == mprotect(u3_Loom + (pag_w << u3a_page),
(1 << (u3a_page + 2)),
pag_siz_i,
PROT_READ) )
{
c3_assert(0);
@ -552,8 +611,8 @@ _ce_patch_compose(void)
u3m_water(&nwr_w, &swu_w);
nor_w = (nwr_w + ((1 << u3a_page) - 1)) >> u3a_page;
sou_w = (swu_w + ((1 << u3a_page) - 1)) >> u3a_page;
nor_w = (nwr_w + (pag_wiz_i - 1)) >> u3a_page;
sou_w = (swu_w + (pag_wiz_i - 1)) >> u3a_page;
}
#ifdef U3_SNAPSHOT_VALIDATION
@ -676,7 +735,7 @@ _ce_patch_apply(u3_ce_patch* pat_u)
//
for ( i_w = 0; i_w < pat_u->con_u->pgs_w; i_w++ ) {
c3_w pag_w = pat_u->con_u->mem_u[i_w].pag_w;
c3_w mem_w[1 << u3a_page];
c3_w mem_w[pag_wiz_i];
c3_i fid_i;
c3_w off_w;
@ -689,7 +748,7 @@ _ce_patch_apply(u3_ce_patch* pat_u)
off_w = (u3a_pages - (pag_w + 1));
}
if ( -1 == read(pat_u->mem_i, mem_w, (1 << (u3a_page + 2))) ) {
if ( -1 == read(pat_u->mem_i, mem_w, pag_siz_i) ) {
fprintf(stderr, "loom: patch apply read: %s\r\n", strerror(errno));
c3_assert(0);
}
@ -698,13 +757,13 @@ _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, (1 << (u3a_page + 2))) ) {
if ( -1 == write(fid_i, mem_w, pag_siz_i) ) {
fprintf(stderr, "loom: patch apply write: %s\r\n", strerror(errno));
c3_assert(0);
}
}
#if 0
u3l_log("apply: %d, %x\n", pag_w, u3r_mug_words(mem_w, (1 << u3a_page)));
u3l_log("apply: %d, %x\n", pag_w, u3r_mug_words(mem_w, pag_wiz_i));
#endif
}
}
@ -721,7 +780,7 @@ _ce_image_blit(u3e_image* img_u,
}
c3_w i_w;
c3_w siz_w = 1 << (u3a_page + 2);
c3_w siz_w = pag_siz_i;
lseek(img_u->fid_i, 0, SEEK_SET);
for ( i_w = 0; i_w < img_u->pgs_w; i_w++ ) {
@ -753,18 +812,18 @@ _ce_image_fine(u3e_image* img_u,
c3_ws stp_ws)
{
c3_w i_w;
c3_w buf_w[1 << u3a_page];
c3_w buf_w[pag_wiz_i];
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, (1 << (u3a_page + 2))) ) {
if ( -1 == read(img_u->fid_i, buf_w, pag_siz_i) ) {
fprintf(stderr, "loom: image fine read: %s\r\n", strerror(errno));
c3_assert(0);
}
mem_w = u3r_mug_words(ptr_w, (1 << u3a_page));
fil_w = u3r_mug_words(buf_w, (1 << u3a_page));
mem_w = u3r_mug_words(ptr_w, pag_wiz_i);
fil_w = u3r_mug_words(buf_w, pag_wiz_i);
if ( mem_w != fil_w ) {
c3_w pag_w = (ptr_w - u3_Loom) >> u3a_page;
@ -804,10 +863,10 @@ _ce_image_copy(u3e_image* fom_u, u3e_image* tou_u)
// copy pages into destination image
//
for ( i_w = 0; i_w < fom_u->pgs_w; i_w++ ) {
c3_w mem_w[1 << u3a_page];
c3_w mem_w[pag_wiz_i];
c3_w off_w = i_w;
if ( -1 == read(fom_u->fid_i, mem_w, (1 << (u3a_page + 2))) ) {
if ( -1 == read(fom_u->fid_i, mem_w, pag_siz_i) ) {
fprintf(stderr, "loom: image copy read: %s\r\n", strerror(errno));
return c3n;
}
@ -816,7 +875,7 @@ _ce_image_copy(u3e_image* fom_u, u3e_image* tou_u)
fprintf(stderr, "loom: image copy seek: %s\r\n", strerror(errno));
return c3n;
}
if ( -1 == write(tou_u->fid_i, mem_w, (1 << (u3a_page + 2))) ) {
if ( -1 == write(tou_u->fid_i, mem_w, pag_siz_i) ) {
fprintf(stderr, "loom: image copy write: %s\r\n", strerror(errno));
return c3n;
}
@ -921,11 +980,11 @@ u3e_save(void)
{
_ce_image_fine(&u3P.nor_u,
u3_Loom,
(1 << u3a_page));
pag_wiz_i);
_ce_image_fine(&u3P.sou_u,
(u3_Loom + (1 << u3a_bits) - (1 << u3a_page)),
-(1 << u3a_page));
(u3_Loom + (1 << u3a_bits) - pag_wiz_i),
-(ssize_t)pag_wiz_i);
c3_assert(u3P.nor_u.pgs_w == u3K.nor_w);
c3_assert(u3P.sou_u.pgs_w == u3K.sou_w);
@ -991,11 +1050,11 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
{
_ce_image_blit(&u3P.nor_u,
u3_Loom,
(1 << u3a_page));
pag_wiz_i);
_ce_image_blit(&u3P.sou_u,
(u3_Loom + (1 << u3a_bits) - (1 << u3a_page)),
-(1 << u3a_page));
(u3_Loom + (1 << u3a_bits) - pag_wiz_i),
-(ssize_t)pag_wiz_i);
u3l_log("boot: protected loom\r\n");
}
@ -1012,6 +1071,7 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
}
}
}
return nuu_o;
}
@ -1036,3 +1096,11 @@ u3e_foul(void)
{
memset((void*)u3P.dit_w, 0xff, sizeof(u3P.dit_w));
}
void
u3e_init(void)
{
#ifdef U3_GUARD_PAGE
_ce_center_guard_page();
#endif
}

View File

@ -361,7 +361,9 @@ _cm_signal_deep(c3_w mil_w)
// go utterly haywire.
//
if ( 0 == u3H->rod_u.bug.mer ) {
u3H->rod_u.bug.mer = u3i_string("emergency buffer");
u3H->rod_u.bug.mer = u3i_string(
"emergency buffer with sufficient space to cons the trace and bail"
);
}
if ( mil_w ) {
@ -731,6 +733,11 @@ u3m_bail(u3_noun how)
u3m_signal(how);
}
// release the emergency buffer, ensuring space for cells
//
u3z(u3R->bug.mer);
u3R->bug.mer = 0;
/* Reconstruct a correct error ball.
*/
if ( _(u3ud(how)) ) {
@ -900,6 +907,10 @@ u3m_hate(c3_w pad_w)
u3R->ear_p = u3R->cap_p;
u3m_leap(pad_w);
u3R->bug.mer = u3i_string(
"emergency buffer with sufficient space to cons the trace and bail"
);
}
/* u3m_love(): return product from leap.
@ -1290,20 +1301,32 @@ u3m_soft(c3_w mil_w,
return why;
}
else {
// don't use .^ at the top level!
//
c3_assert(1 != u3h(why));
u3_noun tax, cod, pro;
switch ( u3h(why) ) {
case 2: {
cod = c3__exit;
tax = u3t(why);
} break;
case 3: {
cod = u3h(u3t(why));
tax = u3t(u3t(why));
} break;
// don't use .^ at the top level!
//
default: {
u3m_p("invalid mot", u3h(why));
c3_assert(0);
}
}
// don't call +mook if we have no kernel
//
// This is required to soft the boot sequence.
// XX produce specific error motes instead of %2?
//
if ( 0 == u3A->roc ) {
u3_noun tax = u3t(why);
u3m_p("tone", u3h(why));
while ( u3_nul != tax ) {
u3_noun dat, mot, val;
u3x_cell(tax, &dat, &tax);
@ -1323,31 +1346,21 @@ u3m_soft(c3_w mil_w,
}
}
u3z(why);
return u3nc(c3__fail, u3_nul);
pro = u3nc(u3k(cod), u3_nul);
}
// %evil leaves no trace
//
else if ( c3__evil == cod ) {
pro = u3nc(u3k(cod), u3_nul);
}
else {
u3_noun tax, cod, pro, mok;
if ( 2 == u3h(why) ) {
cod = c3__exit;
tax = u3k(u3t(why));
}
else {
c3_assert(3 == u3h(why));
cod = u3k(u3h(u3t(why)));
tax = u3k(u3t(u3t(why)));
}
mok = u3dc("mook", 2, tax);
pro = u3nc(cod, u3k(u3t(mok)));
u3_noun mok = u3dc("mook", 2, u3k(tax));
pro = u3nc(u3k(cod), u3k(u3t(mok)));
u3z(mok);
u3z(why);
return pro;
}
u3z(why);
return pro;
}
}
@ -1796,6 +1809,10 @@ u3m_boot(c3_c* dir_c)
*/
u3m_pave(nuu_o);
/* Place the guard page.
*/
u3e_init();
/* Initialize the jet system.
*/
{

View File

@ -1444,9 +1444,9 @@ _n_push(c3_ys mov, c3_ys off, u3_noun a)
{
u3R->cap_p += mov;
// XX stack sanity-check disabled for performance
// XX switch to u3a_push()
//
#if 0
#ifndef U3_GUARD_PAGE
if ( 0 == off ) {
if( !(u3R->cap_p > u3R->hat_p) ) {
u3m_bail(c3__meme);

View File

@ -864,7 +864,7 @@ u3r_p(u3_noun a,
if ( (c3y == u3r_cell(a, &feg, &nux)) &&
(c3y == u3r_sing(feg, b)) )
{
*c = nux;
if ( c ) *c = nux;
return c3y;
}
else return c3n;
@ -1732,10 +1732,6 @@ _cr_mug_next(u3a_pile* pil_u, u3_noun veb)
u3a_cell* cel_u = (u3a_cell*)veb_u;
_cr_mugf* fam_u = u3a_push(pil_u);
// check for overflow
//
u3a_pile_sane(pil_u);
fam_u->mug_l = 0;
fam_u->cel = veb;

View File

@ -158,15 +158,9 @@ u3s_jam_fib(u3i_slab* sab_u, u3_noun a)
fib_u.bit_w = 0;
u3i_slab_init(sab_u, 0, fib_u.a_w);
// as this is a hot path, we unsafely elide overflow checks
//
// a page-fault overflow detection system is urgently needed ...
//
u3a_walk_fore_unsafe(a, &fib_u, _cs_jam_fib_atom_cb,
_cs_jam_fib_cell_cb);
u3a_walk_fore(a, &fib_u, _cs_jam_fib_atom_cb, _cs_jam_fib_cell_cb);
u3h_free(fib_u.har_p);
return fib_u.bit_w;
}
@ -270,18 +264,11 @@ u3s_jam_xeno(u3_noun a, c3_d* len_d, c3_y** byt_y)
{
_jam_xeno_t jam_u = {0};
ur_bsw_init(&jam_u.rit_u, ur_fib11, ur_fib12);
jam_u.har_p = u3h_new();
// as this is a hot path, we unsafely elide overflow checks
//
// a page-fault overflow detection system is urgently needed ...
//
u3a_walk_fore_unsafe(a, &jam_u, _cs_jam_xeno_atom,
_cs_jam_xeno_cell);
u3a_walk_fore(a, &jam_u, _cs_jam_xeno_atom, _cs_jam_xeno_cell);
u3h_free(jam_u.har_p);
return ur_bsw_done(&jam_u.rit_u, len_d, byt_y);
}
@ -360,7 +347,6 @@ _cs_cue_next(u3a_pile* pil_u,
//
else {
_cs_cue* fam_u = u3a_push(pil_u);
u3a_pile_sane(pil_u);
// NB: fam_u->wid unused in head-frame
//
@ -472,7 +458,6 @@ _cs_cue_xeno_next(u3a_pile* pil_u,
case ur_jam_cell: {
_cue_frame_t* fam_u = u3a_push(pil_u);
u3a_pile_sane(pil_u);
fam_u->ref = u3_none;
fam_u->bit_d = bit_d;
@ -731,7 +716,6 @@ _cs_cue_bytes_next(u3a_pile* pil_u,
case ur_jam_cell: {
_cue_frame_t* fam_u = u3a_push(pil_u);
u3a_pile_sane(pil_u);
fam_u->ref = u3_none;
fam_u->bit_d = bit_d;

View File

@ -0,0 +1,83 @@
#include "all.h"
/* _setup(): prepare for tests.
*/
static void
_setup(void)
{
u3m_init();
u3m_pave(c3y);
u3e_init();
}
static u3_noun
_nock_fol(u3_noun fol)
{
return u3n_nock_on(u3_nul, fol);
}
static c3_i
_test_nock_meme(void)
{
// (jam !=(=(~ =|(i=@ |-(?:(=(i ^~((bex 32))) ~ [i $(i +(i))]))))))
//
const c3_y buf_y[] = {
0xe1, 0x16, 0x1b, 0x4, 0x1b, 0xe1, 0x20, 0x58, 0x1c, 0x76, 0x4d, 0x96, 0xd8,
0x31, 0x60, 0x0, 0x0, 0x0, 0x0, 0xd8, 0x8, 0x37, 0xce, 0xd, 0x92, 0x21,
0x83, 0x68, 0x61, 0x87, 0x39, 0xce, 0x4d, 0xe, 0x92, 0x21, 0x87, 0x19, 0x8
};
u3_noun fol = u3s_cue_bytes(sizeof(buf_y), buf_y);
u3_noun gon;
c3_w i_w;
c3_i ret_i = 1;
for ( i_w = 0; i_w < 3; i_w++ ) {
gon = u3m_soft(0, _nock_fol, u3k(fol));
if ( c3n == u3r_p(gon, c3__meme, 0) ) {
u3m_p("nock meme unexpected mote", u3h(gon));
ret_i = 0;
u3z(gon);
break;
}
u3z(gon);
}
u3z(fol);
return ret_i;
}
static c3_i
_test_nock(void)
{
c3_i ret_i = 1;
if ( !_test_nock_meme() ) {
fprintf(stderr, "test nock meme: failed\r\n");
ret_i = 0;
}
return ret_i;
}
/* main(): run all test cases.
*/
int
main(int argc, char* argv[])
{
_setup();
if ( !_test_nock() ) {
fprintf(stderr, "test nock: failed\r\n");
exit(1);
}
// GC
//
u3m_grab(u3_none);
fprintf(stderr, "test nock: ok\r\n");
return 0;
}

View File

@ -63,11 +63,19 @@ u3_lmdb_init(const c3_c* pax_c, size_t siz_i)
return 0;
}
if ( (ret_w = mdb_env_open(env_u, pax_c, 0, 0664)) ) {
mdb_logerror(stderr, ret_w, "lmdb: failed to open event log");
// XX dispose env_u
//
return 0;
{
# if defined(U3_OS_no_ubc)
c3_w ops_w = MDB_WRITEMAP;
# else
c3_w ops_w = 0;
# endif
if ( (ret_w = mdb_env_open(env_u, pax_c, ops_w, 0664)) ) {
mdb_logerror(stderr, ret_w, "lmdb: failed to open event log");
// XX dispose env_u
//
return 0;
}
}
return env_u;

View File

@ -689,18 +689,14 @@ u3_disk_exit(u3_disk* log_u)
}
}
// cancel write thread
// try to cancel write thread
// shortcircuit cleanup if we cannot
//
// XX can deadlock when called from signal handler
// XX revise SIGTSTP handling
//
if ( c3y == log_u->ted_o ) {
c3_i sas_i;
do {
sas_i = uv_cancel(&log_u->req_u);
}
while ( UV_EBUSY == sas_i );
if ( (c3y == log_u->ted_o)
&& (0 > uv_cancel(&log_u->req_u)) )
{
// u3l_log("disk: unable to cleanup\r\n");
return;
}
// close database
@ -885,8 +881,11 @@ u3_disk_init(c3_c* pax_c, u3_disk_cb cb_u)
//
{
const size_t siz_i =
#if (defined(U3_CPU_aarch64) && defined(U3_OS_linux)) || defined(U3_OS_mingw)
#if defined(U3_OS_mingw)
0xf00000000;
// 500 GiB is as large as musl on aarch64 wants to allow
#elif (defined(U3_CPU_aarch64) && defined(U3_OS_linux))
0x7d00000000;
#else
0x10000000000;
#endif

View File

@ -52,6 +52,7 @@
c3_d foq_d; // forward queue size
c3_d fow_d; // forwarded count
c3_d fod_d; // forwards dropped count
c3_d bad_d; // bad ciphertext count
} sat_u; //
} u3_ames;
@ -768,51 +769,47 @@ _ames_cap_queue(u3_ames* sam_u)
}
}
/* _ames_punt_goof(): print %bail error report(s).
*/
static void
_ames_punt_goof(u3_noun lud)
{
if ( 2 == u3qb_lent(lud) ) {
u3_pier_punt_goof("hear", u3k(u3h(lud)));
u3_pier_punt_goof("crud", u3k(u3h(u3t(lud))));
}
else {
u3_noun dul = lud;
c3_w len_w = 1;
while ( u3_nul != dul ) {
u3l_log("ames: bail %u\r\n", len_w++);
u3_pier_punt_goof("ames", u3k(u3h(dul)));
dul = u3t(dul);
}
}
u3z(lud);
}
/* _ames_hear_bail(): handle packet failure.
*/
static void
_ames_hear_bail(u3_ovum* egg_u, u3_noun lud)
{
u3_ames* sam_u = (u3_ames*)egg_u->car_u;
sam_u->sat_u.fal_d++;
c3_w len_w = u3qb_lent(lud);
if ( (u3C.wag_w & u3o_verbose)
|| (0 == (sam_u->sat_u.fal_d % 1000)) )
{
_ames_punt_goof(lud);
u3l_log("ames: packet failed (%" PRIu64 " total)\n\n", sam_u->sat_u.fal_d);
if ( (1 == len_w) && c3__evil == u3h(u3h(lud)) ) {
sam_u->sat_u.bad_d++;
if ( (u3C.wag_w & u3o_verbose)
|| (0 == (sam_u->sat_u.bad_d % 100)) )
{
u3l_log("ames: heard bad crypto (%" PRIu64 " total), "
"check azimuth state\r\n",
sam_u->sat_u.bad_d);
}
}
else {
u3z(lud);
sam_u->sat_u.fal_d++;
if ( 0 == (sam_u->sat_u.fal_d % 1000) ) {
u3l_log("ames: packet failed (%" PRIu64 " total)\n\n", sam_u->sat_u.fal_d);
if ( (u3C.wag_w & u3o_verbose)
|| (0 == (sam_u->sat_u.fal_d % 100)) )
{
if ( 2 == len_w ) {
u3_pier_punt_goof("hear", u3k(u3h(lud)));
u3_pier_punt_goof("crud", u3k(u3h(u3t(lud))));
}
// !2 traces is unusual, just print the first if present
//
else if ( len_w ) {
u3_pier_punt_goof("hear", u3k(u3h(lud)));
}
u3l_log("ames: packet failed (%" PRIu64 " total)\r\n",
sam_u->sat_u.fal_d);
}
}
u3z(lud);
u3_ovum_free(egg_u);
}
@ -853,9 +850,10 @@ _ames_forward(u3_panc* pac_u, u3_noun las)
c3_c* rec_c = u3r_string(rec);
c3_y* pip_y = (c3_y*)&pac_u->ore_u.pip_w;
//NOTE ip byte order assumes little-endian
u3l_log("ames: forwarding for %s to %s from %d.%d.%d.%d:%d\n",
sen_c, rec_c,
pip_y[0], pip_y[1], pip_y[2], pip_y[3],
pip_y[3], pip_y[2], pip_y[1], pip_y[0],
pac_u->ore_u.por_s);
c3_free(sen_c); c3_free(rec_c);

View File

@ -666,6 +666,14 @@ _http_start_respond(u3_hreq* req_u,
c3_i has_len_i = 0;
while ( 0 != hed_u ) {
if ( 0x200 <= rec_u->version ) {
h2o_strtolower(hed_u->nam_c, hed_u->nam_w);
if ( 0 == strncmp(hed_u->nam_c, "connection", 10) ) {
hed_u = hed_u->nex_u;
continue;
}
}
if ( 0 == strncmp(hed_u->nam_c, "content-length", 14) ) {
has_len_i = 1;
}
@ -1608,7 +1616,7 @@ _http_init_tls(uv_buf_t key_u, uv_buf_t cer_u)
"RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS");
// enable ALPN for HTTP 2 support
#if 0 //H2O_USE_ALPN
#if H2O_USE_ALPN
{
SSL_CTX_set_ecdh_auto(tls_u, 1);
h2o_ssl_register_alpn_protocols(tls_u, h2o_http2_alpn_protocols);

View File

@ -1036,13 +1036,11 @@ u3_term_ef_ctlc(void)
{
u3_utty* uty_u = _term_main();
{
if ( uty_u->car_u ) {
u3_noun wir = u3nt(c3__term, '1', u3_nul);
u3_noun cad = u3nt(c3__belt, c3__ctl, 'c');
c3_assert( 1 == uty_u->tid_l );
c3_assert( uty_u->car_u );
_term_ovum_plan(uty_u->car_u, wir, cad);
}

View File

@ -1507,51 +1507,61 @@ u3_king_done(void)
{
uv_handle_t* han_u = (uv_handle_t*)&u3K.tim_u;
// get next binary
//
if ( c3y == u3_Host.nex_o ) {
c3_c* pac_c;
c3_c* ver_c;
// hack to ensure we only try once
if ( u3_Host.xit_i ) {
if ( c3y == u3_Host.nex_o ) {
u3l_log("vere: upgrade failed\r\n");
}
else if ( c3y == u3_Host.pep_o ) {
u3l_log("vere: prep for upgrade failed\r\n");
}
}
else {
// get next binary
//
u3_Host.nex_o = c3n;
if ( c3y == u3_Host.nex_o ) {
c3_c* pac_c;
c3_c* ver_c;
pac_c = _king_get_pace();
// hack to ensure we only try once
//
u3_Host.nex_o = c3n;
switch ( u3_king_next(pac_c, &ver_c) ) {
case -2: {
u3l_log("vere: unable to check for next version\n");
} break;
pac_c = _king_get_pace();
case -1: {
u3l_log("vere: up to date\n");
} break;
switch ( u3_king_next(pac_c, &ver_c) ) {
case -2: {
u3l_log("vere: unable to check for next version\n");
} break;
case 0: {
u3l_log("vere: next (%%%s): %s\n", pac_c, ver_c);
_king_do_upgrade(pac_c, ver_c);
c3_free(ver_c);
} break;
case -1: {
u3l_log("vere: up to date\n");
} break;
default: c3_assert(0);
case 0: {
u3l_log("vere: next (%%%s): %s\n", pac_c, ver_c);
_king_do_upgrade(pac_c, ver_c);
c3_free(ver_c);
} break;
default: c3_assert(0);
}
c3_free(pac_c);
}
else if ( c3y == u3_Host.pep_o ) {
u3l_log("vere: ready for upgrade\n");
}
c3_free(pac_c);
}
else if ( c3y == u3_Host.pep_o ) {
u3l_log("vere: ready for upgrade\n");
}
// copy binary into pier on boot
//
if ( (c3y == u3_Host.ops_u.nuu)
&& (c3y == u3_Host.ops_u.doc) )
{
// hack to ensure we only try once
// copy binary into pier on boot
//
u3_Host.ops_u.nuu = c3n;
u3_king_dock(U3_VERE_PACE);
if ( (c3y == u3_Host.ops_u.nuu)
&& (c3y == u3_Host.ops_u.doc) )
{
// hack to ensure we only try once
//
u3_Host.ops_u.nuu = c3n;
u3_king_dock(U3_VERE_PACE);
}
}
// XX hack, if pier's are still linked, we're not actually done
@ -1566,7 +1576,7 @@ u3_king_done(void)
// XX remove move
//
exit(0);
exit(u3_Host.xit_i);
}
/* u3_king_exit(): shutdown gracefully
@ -1582,10 +1592,11 @@ u3_king_exit(void)
void
u3_king_bail(void)
{
u3_Host.xit_i = 1;
_king_forall_unlink(u3_pier_bail);
_king_loop_exit();
u3_king_done();
exit(1);
exit(u3_Host.xit_i);
}
/* u3_king_grab(): gc the daemon

View File

@ -2234,6 +2234,8 @@ u3_pier_exit(u3_pier* pir_u)
void
u3_pier_bail(u3_pier* pir_u)
{
u3_Host.xit_i = 1;
// halt serf
//
if ( pir_u->god_u ) {

View File

@ -1 +1 @@
1.9
1.10

View File

@ -565,6 +565,14 @@ _serf_work(u3_serf* sef_u, c3_w mil_w, u3_noun job)
sef_u->mug_l,
vir));
}
// event rejected -- bad ciphertext
//
else if ( c3__evil == u3h(gon) ) {
sef_u->sen_d = sef_u->dun_d;
u3z(job);
return u3nt(c3__bail, gon, u3_nul);
}
// event rejected
//
else {

View File

@ -22,7 +22,7 @@ let
#
# Typically the inputs listed here also have a shell.nix in their respective
# source directory you can use directly.
inputsFrom = with pkgsLocal; [ ent herb urbit urcrypt ];
inputsFrom = with pkgsLocal; [ ent urbit urcrypt ];
# Collect the named attribute from all dependencies listed in inputsFrom.
mergeFrom = name: pkgs.lib.concatLists (pkgs.lib.catAttrs name inputsFrom);