Merge branch 'master' into jo/khan-c3

This commit is contained in:
Jōshin 2021-11-28 00:13:26 +00:00
commit a395661aad
No known key found for this signature in database
GPG Key ID: A8BE5A9A521639D0
88 changed files with 10042 additions and 711 deletions

2
.gitattributes vendored
View File

@ -1,9 +1,11 @@
bin/* filter=lfs diff=lfs merge=lfs -text
bin/*/* filter=lfs diff=lfs merge=lfs -text
pkg/arvo/**/*.css binary
pkg/arvo/app/naive/logs.eth-logs filter=lfs diff=lfs merge=lfs -text
**/package-lock.json binary merge=theirs
pkg/arvo/tmp/garden.jam filter=lfs diff=lfs merge=lfs -text
pkg/arvo/tmp/landscape.jam filter=lfs diff=lfs merge=lfs -text
pkg/arvo/tmp/base.jam filter=lfs diff=lfs merge=lfs -text
pkg/arvo/tmp/bitcoin.jam filter=lfs diff=lfs merge=lfs -text
pkg/arvo/tmp/webterm.jam filter=lfs diff=lfs merge=lfs -text

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f50aee74e4f3dd6685d36520bbc924ab94d3d47a7bc86e649882e58ab069e7dd
size 991930
oid sha256:f59ec4eaf907227a1fd64e1d54810b769b5d39f6811c6bb254b2e89de528ca04
size 1209494

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:049801d388b4cb7203854b4668826688c21089f90430bd547d276e7b59386e8d
size 5588170
oid sha256:6f48518fe49584a6532a20018f4ac4eae3817b25d85d60536a99643eb5d65b2b
size 22872573

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d8d387759fe4830fcc09a1fc7b80d52e61327d518f7eb0713697aec1819eacf7
size 5608210
oid sha256:c29577dc949ac0689ba3c97ad13b812ea6c3c6cc9d255b770d2da95fd9af84b9
size 23121802

View File

@ -41,6 +41,10 @@ in stdenvNoCC.mkDerivation {
if check && sleep 10 && check; then
header "boot success"
herb ./pier -p hood -d '+hood/exit'
while [ -f ./pier/.vere.lock ]; do
echo "waiting for pier to shut down"
sleep 5
done
else
header "boot failure"
kill $(< ./pier/.vere.lock) || true
@ -49,6 +53,8 @@ in stdenvNoCC.mkDerivation {
'';
installPhase = ''
ls
ls -a ./pier
# XX unlink khan.sock in case pier has not finished shutting down
rm -f ./pier/.urb/khan.sock
mv ./pier $out

View File

@ -588,7 +588,7 @@
::
=/ =purl
:- [sec=| por=~ host=[%& turf.next]]
[[ext=`~.udon path=/static] query=~]
[[ext=~ path=/'~debug'] query=~]
=/ =wire
(acme-wire try %validate-domain /idx/(scot %ud idx.next))
(emit (request wire purl %get ~ ~))
@ -1300,11 +1300,11 @@
~& [%failed-order-history fal.hit]
this
::
:: install privkey and cert .pem from /=home=/acme, ignores app state
:: install privkey and cert .pem from /=base=/acme, ignores app state
::TODO refactor this out of %acme, see also arvo#1151
::
%install-from-clay
=/ bas=path /(scot %p our.bow)/home/(scot %da now.bow)/acme
=/ bas=path /(scot %p our.bow)/base/(scot %da now.bow)/acme
=/ key=wain .^(wain %cx (weld bas /privkey/pem))
=/ cer=wain .^(wain %cx (weld bas /cert/pem))
(emit %pass /install %arvo %e %rule %cert `[key cer])

View File

@ -0,0 +1,182 @@
:: Azimuth JSON-RPC API
::
/- rpc=json-rpc
/+ naive,
azimuth-roll-rpc,
json-rpc,
*server,
default-agent,
verb,
dbug,
agentio
|%
::
+$ card card:agent:gall
::
+$ state-0 [%0 ~]
--
::
%+ verb |
%- agent:dbug
::
=| state-0
=* state -
::
^- agent:gall
=<
|_ =bowl:gall
+* this .
do ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
::
++ on-init
^- (quip card _this)
~& > 'init'
:_ this
[%pass /bind %arvo %e %connect [~ /v1/azimuth] dap.bowl]~
::
++ on-save !>(state)
++ on-load
|= old=vase
^- (quip card _this)
[~ this(state !<(state-0 old))]
::
++ on-poke
|= [=mark =vase]
^- (quip card _this)
|^
?> (team:title our.bowl src.bowl)
?+ mark (on-poke:def mark vase)
%handle-http-request
=+ !<([id=@ta req=inbound-request:eyre] vase)
:_ this
(handle-http-request id req)
::
%azimuth-action
=+ !<([%disconnect bind=binding:eyre] vase)
~& >>> "disconnecting at {<bind>}"
:_ this
[%pass /bind %arvo %e %disconnect bind]~
==
::
++ handle-http-request
|= [id=@ta =inbound-request:eyre]
^- (list card)
|^
=* req request.inbound-request
=* headers header-list.req
=/ req-line (parse-request-line url.req)
?. =(method.req %'POST')
:: TODO: method not supported
::
(give-simple-payload:app id not-found:gen)
?~ rpc-request=(validate-request:json-rpc body.req)
:: TODO: malformed request
::
(give-simple-payload:app id not-found:gen)
=/ [data=(list cage) response=simple-payload:http]
(process-rpc-request:do u.rpc-request)
%+ weld
(give-simple-payload:app id response)
|-
?~ data ~
:_ $(data t.data)
^- card
[%pass / %agent [our.bowl %azimuth] %poke i.data]
--
--
::
++ on-watch
|= =path
^- (quip card _this)
?> (team:title our.bowl src.bowl)
?+ path (on-watch:def path)
[%http-response *] [~ this]
==
::
++ on-arvo
|= [=wire =sign-arvo]
^- (quip card _this)
?+ sign-arvo (on-arvo:def wire sign-arvo)
[%eyre %bound *]
~? !accepted.sign-arvo
[dap.bowl 'bind rejected!' binding.sign-arvo]
[~ this]
==
::
++ on-leave on-leave:def
++ on-peek on-peek:def
++ on-agent on-agent:def
++ on-fail on-fail:def
--
::
|_ =bowl:gall
++ process-rpc-request
|= req=batch-request:rpc
^- [(list cage) simple-payload:http]
|^
?- -.req
%o
=/ [data=(unit cage) =response:rpc]
(process p.req)
[(drop data) (render response)]
::
%a
=| data=(list cage)
=| resp=(list response:rpc)
|-
?~ p.req
[(flop data) (render %batch (flop resp))]
=/ [dat=(unit cage) res=response:rpc]
(process i.p.req)
=? data ?=(^ dat) [u.dat data]
$(p.req t.p.req, resp [res resp])
==
::
++ render
|= res=response:rpc
%- json-response:gen
(response-to-json:json-rpc res)
::
++ process
|= request:rpc
=, azimuth-roll-rpc
?. ?=([%map *] params)
[~ ~(parse error:json-rpc id)]
=/ method=@tas (enkebab method)
?+ method [~ ~(method error:json-rpc id)]
%get-point `(get-point id +.params point:scry)
%get-dns `(get-dns id +.params dns:scry)
%get-naive-state `(get-naive id +.params naive-state:scry)
%get-refresh `(get-refresh id +.params refresh:scry)
==
--
::
++ scry
|%
++ point
|= =ship
.^ (unit point:naive)
%gx
(~(scry agentio bowl) %azimuth /point/(scot %p ship)/noun)
==
::
++ dns
.^ (list @t)
%gx
(~(scry agentio bowl) %azimuth /dns/noun)
==
::
++ naive-state
.^ ^state:naive
%gx
(~(scry agentio bowl) %azimuth /nas/noun)
==
::
++ refresh
.^ @dr
%gx
(~(scry agentio bowl) %azimuth /refresh/noun)
==
--
--

View File

@ -94,6 +94,7 @@
:* url.state =(%czar (clan:title our)) ~m5 ~m30
launch:contracts:azimuth
~[azimuth:contracts:azimuth]
~
(topics whos.state)
==
[%pass /wa %agent [our %eth-watcher] %poke %eth-watcher-poke args]

419
pkg/arvo/app/azimuth.hoon Normal file
View File

@ -0,0 +1,419 @@
/- eth-watcher, *dice
/+ ethereum,
azimuth,
naive,
dice,
default-agent,
verb,
dbug
:: Generally don't update the snapshot until we have clay tombstoning.
:: To update, run:
:: =e -build-file %/lib/ethereum/hoon
:: =l .^((list event-log:rpc:e) %gx /=azimuth=/logs/noun)
:: */app/azimuth/logs/eth-logs &eth-logs l
::
/* snap %eth-logs /app/azimuth/logs/eth-logs
::
=/ last-snap :: maybe just use the last one?
%+ roll `(list event-log:rpc:ethereum)`snap ::~
|= [log=event-log:rpc:ethereum last=@ud]
?~ mined.log
last
(max block-number.u.mined.log last)
::
=, jael
|%
+$ app-state
$: %2
url=@ta
=net
whos=(set ship)
nas=^state:naive
own=owners
spo=sponsors
logs=(list =event-log:rpc:ethereum)
==
::
+$ poke-data
$% :: %listen
::
[%listen whos=(list ship) =source:jael]
:: %watch: configure node url and network
::
[%watch url=@ta =net]
==
::
+$ tagged-diff [=id:block diff:naive]
+$ card card:agent:gall
:: TODO: add to state?
::
++ refresh ~m5
--
::
=| state=app-state
%- agent:dbug
%+ verb |
^- agent:gall
=<
|_ =bowl:gall
+* this .
do ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
::
++ on-init
^- (quip card _this)
=: net.state %default
logs.state snap
url.state 'http://eth-mainnet.urbit.org:8545'
==
:_ this
?: .^(? %j /(scot %p our.bowl)/fake/(scot %da now.bowl))
~
:~ :* %pass /old-tracker %agent [our.bowl %hood]
%poke %kiln-nuke !>([%azimuth-tracker %|])
==
::
[%pass /init %arvo %b %wait now.bowl]
==
::
++ on-save !>(state)
++ on-load
|= old=vase
^- (quip card _this)
|^
=+ !<(old-state=app-states old)
=? old-state ?=(%0 -.old-state)
=, old-state
[%1 url net whos nas own *sponsors logs]
=^ cards-1 old-state
?. ?=(%1 -.old-state)
`old-state
%- %- slog :_ ~
leaf+"azimuth: loading snapshot with {<(lent logs.old-state)>} events"
=. +.state +.old-state
=^ cards state
(%*(run-logs do nas.state *^state:naive) logs.state)
[(jael-update:do (to-udiffs:do cards)) state]
?> ?=(%2 -.old-state)
[cards-1 this(state old-state)]
::
++ app-states $%(state-0 state-1 app-state)
::
+$ state-1
$: %1
url=@ta
=net
whos=(set ship)
nas=^state:naive
own=owners
spo=sponsors
logs=(list =event-log:rpc:ethereum)
==
::
++ state-0
$: %0
url=@ta
=net
whos=(set ship)
nas=^state:naive
own=owners
logs=(list =event-log:rpc:ethereum)
==
--
::
++ on-poke
|= [=mark =vase]
^- (quip card _this)
?: =(%noun mark)
?+ q.vase !!
%rerun
~& [%rerunning (lent logs.state)]
=. points.nas.state ~
=. own.state ~
=^ * state (run-logs:do logs.state)
`this
::
%resub
:_ this :_ ~
:* %pass /eth-watcher %agent [our.bowl %eth-watcher]
%watch /logs/[dap.bowl]
==
::
%resnap
=. logs.state snap
$(mark %noun, vase !>(%rerun))
==
?: =(%eth-logs mark)
=+ !<(logs=(list event-log:rpc:ethereum) vase)
=. logs.state logs
$(mark %noun, vase !>(%rerun))
::
?. ?=(%azimuth-poke mark)
(on-poke:def mark vase)
=+ !<(poke=poke-data vase)
?- -.poke
%listen
[[%pass /lo %arvo %j %listen (silt whos.poke) source.poke]~ this]
::
%watch
:: TODO: only wipe out state when switching networks?
:: ?: =(net.state net.poke)
:: [~ this]
=: nas.state *^state:naive
net.state net.poke
url.state url.poke
own.state ~
spo.state ~
logs.state ?:(?=(%default net.poke) snap ~)
==
[start:do this]
==
::
++ on-watch
|= =path
^- (quip card _this)
?< =(/sole/drum path)
?: =(/event path)
:_ this
[%give %fact ~ %naive-state !>([nas.state own.state spo.state])]~
=/ who=(unit ship)
?~ path ~
?: ?=([@ ~] path) ~
`(slav %p i.path)
=. whos.state
?~ who
~
(~(put in whos.state) u.who)
^- (quip card _this)
:: Slow to recalculate all the diffs, but this is necessary to make
:: sure Jael gets the updates from the snapshot
::
%- %- slog :_ ~
leaf+"azimuth: loading snapshot with {<(lent logs.state)>} events"
=^ snap-cards state
(%*(run-logs do nas.state *^state:naive) logs.state)
[(weld (jael-update:do (to-udiffs:do snap-cards)) start:do) this]
::
++ on-leave on-leave:def
++ on-peek
|= =path
^- (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)
[%x %point @ ~] ``noun+(point i.t.t.path)
==
::
++ point
|= wat=@t
^- vase
!> ^- (unit point:naive)
?~ ship=(rush wat ;~(pfix sig fed:ag))
~
(get:orm:naive points.nas.state u.ship)
--
::
++ on-agent
|= [=wire =sign:agent:gall]
^- (quip card _this)
?. ?=([%eth-watcher ~] wire)
(on-agent:def wire sign)
?. ?=(%fact -.sign)
(on-agent:def wire sign)
?. ?=(%eth-watcher-diff p.cage.sign)
(on-agent:def wire sign)
=+ !<(diff=diff:eth-watcher q.cage.sign)
?: ?=(%disavow -.diff)
[(jael-update:do [*ship id.diff %disavow ~]~) this]
::
=. logs.state
?- -.diff
:: %history loglist.diff
%history (welp logs.state loglist.diff)
%logs (welp logs.state loglist.diff)
==
=? nas.state ?=(%history -.diff) *^state:naive
=^ effects state (run-logs:do loglist.diff)
::
:_ this
%+ weld
(event-update:do effects)
(jael-update:do (to-udiffs:do effects))
::
++ on-arvo
|= [=wire =sign-arvo]
?. &(=(/init wire) ?=(%wake +<.sign-arvo))
(on-arvo:def wire sign-arvo)
?^ error.sign-arvo
%- (slog 'azimuth: failed to initialize!' ~)
`this
:_ this
:~ :* %pass /eth-watcher %agent [our.bowl %eth-watcher]
%watch /logs/[dap.bowl]
==
::
[%pass /lo %arvo %j %listen ~ [%| dap.bowl]]
==
::
++ on-fail on-fail:def
--
|_ =bowl:gall
:: TODO: maybe flop the endianness here so metamask signs it in normal
:: order?
::
++ verifier
^- ^verifier:naive
|= [dat=octs v=@ r=@ s=@]
?: (gth v 3) ~ :: TODO: move to jet
=/ result
%- mule
|.
=, secp256k1:secp:crypto
%- address-from-pub:key:ethereum
%- serialize-point
(ecdsa-raw-recover (keccak-256:keccak:crypto dat) v r s)
?- -.result
%| ~
%& `p.result
==
::
++ topics
|= ships=(set ship)
^- (list ?(@ux (list @ux)))
~
::
++ data-to-hex
|= data=@t
?~ data *@ux
?: =(data '0x') *@ux
(hex-to-num:ethereum data)
::
++ run-logs
|= [logs=(list event-log:rpc:ethereum)]
^- (quip tagged-diff _state)
=+ net=(get-network net.state)
=| effects=(list tagged-diff)
!. :: saves 700MB replaying snapshot
=- =/ res (mule -)
?- -.res
%& p.res
%| (mean 'naive: fail!' p.res)
==
|.
?~ logs
[(flop effects) state]
?~ mined.i.logs
$(logs t.logs)
=/ [raw-effects=effects:naive new-nas=_nas.state]
=/ =^input:naive
:- block-number.u.mined.i.logs
?: =(azimuth.net address.i.logs)
=/ data (data-to-hex data.i.logs)
=/ =event-log:naive
[address.i.logs data topics.i.logs]
[%log event-log]
?~ input.u.mined.i.logs
[%bat *@]
[%bat u.input.u.mined.i.logs]
(%*(. naive lac |) verifier chain-id.net nas.state input)
:: TODO: move to /lib/dice ?
::
=/ [new-own=_own.state new-spo=_spo.state]
=< [own spo]
?. =(azimuth.net address.i.logs)
%: apply-effects:dice
chain-id.net
raw-effects
nas.state
own.state
spo.state
==
%: update-indices:dice
raw-effects
nas.state
new-nas
own.state
spo.state
==
=: nas.state new-nas
own.state new-own
spo.state new-spo
==
=/ effects-1
=/ =id:block [block-hash block-number]:u.mined.i.logs
(turn raw-effects |=(=diff:naive [id diff]))
=. effects (welp (flop effects-1) effects)
$(logs t.logs)
::
++ to-udiffs
|= effects=(list tagged-diff)
^- =udiffs:point
%+ murn effects
|= tag=tagged-diff
^- (unit [=ship =udiff:point])
?. ?=(%point +<.tag) ~
?+ +>+<.tag ~
%rift `[ship.tag id.tag %rift rift.tag]
%sponsor `[ship.tag id.tag %spon sponsor.tag]
%keys
=/ =pass
(pass-from-eth:azimuth 32^crypt.keys.tag 32^auth.keys.tag suite.keys.tag)
`[ship.tag id.tag %keys life.keys.tag suite.keys.tag pass]
==
::
++ jael-update
|= =udiffs:point
^- (list card)
:: ?: & ~ :: XX
:- [%give %fact ~[/] %azimuth-udiffs !>(udiffs)]
|- ^- (list card)
?~ udiffs
~
=/ =path /(scot %p ship.i.udiffs)
:: Should really give all diffs involving each ship at the same time
::
:- [%give %fact ~[path] %azimuth-udiffs !>(~[i.udiffs])]
$(udiffs t.udiffs)
::
++ event-update
|= effects=(list tagged-diff)
^- (list card)
%+ murn effects
|= tag=tagged-diff
^- (unit card)
?. |(?=(%tx +<.tag) ?=(%point +<.tag)) ~
%- some
^- card
[%give %fact ~[/event] %naive-diffs !>(+.tag)]
::
++ get-network
|= =net
^- [azimuth=@ux naive=@ux chain-id=@ launch=@]
=< [azimuth naive chain-id launch]
=, azimuth
?- net
%mainnet mainnet-contracts
%ropsten ropsten-contracts
%local local-contracts
%default contracts
==
::
++ start
^- (list card)
=+ net=(get-network net.state)
=/ args=vase !>
:+ %watch /[dap.bowl]
^- config:eth-watcher
:* url.state =(%czar (clan:title our.bowl)) refresh ~h30
(max launch.net ?:(=(net.state %default) last-snap 0))
~[azimuth.net]
~[naive.net]
(topics whos.state)
==
[%pass /wa %agent [our.bowl %eth-watcher] %poke %eth-watcher-poke args]~
--

Binary file not shown.

View File

@ -8,7 +8,7 @@
=> |%
+$ card card:agent:gall
+$ app-state
$: %4
$: %5
dogs=(map path watchdog)
==
::
@ -23,7 +23,7 @@
==
::
:: history: newest block first, oldest event first
+$ history (list loglist)
+$ history (list loglist)
--
::
:: Helpers
@ -112,14 +112,16 @@
::
=? old-state ?=(%3 -.old-state)
%- (slog leaf+"upgrading eth-watcher from %3" ~)
^- app-state
^- app-state-4
%= old-state
- %4
dogs
%- ~(run by dogs.old-state)
|= dog=watchdog-3
^- watchdog-4
%= dog
-
^- config-4
=, -.dog
[url eager refresh-rate (mul refresh-rate 6) from contracts topics]
::
@ -129,10 +131,80 @@
==
==
::
[cards-1 this(state ?>(?=(%4 -.old-state) old-state))]
=? old-state ?=(%4 -.old-state)
%- (slog leaf+"upgrading eth-watcher from %4" ~)
^- app-state
%= old-state
- %5
dogs
%- ~(run by dogs.old-state)
|= dog=watchdog-4
%= dog
-
=, -.dog
[url eager refresh-rate timeout-time from contracts ~ topics]
::
pending-logs-4
%- ~(run by pending-logs-4.dog)
|= =loglist-4
%+ turn loglist-4
|= =event-log-4
event-log-4(mined ?~(mined.event-log-4 ~ `mined.event-log-4))
::
history-4
%+ turn history-4.dog
|= =loglist-4
%+ turn loglist-4
|= =event-log-4
event-log-4(mined ?~(mined.event-log-4 ~ `mined.event-log-4))
==
==
::
[cards-1 this(state ?>(?=(%5 -.old-state) old-state))]
::
+$ app-states
$%(app-state-0 app-state-1 app-state-2 app-state-3 app-state)
$%(app-state-0 app-state-1 app-state-2 app-state-3 app-state-4 app-state)
::
+$ app-state-4
$: %4
dogs=(map path watchdog-4)
==
::
+$ watchdog-4
$: config-4
running=(unit [since=@da =tid:spider])
=number:block
=pending-logs-4
=history-4
blocks=(list block)
==
::
+$ config-4
$: url=@ta
eager=?
refresh-rate=@dr
timeout-time=@dr
from=number:block
contracts=(list address:ethereum)
=topics
==
+$ pending-logs-4 (map number:block loglist-4)
+$ history-4 (list loglist-4)
+$ loglist-4 (list event-log-4)
+$ event-log-4
$: $= mined %- unit
$: log-index=@ud
transaction-index=@ud
transaction-hash=@ux
block-number=@ud
block-hash=@ux
removed=?
==
::
address=@ux
data=@t
topics=(lest @ux)
==
::
+$ app-state-3
$: %3
@ -143,8 +215,8 @@
$: config-3
running=(unit =tid:spider)
=number:block
=pending-logs
=history
=pending-logs-4
=history-4
blocks=(list block)
==
::
@ -171,8 +243,8 @@
$: config-1
running=(unit =tid:spider)
=number:block
=pending-logs
=history
=pending-logs-4
=history-4
blocks=(list block)
==
::
@ -193,8 +265,8 @@
$: config-0
running=(unit =tid:spider)
=number:block
=pending-logs
=history
=pending-logs-4
=history-4
blocks=(list block)
==
::
@ -390,9 +462,9 @@
++ release-logs
|= [=path dog=watchdog]
^- (quip card watchdog)
?: (lth number.dog 30)
?: (lth number.dog 0) :: TODO: 30!
`dog
=/ rel-number (sub number.dog 30)
=/ rel-number (sub number.dog 0) :: TODO: 30!
=/ numbers=(list number:block) ~(tap in ~(key by pending-logs.dog))
=. numbers (sort numbers lth)
=^ logs=(list event-log:rpc:ethereum) dog

View File

@ -212,6 +212,7 @@
public:mainnet-contracts
~[azimuth delegated-sending]:mainnet-contracts
~
~
==
::
:: see also comment in +setup-cards

View File

@ -0,0 +1,365 @@
:: Roller JSON-RPC API
::
/- rpc=json-rpc, *dice
/+ naive,
azimuth-roll-rpc,
json-rpc,
*server,
default-agent,
verb,
dbug,
agentio
|%
::
+$ card card:agent:gall
::
+$ state-0 [%0 ~]
--
::
%+ verb |
%- agent:dbug
::
=| state-0
=* state -
::
^- agent:gall
=<
|_ =bowl:gall
+* this .
do ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
::
++ on-init
^- (quip card _this)
~& > 'init'
:_ this
[%pass /bind %arvo %e %connect [~ /v1/roller] dap.bowl]~
::
++ on-save !>(state)
++ on-load
|= old=vase
^- (quip card _this)
[~ this(state !<(state-0 old))]
::
++ on-poke
|= [=mark =vase]
^- (quip card _this)
|^
?> (team:title our.bowl src.bowl)
?+ mark (on-poke:def mark vase)
%handle-http-request
=+ !<([id=@ta req=inbound-request:eyre] vase)
:_ this
(handle-http-request id req)
::
%azimuth-action
=+ !<([%disconnect bind=binding:eyre] vase)
~& >>> "disconnecting at {<bind>}"
:_ this
[%pass /bind %arvo %e %disconnect bind]~
==
::
++ handle-http-request
|= [id=@ta =inbound-request:eyre]
^- (list card)
|^
=* req request.inbound-request
=* headers header-list.req
=/ req-line (parse-request-line url.req)
?. =(method.req %'POST')
:: TODO: method not supported
::
(give-simple-payload:app id not-found:gen)
?~ rpc-request=(validate-request:json-rpc body.req)
:: TODO: malformed request
::
(give-simple-payload:app id not-found:gen)
=/ [data=(list cage) response=simple-payload:http]
(process-rpc-request:do u.rpc-request)
%+ weld
(give-simple-payload:app id response)
|-
?~ data ~
:_ $(data t.data)
^- card
[%pass / %agent [our.bowl %roller] %poke i.data]
--
--
::
++ on-watch
|= =path
^- (quip card _this)
?> (team:title our.bowl src.bowl)
?+ path (on-watch:def path)
[%http-response *] [~ this]
==
::
++ on-arvo
|= [=wire =sign-arvo]
^- (quip card _this)
?+ sign-arvo (on-arvo:def wire sign-arvo)
[%eyre %bound *]
~? !accepted.sign-arvo
[dap.bowl 'bind rejected!' binding.sign-arvo]
[~ this]
==
::
++ on-leave on-leave:def
++ on-peek on-peek:def
++ on-agent on-agent:def
++ on-fail on-fail:def
--
::
|_ =bowl:gall
++ process-rpc-request
|= req=batch-request:rpc
^- [(list cage) simple-payload:http]
|^
?- -.req
%o
=/ [data=(unit cage) =response:rpc]
(process p.req)
[(drop data) (render response)]
::
%a
=| data=(list cage)
=| resp=(list response:rpc)
|-
?~ p.req
[(flop data) (render %batch (flop resp))]
=/ [dat=(unit cage) res=response:rpc]
(process i.p.req)
=? data ?=(^ dat) [u.dat data]
$(p.req t.p.req, resp [res resp])
==
::
++ render
|= res=response:rpc
%- json-response:gen
(response-to-json:json-rpc res)
::
++ process
|= request:rpc
?. ready:scry
:: TODO: move to lib
::
`[%error id '-32003' 'Roller is not ready']
=, azimuth-roll-rpc
?. ?=([%map *] params)
[~ ~(parse error:json-rpc id)]
=/ method=@tas (enkebab method)
?: ?=(l2-tx method)
(process-rpc id +.params method over-quota:scry)
?+ method [~ ~(method error:json-rpc id)]
%get-point `(get-point id +.params point:scry)
%get-ships `(get-ships id +.params ships:scry)
%cancel-transaction (cancel-tx id +.params)
%get-spawned `(get-spawned id +.params spawned:scry)
%get-unspawned `(get-spawned id +.params unspawned:scry)
%spawns-remaining `(spawns-remaining id +.params unspawned:scry)
%get-sponsored-points `(sponsored-points id +.params sponsored:scry)
%get-owned-points `(get-ships id +.params owned:scry)
%get-transferring-for `(get-ships id +.params transfers:scry)
%get-manager-for `(get-ships id +.params manager:scry)
%get-voting-for `(get-ships id +.params voting:scry)
%get-spawning-for `(get-ships id +.params spawning:scry)
%get-all-pending `(all:pending id +.params all:pending:scry)
%get-pending-by-ship `(ship:pending id +.params ship:pending:scry)
%get-pending-by-address `(addr:pending id +.params addr:pending:scry)
%get-pending-tx `(hash:pending id +.params hash:pending:scry)
%get-transaction-status `(status id +.params tx-status:scry)
%when-next-batch `(next-batch id +.params next-batch:scry)
%get-nonce `(nonce id +.params nonce:scry)
%get-history `(history id +.params addr:history:scry)
%get-roller-config `(get-config id +.params config:scry)
%prepare-for-signing `(hash-transaction id +.params chain:scry | &)
%get-unsigned-tx `(hash-transaction id +.params chain:scry & |)
%get-predicted-state `(get-naive id +.params predicted:scry)
%hash-raw-transaction `(hash-raw-transaction id +.params)
:: TODO: deprecated, remove (used together with personal_sign)
::
%hash-transaction ::`(hash-transaction id +.params chain:scry | &)
`(hash-transaction id +.params chain:scry & |)
==
--
::
++ scry
|%
++ point
|= =ship
.^ (unit point:naive)
%gx
(~(scry agentio bowl) %roller /point/(scot %p ship)/noun)
==
::
++ ships
|= =address:naive
.^ (list ship)
%gx
(~(scry agentio bowl) %roller /ships/(scot %ux address)/noun)
==
::
++ spawned
|= =ship
.^ (list @p)
%gx
(~(scry agentio bowl) %roller /spawned/(scot %p ship)/noun)
==
::
++ unspawned
|= =ship
.^ (list @p)
%gx
(~(scry agentio bowl) %roller /unspawned/(scot %p ship)/noun)
==
::
++ owned
|= =address:naive
.^ (list ship)
%gx
(~(scry agentio bowl) %roller /owned/(scot %ux address)/noun)
==
::
++ sponsored
|= parent=ship
.^ [residents=(list ship) requests=(list ship)]
%gx
(~(scry agentio bowl) %roller /sponsored/(scot %p parent)/noun)
==
::
++ transfers
|= =address:naive
.^ (list ship)
%gx
(~(scry agentio bowl) %roller /transfers/(scot %ux address)/noun)
==
::
++ manager
|= =address:naive
.^ (list ship)
%gx
(~(scry agentio bowl) %roller /manager/(scot %ux address)/noun)
==
::
++ voting
|= =address:naive
.^ (list ship)
%gx
(~(scry agentio bowl) %roller /voting/(scot %ux address)/noun)
==
::
++ spawning
|= =address:naive
.^ (list ship)
%gx
(~(scry agentio bowl) %roller /spawning/(scot %ux address)/noun)
==
::
++ pending
|%
++ all
.^ (list pend-tx)
%gx
(~(scry agentio bowl) %roller /pending/noun)
==
::
++ ship
|= =^ship
.^ (list pend-tx)
%gx
(~(scry agentio bowl) %roller /pending/(scot %p ship)/noun)
==
::
++ addr
|= =address:naive
.^ (list pend-tx)
%gx
%+ ~(scry agentio bowl) %roller
/pending/[(scot %ux address)]/noun
==
::
++ hash
|= keccak=@ux
.^ (unit pend-tx)
%gx
%+ ~(scry agentio bowl) %roller
/pending-tx/[(scot %ux keccak)]/noun
==
--
::
++ history
|%
++ addr
|= =address:naive
.^ (list hist-tx)
%gx
(~(scry agentio bowl) %roller /history/(scot %ux address)/noun)
==
--
::
++ tx-status
|= keccak=@ux
.^ ^tx-status
%gx
(~(scry agentio bowl) %roller /tx/(scot %ux keccak)/status/noun)
==
::
++ next-batch
.^ time
%gx
(~(scry agentio bowl) %roller /next-batch/noun)
==
::
++ nonce
|= [=ship =proxy:naive]
.^ (unit @)
%gx
%+ ~(scry agentio bowl)
%roller
/nonce/(scot %p ship)/[proxy]/noun
==
::
++ config
^- [azimuth-config roller-config]
:- refresh
.^ roller-config
%gx
%+ ~(scry agentio bowl)
%roller
/config/noun
==
::
++ chain
.^ @
%gx
%+ ~(scry agentio bowl)
%roller
/chain-id/noun
==
::
++ predicted
.^ ^state:naive
%gx
(~(scry agentio bowl) %roller /predicted/noun)
==
::
++ refresh
.^ @dr
%gx
(~(scry agentio bowl) %azimuth /refresh/noun)
==
::
++ over-quota
|= =ship
.^ ?
%gx
(~(scry agentio bowl) %roller /over-quota/(scot %p ship)/atom)
==
::
++ ready
.^ ?
%gx
(~(scry agentio bowl) %roller /ready/atom)
==
--
--

1338
pkg/arvo/app/roller.hoon Normal file

File diff suppressed because it is too large Load Diff

View File

@ -50,7 +50,7 @@
|=(c=@tD `@tD`?:(=('/' c) '-' c))
=/ sing=card
:+ %pass /build/mar/[mak]
[%arvo %c %warp our.bowl %home ~ %sing %b da+now.bowl /[mak]]
[%arvo %c %warp our.bowl q.byk.bowl ~ %sing %b da+now.bowl /[mak]]
%_ $
paz t.paz
fex [sing fex]
@ -72,7 +72,7 @@
$(daz t.daz)
=/ sing=card
:+ %pass /build/app/[i.daz]
[%arvo %c %warp our.bowl %home ~ %sing %a da+now.bowl dap-pax]
[%arvo %c %warp our.bowl q.byk.bowl ~ %sing %a da+now.bowl dap-pax]
%_ $
daz t.daz
fex [sing fex]
@ -92,7 +92,7 @@
$(paz t.paz)
=/ sing=card
:+ %pass build+i.paz
[%arvo %c %warp our.bowl %home ~ %sing %a da+now.bowl i.paz]
[%arvo %c %warp our.bowl q.byk.bowl ~ %sing %a da+now.bowl i.paz]
%_ $
paz t.paz
fex [sing fex]

View File

@ -1,5 +1,5 @@
:~ %acme
%azimuth-tracker
%azimuth
%dbug
%dojo
%eth-watcher

View File

@ -10,5 +10,5 @@
[leaf+(scow %ud block)]~
.^ @ud
%gx
/(scot %p our)/eth-watcher/(scot %da now)/block/azimuth-tracker/noun
/(scot %p our)/eth-watcher/(scot %da now)/block/azimuth/noun
==

View File

@ -0,0 +1,4 @@
::
:- %say
|= [* [=binding:eyre ~] ~]
[%azimuth-action %disconnect binding]

View File

@ -1,4 +0,0 @@
:: Kick azimuth-tracker
:- %say
|= *
[%azimuth-tracker-poke %listen ~ %| %azimuth-tracker]

View File

@ -1,4 +0,0 @@
:: Change node url for azimuth-tracker
:- %say
|= [* [url=@ta ~] ~]
[%azimuth-tracker-poke %watch url]

View File

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

View File

@ -1,4 +1,5 @@
:: Add a source for azimuth-tracker
:: Add a source for azimuth
::
=> |%
+$ src
$% [%ship =ship ~]
@ -12,4 +13,4 @@
%ship [%& ship.src]
%app [%| term.src]
==
[%azimuth-tracker-poke %listen whos source]
[%azimuth-poke %listen whos source]

View File

@ -0,0 +1,4 @@
:: Change node url and network for azimuth
:- %say
|= [* [url=@ta net=?(%mainnet %ropsten %local %default) ~] ~]
[%azimuth-poke %watch url net]

View File

@ -8,7 +8,13 @@
::
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[arg=[syd=desk lab=@tas ~] ~]
[arg=[syd=desk lab=@tas ~] aeon=aeon:clay ~]
==
:: handle optional aeon
::
=/ aey=(unit aeon:clay)
?: =(0 aeon)
~
`aeon
:- %kiln-label
[syd lab]:arg
[syd.arg lab.arg aey]

View File

@ -10,7 +10,7 @@
:- desk
%+ roll arg
=| =rein:hood
|: [*[on=? =dude:gall] rein(liv liv)]
|: [*[on=? =dude:gall] rein=rein(liv liv)]
?: on
rein(add (~(put in add.rein) dude))
rein(sub (~(put in sub.rein) dude))

View File

@ -10,8 +10,9 @@
|= $: [now=@da eny=@uvJ bec=beak]
[arg=[@ $@(~ [@ ~])] ~]
==
:- %drum-start
?> ((sane %tas) -.arg)
?@ +.arg [q.bec -.arg]
?> ((sane %tas) +<.arg)
[-.arg +<.arg]
=/ [des=@tas dap=@tas]
?> ((sane %tas) -.arg)
?@ +.arg [q.bec -.arg]
?> ((sane %tas) +<.arg)
[-.arg +<.arg]
[%kiln-rein des & [dap ~ ~] ~]

View File

@ -0,0 +1,5 @@
:: Submits a new L2 batch with all pending transactions
::
:- %say
|= *
[%roller-action %commit ~]

View File

@ -0,0 +1,7 @@
:: Updates a configuration option for /app/roller
::
/- *dice
::
:- %say
|= [* [=config ~] ~]
[%roller-action %config config]

View File

@ -0,0 +1,4 @@
::
:- %say
|= [* [url=@t net=?(%mainnet %ropsten %local) ~] ~]
[%roller-action %config %endpoint url net]

View File

@ -0,0 +1,4 @@
::
:- %say
|= [* [freq=@dr ~] ~]
[%roller-action %config %frequency freq]

View File

@ -0,0 +1,5 @@
:: Configures /app/roller to listen to a local Ethereum node
::
:- %say
|= *
[%roller-action %config %endpoint 'http://0.0.0.0:8545' %local]

View File

@ -0,0 +1,5 @@
:: Modifies the number of txs a ship is allowed to send, per unit of time (slice)
::
:- %say
|= [* [quota=@ud ~] ~]
[%roller-action %config %quota quota]

View File

@ -0,0 +1,10 @@
:: Configures /app/roller to listen to a Ropsten Infura node
::
:- %say
|= *
:* %roller-action
%config
%endpoint
'https://ropsten.infura.io/v3/2599df54929b47099bda360958d75aaf'
%ropsten
==

View File

@ -0,0 +1,5 @@
:: Loads a private key into the roller and retrieves its L1 nonce
::
:- %say
|= [* [pk=@t ~] ~]
[%roller-action %config %setkey pk]

View File

@ -0,0 +1,5 @@
:: Modifies the unit of time (e.g. ~d1) for each ship's quota
::
:- %say
|= [* [slice=@dr ~] ~]
[%roller-action %config %slice slice]

View File

@ -1,4 +1,3 @@
/- *bill
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[=desk ~]
@ -11,5 +10,5 @@
:~ 'sys.kelvin:'
leaf/"[%{<lal>} %{<num>}]"
'desk.bill:'
(sell !>(.^(bill cx+(weld pax /desk/bill))))
(sell !>(.^((list dude:gall) cx+(weld pax /desk/bill))))
==

56
pkg/arvo/gen/tx.hoon Normal file
View File

@ -0,0 +1,56 @@
:: ethereum.request({method: 'personal_sign', params: ['tx',count]}).then(console.log)
:: ethereum.request({method: 'eth_sendTransaction', params: [{from: count, gasPrice: '0x2540be400', to: '0xb58101cd3bbbcc6fa40bcdb04bb71623b5c7d39b', gas: '0x10000', data: 'batch', chainId: '0x3'}]}).then(console.log)
::
/+ eth=ethereum
/= tt /tests/lib/naive
|%
:: Generated by running these commands after modifying eth-sig-util
:: such that TypedDataUtils.sign returns the domain separator instead
:: of continuing to sign. I think this is basically EIP-712
:: compatible, but it also doesn't matter much because we're not
:: compatible with the whole EIP anyway. The main thing is to be
:: distinct from other names, versions, and chainIds.
::
:: Alter chainId as necessary
::
:: sig = require('eth-sig-util')
:: domain = [{ name: "name", type: "string" },{ name: "version", type: "string" },{ name: "chainId", type: "uint256" }]
:: domainData = {name: "Urbit", version: "1", chainId: 0x1}
:: sig.TypedDataUtils.sign({domain: domainData, types: {EIP712Domain: domain}, primaryType: 'EIP712Domain'}, true).toString('hex')
::
++ domain-separator ropsten-separator
++ mainnet-separator
0x30e4.9840.ca87.cf16.b969.f49e.4b8d.488f.
08a6.88f9.43f5.b07e.7671.6c0d.b2fb.b44b
++ ropsten-separator
0x77e7.083f.92f9.321e.0a71.a78d.238a.a25a.
5689.19d4.6a58.abf6.7bed.2c83.80e1.8692
::
++ print-for-web3
|= =octs
^- @t
=/ txt (crip (render-hex-bytes:eth octs))
?> =(p.octs (met 4 txt))
(cat 3 '0x' (rev 4 (met 4 txt) txt))
::
++ print-for-batch
|= =octs
^- @t
(crip (render-hex-bytes:eth octs))
--
|= sig=(unit @t)
^- @t
=/ account (hex-to-num:eth '0xb026b0AA6e686F2386051b31A03E5fB95513e1c0')
=/ tx=octs
(gen-tx-octs:tt [~ravmun-mitbus %own] %set-spawn-proxy account)
=/ prepped=octs (prepare-for-sig:tt 3 0 tx)
?~ sig
(cat 3 'sign: ' (print-for-web3 prepped))
=/ batch=@t
%: rap 3
'0x26887f26'
(print-for-batch tx)
(rsh 3^2 u.sig)
~
==
(cat 3 'batch: ' batch)

View File

@ -0,0 +1,683 @@
:: azimuth/roll rpc: command parsing and utilities
::
/- rpc=json-rpc, *dice
/+ naive, json-rpc, lib=naive-transactions
::
=> :: Utilities
::
|%
+$ spawn-action
$? %escape
%cancel-escape
%adopt
%reject
%detach
==
::
+$ proxy-action
$? %set-management-proxy
%set-spawn-proxy
%set-transfer-proxy
==
::
++ parse-ship
|= jon=json
^- (unit @p)
?: ?=([%n *] jon)
(rush p.jon dem)
?. ?=([%s *] jon) ~
(rush p.jon ;~(pfix sig fed:ag))
:: TODO: from /lib/group-store (move to zuse?)
++ enkebab
|= str=cord
^- @tas
~| str
=- (fall - str)
%+ rush str
=/ name
%+ cook
|= part=tape
^- tape
?~ part part
:- (add i.part 32)
t.part
;~(plug hig (star low))
%+ cook
|=(a=(list tape) (crip (zing (join "-" a))))
;~(plug (star low) (star name))
::
++ from-json
=, dejs-soft:format
|%
++ data
|%
++ keys
|= params=(map @t json)
^- (unit [encrypt=@ auth=@ crypto-suite=@ breach=?])
?~ data=(~(get by params) 'data') ~
=; ans=(unit [cryp=(unit @ux) auth=(unit @ux) suit=@ brec=?])
?~ ans ~
?: |(?=(~ cryp.u.ans) ?=(~ auth.u.ans)) ~
(some [u.cryp.u.ans u.auth.u.ans suit.u.ans brec.u.ans])
%. u.data
%- ot
:~ ['encrypt' (cu to-hex so)]
['auth' (cu to-hex so)]
['cryptoSuite' (su dem)]
['breach' bo]
==
::
++ address-transfer
|= params=(map @t json)
^- (unit [@ux ?])
?~ data=(~(get by params) 'data') ~
=; ans=(unit [add=(unit @ux) r=?])
?~ ans ~
?~ add.u.ans ~
(some [u.add.u.ans r.u.ans])
%. u.data
%- ot
~[['address' (cu to-hex so)] ['reset' bo]]
::
++ address-ship
|= params=(map @t json)
^- (unit [@p @ux])
?~ data=(~(get by params) 'data') ~
=; ans=(unit [ship=@p add=(unit @ux)])
?~ ans ~
?~ add.u.ans ~
(some [ship.u.ans u.add.u.ans])
%. u.data
%- ot
:~ ['ship' parse-ship]
['address' (cu to-hex so)]
==
::
++ address
|= params=(map @t json)
^- (unit @ux)
?~ data=(~(get by params) 'data') ~
=; ans=(unit (unit @ux))
?~(ans ~ u.ans)
%. u.data
(ot ['address' (cu to-hex so)]~)
::
++ ship
|= params=(map @t json)
^- (unit @p)
?~ data=(~(get by params) 'data') ~
%. u.data
(ot ['ship' parse-ship]~)
::
++ cancel
|= params=(map @t json)
^- (unit [l2-tx @p])
?~ data=(~(get by params) 'data') ~
%. u.data
%- ot
:~ ['type' (cu l2-tx so)]
['ship' parse-ship]
==
--
::
++ ship
|= params=(map @t json)
^- (unit @p)
?~ data=(~(get by params) 'ship') ~
(parse-ship u.data)
::
++ address
|= params=(map @t json)
^- (unit @ux)
?~ data=(~(get by params) 'address') ~
?~ ans=((cu to-hex so) u.data) ~
u.ans
::
++ sig
|= params=(map @t json)
^- (unit @)
?~ sig=(~(get by params) 'sig') ~
?~ ans=((cu to-hex so) u.sig) ~
u.ans
::
++ from
|= params=(map @t json)
^- (unit [@p proxy:naive])
?~ from=(~(get by params) 'from') ~
%. u.from
%- ot
:~ ['ship' parse-ship]
['proxy' (cu proxy:naive so)]
==
::
++ hash
|= params=(map @t json)
^- (unit @ux)
?~ hash=(~(get by params) 'hash') ~
?~ ans=((cu to-hex so) u.hash) ~
u.ans
::
++ raw
|= params=(map @t json)
^- (unit octs)
?~ raw=(~(get by params) 'raw') ~
?~ ans=((cu to-hex so) u.raw) ~
?~ u.ans ~
(some (as-octs:mimes:html u.u.ans))
::
++ tx
|= params=(map @t json)
^- (unit l2-tx)
?~ data=(~(get by params) 'tx') ~
?~ tx=(so u.data) ~
=/ method=@tas (enkebab u.tx)
?. ?=(l2-tx method) ~
`method
::
++ nonce
|= params=(map @t json)
^- (unit @ud)
?~ nonce=(~(get by params) 'nonce') ~
(ni u.nonce)
--
::
++ to-json
=, enjs:format
|%
++ pending-tx
|= pend-tx
^- json
%- pairs
:~ ['force' b+force]
['time' (^time time)]
['rawTx' (^raw-tx raw-tx)]
(en-address address)
==
::
++ pending-txs
|= pending=(list pend-tx)
^- json
a+(turn pending pending-tx)
::
++ en-address |=(a=@ux address+(hex 20 a))
::
++ raw-tx
|= raw-tx:naive
^- json
|^
%- pairs
:~ ['tx' (parse-tx +.tx)]
['sig' (hex (as-octs:mimes:html sig))]
::
:- 'from'
%- pairs
~[['ship' (ship ship.from.tx)] ['proxy' s+proxy.from.tx]]
==
::
++ parse-tx
|= tx=skim-tx:naive
^- json
%- pairs
:~ ['type' s+-.tx]
::
:- 'data'
%- pairs
?- -.tx
%transfer-point (en-transfer +.tx)
%spawn (en-spawn +.tx)
%configure-keys (en-keys +.tx)
%escape ~[(en-ship parent.tx)]
%cancel-escape ~[(en-ship parent.tx)]
%adopt ~[(en-ship ship.tx)]
%reject ~[(en-ship ship.tx)]
%detach ~[(en-ship ship.tx)]
%set-management-proxy ~[(en-address address.tx)]
%set-spawn-proxy ~[(en-address address.tx)]
%set-transfer-proxy ~[(en-address address.tx)]
== ==
::
++ en-ship |=(s=@p ship+(numb `@ud`s))
++ en-spawn |=([s=@p a=@ux] ~[(en-ship s) (en-address a)])
++ en-transfer |=([a=@ux r=?] ~[(en-address a) reset+b+r])
++ en-keys
|= [encrypt=@ auth=@ crypto-suite=@ breach=?]
^- (list [@t json])
:~ ['encrypt' (numb encrypt)]
['auth' (numb auth)]
['cryptoSuite' (numb crypto-suite)]
['breach' b+breach]
==
--
::
++ hist-txs
|= txs=(list hist-tx)
^- json
:- %a
%+ turn txs
|= hist-tx
^- json
%- pairs
:~ ['time' (time p)]
['status' s+status.q]
['hash' (hex (as-octs:mimes:html hash.q))]
['type' s+type.q]
['ship' (ship ship.q)]
==
::
++ point
|= =point:naive
^- json
%- pairs
:~ ['dominion' s+dominion.point]
::
:- 'ownership'
%- pairs
=* own own.point
^- (list [@t json])
:~ ['owner' (ownership owner.own)]
['spawnProxy' (ownership spawn-proxy.own)]
['managementProxy' (ownership management-proxy.own)]
['votingProxy' (ownership voting-proxy.own)]
['transferProxy' (ownership transfer-proxy.own)]
==
::
:- 'network'
%- pairs
=* net net.point
:* ['rift' s+(json-number rift.net)]
::
:- 'keys'
%- pairs
:~ ['life' s+(json-number life.keys.net)]
['suite' s+(json-number suite.keys.net)]
['auth' (hex 32 auth.keys.net)]
['crypt' (hex 32 crypt.keys.net)]
==
::
:- 'sponsor'
%- pairs
~[['has' b+has.sponsor.net] ['who' (numb `@ud`who.sponsor.net)]]
::
?~ escape.net ~
['escape' (numb `@ud`u.escape.net)]~
== ==
::
++ json-number
|= num=@
^- @t
=/ jon=json (numb num)
?>(?=([%n *] jon) p.jon)
::
++ points
|= points=(list [@p point:naive])
^- json
:- %a
%+ turn points
|= [ship=@p =point:naive]
%- pairs
:~ ['ship' (^ship ship)]
['point' (^point point)]
==
::
++ ships
|= ships=(list @p)
^- json
a+(turn ships (cork @ud numb))
::
++ ownership
|= [=address:naive =nonce:naive]
^- json
%- pairs
:~ (en-address address)
['nonce' (numb nonce)]
==
::
++ spawned
|= children=(list [@p @ux])
^- json
:- %a
%+ turn children
|= [child=@p address=@ux]
%- pairs
:~ ['ship' (ship child)]
(en-address address)
==
::
++ sponsored
|= [res=(list @p) req=(list @p)]
^- json
%- pairs
:~ ['residents' (ships res)]
['requests' (ships req)]
==
::
++ tx-status |=(=^tx-status ^-(json s+status.tx-status))
::
++ roller-config
|= [az=^azimuth-config ro=^roller-config]
^- json
%- pairs
:~ ['azimuthRefreshRate' (numb (div refresh-rate.az ~s1))]
['nextBatch' (time next-batch.ro)]
['frequency' (numb (div frequency.ro ~s1))]
['rollerResendTime' (numb (div resend-time.ro ~s1))]
['rollerUpdateRate' (numb (div update-rate.ro ~s1))]
['contract' (hex 20 contract.ro)]
['chainId' (numb chain-id.ro)]
['timeSlice' (numb (div slice.ro ~s1))]
['rollerQuota' (numb quota.ro)]
==
::
++ azimuth-config
|= config=^azimuth-config
^- json
%- pairs
['refreshRate' (numb (div refresh-rate.config ~s1))]~
::
++ hex
|= [p=@ q=@]
^- json
s+(crip ['0' 'x' ((x-co:co (mul 2 p)) q)])
::
++ naive-state
|= =^state:naive
^- json
|^
%- pairs
:~ ['points' (points (tap:orp points.state))]
['operators' (operators operators.state)]
['dns' a+(turn dns.state (lead %s))]
==
::
++ orp ((on ^ship point:naive) por:naive)
::
++ operators
|= =operators:naive
^- json
:- %a
%+ turn ~(tap by operators)
|= [op=@ux addrs=(set @ux)]
^- json
%- pairs
:~ ['operator' (hex 20 op)]
['addresses' a+(turn ~(tap in addrs) (cury hex 20))]
==
--
--
::
++ to-hex
|= =cord
^- (unit @ux)
?. =((end [3 2] cord) '0x') ~
(rush (rsh [3 2] cord) hex)
::
++ build-l2-tx
|= [=l2-tx from=[@p proxy:naive] params=(map @t json)]
^- (unit tx:naive)
?: =(l2-tx %transfer-point)
?~ data=(address-transfer:data:from-json params)
~
`[from %transfer-point u.data]
?: =(l2-tx %spawn)
?~ data=(address-ship:data:from-json params)
~
`[from %spawn u.data]
?: =(l2-tx %configure-keys)
?~ data=(keys:data:from-json params)
~
`[from %configure-keys u.data]
?: ?=(spawn-action l2-tx)
?~ data=(ship:data:from-json params)
~
?- l2-tx
%escape `[from %escape u.data]
%cancel-escape `[from %cancel-escape u.data]
%adopt `[from %adopt u.data]
%reject `[from %reject u.data]
%detach `[from %detach u.data]
==
?. ?=(proxy-action l2-tx)
~
?~ data=(address:data:from-json params)
~
?- l2-tx
%set-management-proxy `[from %set-management-proxy u.data]
%set-spawn-proxy `[from %set-spawn-proxy u.data]
%set-transfer-proxy `[from %set-transfer-proxy u.data]
==
--
|%
++ get-point
|= [id=@t params=(map @t json) scry=$-(ship (unit point:naive))]
^- response:rpc
?. =(~(wyt by params) 1)
~(params error:json-rpc id)
?~ ship=(~(get by params) 'ship')
~(params error:json-rpc id)
?~ ship=(parse-ship u.ship)
~(params error:json-rpc id)
?~ point=(scry u.ship)
~(not-found error:json-rpc id)
[%result id (point:to-json u.point)]
::
++ get-ships
|= [id=@t params=(map @t json) scry=$-(@ux (list @p))]
^- response:rpc
?. =(~(wyt by params) 1)
~(params error:json-rpc id)
?~ address=(address:from-json params)
~(parse error:json-rpc id)
[%result id (ships:to-json (scry u.address))]
::
++ get-dns
|= [id=@t params=(map @t json) dns=(list @t)]
^- response:rpc
?. =((lent ~(tap by params)) 0)
~(params error:json-rpc id)
[%result id a+(turn dns (cork same (lead %s)))]
::
++ cancel-tx
|= [id=@t params=(map @t json)]
^- [(unit cage) response:rpc]
?. =(~(wyt by params) 3)
[~ ~(params error:json-rpc id)]
=/ sig=(unit @) (sig:from-json params)
=/ keccak=(unit @ux) (hash:from-json params)
=/ data=(unit [l2-tx ship]) (cancel:data:from-json params)
?. &(?=(^ sig) ?=(^ keccak) ?=(^ data))
[~ ~(parse error:json-rpc id)]
:_ [%result id s+'ok']
%- some
roller-action+!>([%cancel u.sig u.keccak u.data])
::
++ get-spawned
|= [id=@t params=(map @t json) scry=$-(@p (list @p))]
^- response:rpc
?. =((lent ~(tap by params)) 1)
~(params error:json-rpc id)
?~ ship=(ship:from-json params)
~(params error:json-rpc id)
[%result id (ships:to-json (scry u.ship))]
::
++ spawns-remaining
|= [id=@t params=(map @t json) scry=$-(@p (list @p))]
^- response:rpc
?. =((lent ~(tap by params)) 1)
~(params error:json-rpc id)
?~ ship=(ship:from-json params)
~(params error:json-rpc id)
[%result id (numb:enjs:format (lent (scry u.ship)))]
::
++ sponsored-points
|= [id=@t params=(map @t json) scry=$-(@p [(list @p) (list @p)])]
^- response:rpc
?. =((lent ~(tap by params)) 1)
~(params error:json-rpc id)
?~ ship=(ship:from-json params)
~(params error:json-rpc id)
[%result id (sponsored:to-json (scry u.ship))]
::
++ process-rpc
|= [id=@t params=(map @t json) action=l2-tx over-quota=$-(@p ?)]
^- [(unit cage) response:rpc]
?. =((lent ~(tap by params)) 4)
[~ ~(params error:json-rpc id)]
=+ ^- $: sig=(unit @)
from=(unit [=ship proxy:naive])
addr=(unit @ux)
==
=, from-json
[(sig params) (from params) (address params)]
?: |(?=(~ sig) ?=(~ from) ?=(~ addr))
[~ ~(parse error:json-rpc id)]
?: (over-quota ship.u.from)
`[%error id '-32002' 'Max tx quota exceeded']
=/ tx=(unit tx:naive) (build-l2-tx action u.from params)
?~ tx [~ ~(parse error:json-rpc id)]
=+ (gen-tx-octs:lib u.tx)
:_ [%result id (hex:to-json 32 (hash-tx:lib p q))]
%- some
roller-action+!>([%submit | u.addr u.sig %don u.tx])
::
++ nonce
|= [id=@t params=(map @t json) scry=$-([ship proxy:naive] (unit @))]
^- response:rpc
?. =((lent ~(tap by params)) 1)
~(params error:json-rpc id)
?~ from=(from:from-json params)
~(parse error:json-rpc id)
?~ nonce=(scry u.from)
~(not-found error:json-rpc id)
[%result id (numb:enjs:format u.nonce)]
::
++ pending
|%
::
++ all
|= [id=@t params=(map @t json) pending=(list pend-tx)]
^- response:rpc
?. =((lent ~(tap by params)) 0)
~(params error:json-rpc id)
[%result id (pending-txs:to-json pending)]
::
++ ship
|= [id=@t params=(map @t json) scry=$-(@p (list pend-tx))]
^- response:rpc
?. =((lent ~(tap by params)) 1)
~(params error:json-rpc id)
?~ ship=(ship:from-json params)
~(parse error:json-rpc id)
[%result id (pending-txs:to-json (scry u.ship))]
::
++ addr
|= [id=@t params=(map @t json) scry=$-(@ux (list pend-tx))]
^- response:rpc
?. =((lent ~(tap by params)) 1)
~(params error:json-rpc id)
?~ address=(address:from-json params)
~(parse error:json-rpc id)
[%result id (pending-txs:to-json (scry u.address))]
::
++ hash
|= [id=@t params=(map @t json) scry=$-(@ux (unit pend-tx))]
^- response:rpc
?. =((lent ~(tap by params)) 1)
~(params error:json-rpc id)
?~ hash=(hash:from-json params)
~(parse error:json-rpc id)
?~ tx=(scry u.hash)
~(not-found error:json-rpc id)
[%result id (pending-tx:to-json u.tx)]
--
::
++ status
|= [id=@t params=(map @t json) scry=$-(@ tx-status)]
^- response:rpc
?. =((lent ~(tap by params)) 1)
~(params error:json-rpc id)
?~ hash=(hash:from-json params)
~(parse error:json-rpc id)
[%result id (tx-status:to-json (scry u.hash))]
::
++ next-batch
|= [id=@t params=(map @t json) when=time]
^- response:rpc
?. =((lent ~(tap by params)) 0)
~(params error:json-rpc id)
[%result id (time:enjs:format when)]
::
++ history
|= [id=@t params=(map @t json) scry=$-(address:naive (list hist-tx))]
^- response:rpc
?. =((lent ~(tap by params)) 1)
~(params error:json-rpc id)
?~ address=(address:from-json params)
~(parse error:json-rpc id)
[%result id (hist-txs:to-json (scry u.address))]
::
++ get-config
|= [id=@t params=(map @t json) config=[azimuth-config roller-config]]
^- response:rpc
?. =((lent ~(tap by params)) 0)
~(params error:json-rpc id)
[%result id (roller-config:to-json config)]
::
++ hash-transaction
|= [id=@t params=(map @t json) chain-id=@ header=? reverse=?]
^- response:rpc
?. =((lent ~(tap by params)) 4)
~(params error:json-rpc id)
=+ ^- $: l2-tx=(unit l2-tx)
nonce=(unit @ud)
from=(unit [@p proxy:naive])
==
=, from-json
[(tx params) (nonce params) (from params)]
?: |(?=(~ nonce) ?=(~ from) ?=(~ l2-tx))
~(parse error:json-rpc id)
=/ tx=(unit tx:naive) (build-l2-tx u.l2-tx u.from params)
?~ tx ~(parse error:json-rpc id)
=/ =octs
%. [chain-id u.nonce (gen-tx-octs:lib u.tx)]
?: header
unsigned-tx:lib
prepare-for-sig:lib
:+ %result id
%- hex:to-json
?: reverse
p.octs^(rev 3 octs)
32^(hash-tx:lib octs)
::
++ hash-raw-transaction
|= [id=@t params=(map @t json)]
^- response:rpc
?. =((lent ~(tap by params)) 4)
~(params error:json-rpc id)
=+ ^- $: sig=(unit @)
l2-tx=(unit l2-tx)
from=(unit [=ship proxy:naive])
==
=, from-json
[(sig params) (tx params) (from params)]
?: |(?=(~ sig) ?=(~ from) ?=(~ l2-tx))
~(parse error:json-rpc id)
=/ tx=(unit tx:naive) (build-l2-tx u.l2-tx u.from params)
?~ tx ~(parse error:json-rpc id)
:+ %result id
%+ hex:to-json 32
(hash-raw-tx:lib u.sig (gen-tx-octs:lib u.tx) u.tx)
::
++ get-naive
|= [id=@t params=(map @t json) =^state:naive]
^- response:rpc
?. =((lent ~(tap by params)) 0)
~(params error:json-rpc id)
[%result id (naive-state:to-json state)]
::
++ get-refresh
|= [id=@t params=(map @t json) =azimuth-config]
^- response:rpc
?. =((lent ~(tap by params)) 0)
~(params error:json-rpc id)
[%result id (azimuth-config:to-json azimuth-config)]
--

View File

@ -98,6 +98,9 @@
++ delegated-sending
0xf790.8ab1.f1e3.52f8.3c5e.bc75.051c.0565.aeae.a5fb
::
++ naive
0xeb70.029c.fb3c.53c7.78ea.f68c.d28d.e725.390a.1fe9
::
:: launch: block number of azimuth deploy
::
++ launch 6.784.800
@ -105,6 +108,8 @@
:: public: block number of azimuth becoming independent
::
++ public 7.033.765
::
++ chain-id 1
--
::
:: Testnet contract addresses
@ -126,8 +131,12 @@
++ delegated-sending
0x3e8c.a510.354b.c2fd.bbd6.1502.52d9.3105.c9c2.7bbe
::
++ naive
0xe7cf.4b83.06d3.11ba.ca15.585f.e3f0.7cd0.441c.21d1
::
++ launch 4.601.630
++ public launch
++ chain-id 3
--
::
:: Local contract addresses
@ -147,8 +156,11 @@
0x3c3.dc12.be65.8158.d1d7.f9e6.6e08.ec40.99c5.68e4
++ conditional-star-release
0x35eb.3b10.2d9c.1b69.ac14.69c1.b1fe.1799.850c.d3eb
++ naive
0x6bb8.8a9b.bd82.be7a.997f.eb01.929c.6ec7.8988.fe12
++ launch 0
++ public 0
++ chain-id 1.337
--
::
:: ++ azimuth 0x863d.9c2e.5c4c.1335.96cf.ac29.d552.55f0.d0f8.6381 :: local bridge

207
pkg/arvo/lib/dice.hoon Normal file
View File

@ -0,0 +1,207 @@
:: dice: helper functions for L2 Rollers
::
/- *dice
/+ naive, *naive-transactions
::
|%
++ nonce-order
|= [a=[* =nonce:naive] b=[* =nonce:naive]]
(lte nonce.a nonce.b)
::
++ apply-effects
|= [chain-t=@ =effects:naive =indices]
^+ indices
%+ roll effects
|= [=diff:naive indices=_indices]
?. ?=([%tx *] diff) indices::[nas own spo]
=< indices
(apply-raw-tx | chain-t raw-tx.diff indices)
::
++ apply-raw-tx
|= [force=? chain-t=@ =raw-tx:naive =indices]
^- [? ups=(list update) indices=_indices]
=+ cache-nas=nas.indices
=/ chain-t=@t (ud-to-ascii:naive chain-t)
?. (verify-sig-and-nonce:naive verifier chain-t nas.indices raw-tx)
~& [%verify-sig-and-nonce %failed tx.raw-tx]
[force ~ indices]
=^ * points.nas.indices
(increment-nonce:naive nas.indices from.tx.raw-tx)
?~ nex=(receive-tx:naive nas.indices tx.raw-tx)
~& [%receive-tx %failed]
=? nas.indices !force cache-nas
[force ~ indices]
=* new-nas +.u.nex
=* effects -.u.nex
=/ [updates=(list update) own=_own.indices spo=_spo.indices]
(update-indices effects cache-nas new-nas [own spo]:indices)
=: nas.indices new-nas
own.indices own
spo.indices spo
==
[& updates indices]
::
++ update-indices
|= $: =effects:naive
cache-nas=^state:naive
nas=^state:naive
=owners
=sponsors
==
^- [(list update) own=_owners spo=_sponsors]
%+ roll effects
|= $: =diff:naive
ups=(list update)
owners=_owners
sponsors=_sponsors
==
=, orm:naive
?. ?=([%point *] diff) [ups owners sponsors]
=* ship ship.diff
=/ old=(unit point:naive)
(get points.cache-nas ship)
=/ new=point:naive
(need (get points.nas ship))
=* event +>.diff
|^
=^ updates owners ownership
=+ sponsors=sponsorship
:+ (weld ups updates)
owners
sponsors
::
++ sponsorship
^+ sponsors
?+ -.event sponsors
%owner
?^ old
:: ownership change
::
sponsors
:: owner event with ?=(~ old) is a spawn
::
=* parent who.sponsor.net.new
?: =(parent ship) sponsors
%+ ~(put by sponsors) parent
?~ sponsor=(~(get by sponsors) parent)
:_ *(set @p)
(~(put in *(set @p)) ship)
:_ requests.u.sponsor
(~(put in residents.u.sponsor) ship)
::
%escape
?~ old sponsors
=* from who.sponsor.net.u.old
=* to to.event
=* escape escape.net.u.old
?~ to
:: cancel/reject escape
::
?~ escape sponsors
?~ receiver=(~(get by sponsors) u.escape)
sponsors
%+ ~(put by sponsors) u.escape
:- residents.u.receiver
(~(del in requests.u.receiver) ship)
:: normal escape
::
%+ ~(put by sponsors) u.to
?~ receiver=(~(get by sponsors) u.to)
:- *(set @p)
(~(put in *(set @p)) ship)
:- residents.u.receiver
(~(put in requests.u.receiver) ship)
::
%sponsor
?~ old sponsors
=* from who.sponsor.net.u.old
=* to sponsor.event
=/ previous (~(get by sponsors) from)
?~ to
:: detach
::
?~ previous sponsors
%+ ~(put by sponsors) from
:_ requests.u.previous
(~(del in residents.u.previous) ship)
:: accepted
::
=/ receiver (~(get by sponsors) u.to)
=? sponsors ?=(^ receiver)
%+ ~(put by sponsors) u.to
:- (~(put in residents.u.receiver) ship)
(~(del in requests.u.receiver) ship)
=? sponsors ?=(^ previous)
%+ ~(put by sponsors) from
:_ requests.u.previous
(~(del in residents.u.previous) ship)
sponsors
==
::
++ ownership
^- (quip update _owners)
=; [to=(unit owner) from=(unit owner)]
=? owners &(?=(^ from) !=(address.u.from 0x0))
(~(del ju owners) u.from ship)
?: ?| =(~ to)
&(?=(^ to) =(address.u.to 0x0))
==
[ups owners]
?~ to [ups owners]
:_ (~(put ju owners) u.to ship)
(snoc ups [%point ship new u.to from])
?+ -.event [~ ~]
%owner
:- `[%own +.event]
?~ old ~
`[%own address.owner.own.u.old]
::
%management-proxy
:- `[%manage +.event]
?~ old ~
`[%manage address.management-proxy.own.u.old]
::
%spawn-proxy
:- `[%spawn +.event]
?~ old ~
`[%spawn address.spawn-proxy.own.u.old]
::
%voting-proxy
:- `[%vote +.event]
?~ old ~
`[%vote address.voting-proxy.own.u.old]
::
%transfer-proxy
:- `[%transfer +.event]
?~ old ~
`[%transfer address.transfer-proxy.own.u.old]
==
--
::
++ get-owner
|= [=point:naive =proxy:naive]
^- [nonce=@ _point]
=* own own.point
?- proxy
%own
:- nonce.owner.own
point(nonce.owner.own +(nonce.owner.own))
::
%spawn
:- nonce.spawn-proxy.own
point(nonce.spawn-proxy.own +(nonce.spawn-proxy.own))
::
%manage
:- nonce.management-proxy.own
point(nonce.management-proxy.own +(nonce.management-proxy.own))
::
%vote
:- nonce.voting-proxy.own
point(nonce.voting-proxy.own +(nonce.voting-proxy.own))
::
%transfer
:- nonce.transfer-proxy.own
point(nonce.transfer-proxy.own +(nonce.transfer-proxy.own))
==
::
--

View File

@ -408,18 +408,6 @@
.^([rev=@ud @da] %cw /(scot %p our)/[d]/(scot %da now))
==
take-commit:(abed:vats %base)
=? kiln ?=(^ wef)
=/ except=(set desk)
=/ base=(set desk) (sy %base %kids ~)
%- ~(gas in base)
%+ murn ~(tap by ark.old)
|= [loc=desk ark=arak]
^- (unit desk)
?. liv.rein.ark `loc
?~ rail.ark `loc
?: paused.u.rail.ark `loc
~
(bump:vats u.wef except force=%.n)
=. wef ~
abet:kiln
::
@ -692,11 +680,11 @@
|= [kel=weft except=(set desk) force=?]
^+ kiln
=/ ded (find-blocked kel except)
?: force
=. kiln (suspend-many ded)
(bump-many kel (all-desks-but (~(uni in except) ded)))
?: =(~ ded)
(bump-many kel (all-desks-but except))
=? kiln force (suspend-many ded)
?: |(force =(~ ded))
?: !=(zuse+zuse kel)
(bump-one kel %base)
(bump-many (all-desks-but (~(uni in except) ded)))
=- (^emit (pyre:pass leaf/- ~))
"kiln: desks blocked upgrade to {<zuse/zuse>}: {<ded>}"
::
@ -716,7 +704,7 @@
$(ded t.ded, kiln abet:(suspend i.ded))
::
++ bump-many
|= [kel=weft live=(set desk)]
|= live=(set desk)
^+ kiln
:: ensure %base is always reloaded first
::
@ -730,7 +718,7 @@
::
|- ^+ kiln
?~ liv kiln
$(liv t.liv, kiln (bump-one kel i.liv))
$(liv t.liv, kiln (bump-one zuse+zuse i.liv))
::
++ bump-one
|= [kel=weft =desk]
@ -745,7 +733,7 @@
?: =(kel u.kul)
~> %slog.(fmt "{here} already at {<[lal num]:kel>}")
update-running-dudes
=^ tem rail.rak (crank-next %| kel)
=^ tem rail.rak (crank-next kel)
?^ tem
(emit merge-main:pass)
=- (emit (pyre:pass leaf/- ~))
@ -873,7 +861,8 @@
++ kelvin-same
^+ vats
~> %slog.(fmt "merging into {here}")
=. rail.rak +:(crank-next %& (dec aeon:ral))
?> ?=(^ rail.rak)
=. next.u.rail.rak ~
(emil ~[merge-main sync-ud]:pass)
::
++ do-base
@ -890,7 +879,8 @@
=/ =diff [%block loc rak new-weft blockers]
(emil sync-ud:pass (diff:give diff) ~)
~> %slog.(fmt "applying OTA to {here}, kelvin: {<new-weft>}")
=. rail.rak +:(crank-next %& (dec aeon:ral))
?> ?=(^ rail.rak)
=. next.u.rail.rak ~
=. wef
?: =(old-weft new-weft) ~
`new-weft
@ -924,11 +914,7 @@
update-running-dudes
?. =(%base loc)
kiln
=/ kel=[@tas @ud]
?~ rail.rak zuse/zuse
?~ next.u.rail.rak zuse/zuse
weft.i.next.u.rail.rak
(bump-many kel (all-desks-but (sy %base ~)))
(bump-many (all-desks-but (get-unblockers ark)))
::
++ take-merge-main
|= syn=sign-arvo
@ -1003,7 +989,7 @@
:: +crank-next: pop stale items from .next until one matches
::
++ crank-next
|= new=(each aeon weft)
|= new=weft
^+ [match=*(unit rung) rail.rak]
?~ rail.rak
~| [%no-rail-for desk=loc]
@ -1012,10 +998,7 @@
=- [match `u.rail.rak(next next)]
|- ^- [match=(unit rung) next=(list rung)]
?~ rog [~ next.u.rail.rak]
?: ?- -.new
%& =(p.new aeon.i.rog)
%| =(p.new weft.i.rog)
==
?: =(new weft.i.rog)
[`i.rog t.rog]
$(rog t.rog)
::
@ -1043,6 +1026,19 @@
?: (lien next.u.rail.arak |=([* k=weft] =(k kel)))
~
`desk
:: +get-unblockers: find desks which shouldn't block a kernel upgrade
::
++ get-unblockers
|= ark=(map desk arak)
=/ base=(set desk) (sy %base %kids ~)
%- ~(gas in base)
%+ murn ~(tap by ark)
|= [loc=desk ark=arak]
^- (unit desk)
?. liv.rein.ark `loc
?~ rail.ark `loc
?: paused.u.rail.ark `loc
~
:: +get-germ: select merge strategy into local desk
::
:: If destination desk doesn't exist, need a %init merge. If this is
@ -1211,9 +1207,9 @@
abet:abet:(install:vats +<)
::
++ poke-label
|= [syd=desk lab=@tas]
|= [syd=desk lab=@tas aey=(unit aeon)]
=+ pax=/(scot %p our)/[syd]/[lab]
(poke-info "labeled {(spud pax)}" `[syd %| lab])
(poke-info "labeled {(spud pax)}" `[syd %| lab aey])
::
++ poke-merge
|= kiln-merge

View File

@ -17,15 +17,85 @@
|= request
^- json
%- pairs:enjs:format
:~ jsonrpc+s+'0.2'
:~ jsonrpc+s+'2.0'
id+s+id
method+s+method
::
:- %params
^- json
?- -.params
%list [%a +.params]
%object [%o (~(gas by *(map @t json)) +.params)]
==
%list [%a +.params]
:: FIXME: support either %map or %object (also in /sur/json/rpc)
::
%map [%o +.params]
%object [%o (~(gas by *(map @t json)) +.params)]
== ==
::
++ response-to-json
|= =response
^- json
:: TODO: consider all cases
::
?+ -.response ~|([%unsupported-rpc-response response] !!)
%batch a+(turn bas.response response-to-json)
::
%result
%- pairs:enjs:format
:: FIXME: return 'id' as string, number or NULL
::
:~ ['jsonrpc' s+'2.0']
['id' s+id.response]
['result' res.response]
==
::
%error
=, enjs:format
%- pairs
:~ ['jsonrpc' s+'2.0']
['id' ?~(id.response ~ s+id.response)]
::
:- 'error'
%- pairs
:~ ['code' n+code.response]
['message' s+message.response]
== ==
==
::
++ validate-request
|= body=(unit octs)
^- (unit batch-request)
?~ body ~
?~ jon=(de-json:html q.u.body) ~
=, dejs-soft:format
=; reparser
?: ?=([%a *] u.jon)
(bind ((ar reparser) u.jon) (lead %a))
(bind (reparser u.jon) (lead %o))
%- ot
:~ :: FIXME: parse 'id' as string, number or NULL
::
['id' so]
['jsonrpc' (su (jest '2.0'))]
['method' so]
::
:- 'params'
|= =json
^- (unit request-params)
?+ -.json ~
%a `[%list ((ar:dejs:format same) json)]
%o `[%map ((om:dejs:format same) json)]
== ==
::
++ error
|_ id=@t
:: https://www.jsonrpc.org/specification#error_object
::
++ parse [%error id '-32700' 'Failed to parse']
++ request [%error id '-32600' 'Invalid Request']
++ method [%error id '-32601' 'Method not found']
++ params [%error id '-32602' 'Invalid params']
++ internal [%error id '-32603' 'Internal error']
++ not-found [%error id '-32000' 'Resource not found']
++ todo [%error id '-32001' 'Method not implemented']
--
--

View File

@ -0,0 +1,218 @@
/+ naive, ethereum
:: Types
|%
+$ address address:ethereum
+$ nonce @ud
+$ proxy ?(%own %spawn %manage %vote %transfer)
--
::
|%
::
:: TODO: does this uniquely produce the pubkey?
++ verifier
^- ^verifier:naive
|= [dat=octs v=@ r=@ s=@]
?: (gth v 3) ~ :: TODO: move to jet
=/ result
%- mule
|.
=, secp256k1:secp:crypto
%- address-from-pub:key:ethereum
%- serialize-point
(ecdsa-raw-recover (hash-tx dat) v r s)
?- -.result
%| ~
%& `p.result
==
:: Verify signature and produce signer address
::
++ verify-sig
|= [sig=@ txdata=octs]
^- (unit address)
|^
:: Reversed of the usual r-s-v order because Ethereum integers are
:: big-endian
::
=^ v sig (take 3)
=^ s sig (take 3 32)
=^ r sig (take 3 32)
:: In Ethereum, v is generally 27 + recid, and verifier expects a
:: recid. Old versions of geth used 0 + recid, so most software
:: now supports either format. See:
::
:: https://github.com/ethereum/go-ethereum/issues/2053
::
=? v (gte v 27) (sub v 27)
(verifier txdata v r s)
::
++ take
|= =bite
[(end bite sig) (rsh bite sig)]
--
::
++ unsigned-tx
|= [chain-id=@ud =nonce tx=octs]
^- octs
=/ prepared-data (prepare-for-sig chain-id nonce tx)
=/ len (rsh [3 2] (scot %ui p.prepared-data))
%: cad:naive 3
26^'\19Ethereum Signed Message:\0a'
(met 3 len)^len
prepared-data
~
==
::
++ sign-tx
|= [pk=@ =nonce tx=octs] ^- octs
=/ sign-data
%- hash-tx
(unsigned-tx 1.337 nonce tx)
=+ (ecdsa-raw-sign:secp256k1:secp:crypto sign-data pk)
(cad:naive 3 1^v 32^s 32^r tx ~)
::
++ prepare-for-sig
|= [chain-id=@ud =nonce tx=octs]
^- octs
=/ chain-t (rsh [3 2] (scot %ui chain-id))
%: cad:naive 3
14^'UrbitIDV1Chain'
(met 3 chain-t)^chain-t
1^':'
4^nonce
tx
~
==
::
++ extract-address
|= [=raw-tx:naive nas=^state:naive chain-id=@]
^- (unit @ux)
?~ point=(get:orm:naive points.nas ship.from.tx.raw-tx)
~
=/ =nonce:naive
=< nonce
(proxy-from-point:naive proxy.from.tx.raw-tx u.point)
=/ message=octs
(unsigned-tx chain-id nonce raw.raw-tx)
(verify-sig sig.raw-tx message)
::
++ gen-tx
|= [=nonce tx=tx:naive pk=@] ^- octs
:: takes in a nonce, tx:naive, and private key and returned a signed transactions as octs
%^ sign-tx pk nonce (gen-tx-octs tx)
::
++ gen-tx-octs
:: generates octs for a transaction
|= tx=tx:naive
|^
^- octs
=/ raw=octs
?- +<.tx
%spawn (get-spawn +>.tx)
%transfer-point (get-transfer +>.tx)
%configure-keys (get-keys +>.tx)
%escape (get-escape +.tx)
%cancel-escape (get-escape +.tx)
%adopt (get-escape +.tx)
%reject (get-escape +.tx)
%detach (get-escape +.tx)
%set-management-proxy (get-ship-address +.tx)
%set-spawn-proxy (get-ship-address +.tx)
%set-transfer-proxy (get-ship-address +.tx)
==
raw
::
++ get-spawn
|= [child=ship to=address] ^- octs
%: cad:naive 3
(from-proxy proxy.from.tx)
4^ship.from.tx
1^%1 :: %spawn
4^child
20^to
~
==
::
++ get-transfer
|= [=address reset=?] ^- octs
%: cad:naive 3
(from-proxy proxy.from.tx)
4^ship.from.tx
1^(can 0 7^%0 1^reset ~) :: %transfer-point
20^address
~
==
::
++ get-keys
|= [crypt=@ auth=@ suite=@ breach=?] ^- octs
%: cad:naive 3
(from-proxy proxy.from.tx)
4^ship.from.tx
1^(can 0 7^%2 1^breach ~) :: %configure-keys
32^crypt
32^auth
4^suite
~
==
::
++ get-escape
|= [action=@tas other=ship] ^- octs
=/ op
?+ action !!
%escape %3
%cancel-escape %4
%adopt %5
%reject %6
%detach %7
==
%: cad:naive 3
(from-proxy proxy.from.tx)
4^ship.from.tx
1^(can 0 7^op 1^0 ~)
4^other
~
==
::
++ get-ship-address
|= [action=@tas =address] ^- octs
=/ op
?+ action !!
%set-management-proxy %8
%set-spawn-proxy %9
%set-transfer-proxy %10
==
%: cad:naive 3
(from-proxy proxy.from.tx)
4^ship.from.tx
1^(can 0 7^op 1^0 ~)
20^address
~
==
::
++ from-proxy
|= prx=@tas
^- [@ @]
=/ proxy
?+ prx !!
%own %0
%spawn %1
%manage %2
%vote %3
%transfer %4
==
1^(can 0 3^proxy 5^0 ~)
::
--
::
++ hash-tx keccak-256:keccak:crypto
::
++ hash-raw-tx
|= raw-tx:naive
^- @ux
%- hash-tx
%: cad:naive 3
65^sig
raw
~
==
::
--

926
pkg/arvo/lib/naive.hoon Normal file
View File

@ -0,0 +1,926 @@
/+ tiny
!.
=> => tiny
:: Laconic bit
::
=| lac=?
:: Constants
::
|%
:: Transfers on L1 to this address count as depositing to L2
::
++ deposit-address 0x1111.1111.1111.1111.1111.1111.1111.1111.1111.1111
++ log-names
|%
:: Generated with (keccak-256:keccak:crypto (as-octs:mimes:html name))
::
:: OwnerChanged(uint32,address)
++ owner-changed
0x16d0.f539.d49c.6cad.822b.767a.9445.bfb1.
cf7e.a6f2.a6c2.b120.a7ea.4cc7.660d.8fda
::
:: Activated(uint32)
++ activated
0xe74c.0380.9d07.69e1.b1f7.06cc.8414.258c.
d1f3.b6fe.020c.d15d.0165.c210.ba50.3a0f
::
:: Spawned(uint32,uint32)
++ spawned
0xb2d3.a6e7.a339.f5c8.ff96.265e.2f03.a010.
a854.1070.f374.4a24.7090.9644.1508.1546
::
:: OwnershipTransferred(address,address)
++ ownership-transferred
0x8be0.079c.5316.5914.1344.cd1f.d0a4.f284.
1949.7f97.22a3.daaf.e3b4.186f.6b64.57e0
::
:: EscapeRequested(uint32,uint32)
++ escape-requested
0xb4d4.850b.8f21.8218.141c.5665.cba3.79e5.
3e9b.b015.b51e.8d93.4be7.0210.aead.874a
::
:: EscapeCanceled(uint32,uint32)
++ escape-canceled
0xd653.bb0e.0bb7.ce83.93e6.24d9.8fbf.17cd.
a590.2c83.28ed.0cd0.9988.f368.90d9.932a
::
:: EscapeAccepted(uint32,uint32)
++ escape-accepted
0x7e44.7c9b.1bda.4b17.4b07.96e1.00bf.7f34.
ebf3.6dbb.7fe6.6549.0b1b.fce6.246a.9da5
::
:: LostSponsor(uint32,uint32)
++ lost-sponsor
0xd770.4f9a.2519.3dbd.0b0c.b4a8.09fe.ffff.
a7f1.9d1a.ae88.17a7.1346.c194.4482.10d5
::
:: ChangedKeys(uint32,bytes32,bytes32,uint32,uint32)
++ changed-keys
0xaa10.e7a0.117d.4323.f1d9.9d63.0ec1.69be.
bb3a.988e.8957.70e3.5198.7e01.ff54.23d5
::
:: BrokeContinuity(uint32,uint32)
++ broke-continuity
0x2929.4799.f1c2.1a37.ef83.8e15.f79d.d91b.
cee2.df99.d63c.d1c1.8ac9.68b1.2951.4e6e
::
:: ChangedSpawnProxy(uint32,address)
++ changed-spawn-proxy
0x9027.36af.7b3c.efe1.0d9e.840a.ed0d.687e.
35c8.4095.122b.2505.1a20.ead8.866f.006d
::
:: ChangedTransferProxy(uint32,address)
++ changed-transfer-proxy
0xcfe3.69b7.197e.7f0c.f067.93ae.2472.a9b1.
3583.fecb.ed2f.78df.a14d.1f10.796b.847c
::
:: ChangedManagementProxy(uint32,address)
++ changed-management-proxy
0xab9c.9327.cffd.2acc.168f.afed.be06.139f.
5f55.cb84.c761.df05.e051.1c25.1e2e.e9bf
::
:: ChangedVotingProxy(uint32,address)
++ changed-voting-proxy
0xcbd6.269e.c714.57f2.c7b1.a227.74f2.46f6.
c5a2.eae3.795e.d730.0db5.1768.0c61.c805
::
:: ChangedDns(string,string,string)
++ changed-dns
0xfafd.04ad.e1da.ae2e.1fdb.0fc1.cc6a.899f.
d424.063e.d5c9.2120.e67e.0730.53b9.4898
::
:: ApprovalForAll(address,address,bool)
++ approval-for-all
0x1730.7eab.39ab.6107.e889.9845.ad3d.59bd.
9653.f200.f220.9204.89ca.2b59.3769.6c31
--
-- =>
:: Types
|%
:: ethereum address, 20 bytes.
::
+$ address @ux
+$ nonce @ud
+$ dominion ?(%l1 %l2 %spawn)
+$ keys [=life suite=@ud auth=@ crypt=@]
++ orm ((on ship point) por)
++ point
$: :: domain
::
=dominion
::
:: ownership
::
$= own
$: owner=[=address =nonce]
spawn-proxy=[=address =nonce]
management-proxy=[=address =nonce]
voting-proxy=[=address =nonce]
transfer-proxy=[=address =nonce]
==
::
:: networking
::
$= net
$: rift=@ud
=keys
sponsor=[has=? who=@p]
escape=(unit @p)
==
==
::
++ diff
$% [%nonce =ship =proxy =nonce]
[%tx =raw-tx err=(unit @tas)]
[%operator owner=address operator=address approved=?]
[%dns domains=(list @t)]
$: %point =ship
$% [%rift =rift]
[%keys =keys]
[%sponsor sponsor=(unit @p)]
[%escape to=(unit @p)]
[%owner =address]
[%spawn-proxy =address]
[%management-proxy =address]
[%voting-proxy =address]
[%transfer-proxy =address]
[%dominion =dominion]
== == ==
::
+$ state
$: %0
=points
=operators
dns=(list @t)
==
+$ points (tree [ship point])
+$ operators (jug address address)
+$ effects (list diff)
+$ proxy ?(%own %spawn %manage %vote %transfer)
+$ roll (list raw-tx)
+$ raw-tx [sig=@ raw=octs =tx]
+$ tx [from=[=ship =proxy] skim-tx]
+$ skim-tx
$% [%transfer-point =address reset=?]
[%spawn =ship =address]
[%configure-keys encrypt=@ auth=@ crypto-suite=@ breach=?]
[%escape parent=ship]
[%cancel-escape parent=ship]
[%adopt =ship]
[%reject =ship]
[%detach =ship]
[%set-management-proxy =address]
[%set-spawn-proxy =address]
[%set-transfer-proxy =address]
==
::
+$ event-log
$: address=@ux
data=@ux
topics=(lest @ux)
==
+$ input
$: block=@ud
$% [%bat batch=@]
[%log =event-log]
== ==
:: ECDSA verifier.
::
:: Must keccak `dat` and recover the ethereum address which signed.
:: Must not crash. `v` will normally be between 0 and 3; if it is not,
:: should produce null.
::
+$ verifier $-([dat=octs v=@ r=@ s=@] (unit address))
-- =>
::
|%
++ debug
|* [meg=@t *]
?: lac
+<+
~> %slog.[0 meg]
+<+
::
++ parse-roll
|= batch=@
=| =roll
=| pos=@ud
=/ las (met 0 batch)
|- ^+ roll
?: (gte pos las)
(flop roll)
=/ parse-result (parse-raw-tx pos batch)
:: Parsing failed, abort batch
::
?~ parse-result
(debug %parse-failed ~)
=^ =raw-tx pos u.parse-result
$(roll [raw-tx roll])
::
++ parse-raw-tx
|= [pos=@ud batch=@]
^- (unit [raw-tx pos=@ud])
|^
=^ sig pos (take 3 65)
=/ res=(unit [=tx pos=@ud]) parse-tx
?~ res ~
=/ dif (sub pos.u.res pos)
=/ len =>((dvr dif 8) ?>(=(0 q) p))
:- ~ :_ pos.u.res
[sig [len (cut 0 [pos dif] batch)] tx.u.res]
::
++ parse-tx
^- (unit [tx pos=@ud])
=^ from-proxy=@ pos (take 0 3)
?. ?=(?(%0 %1 %2 %3 %4) from-proxy) (debug %bad-proxy ~)
=/ =proxy
?- from-proxy
%0 %own
%1 %spawn
%2 %manage
%3 %vote
%4 %transfer
==
=^ pad pos (take 0 5)
=^ from-ship=ship pos (take 3 4)
=- ?~ res
~
`[[[from-ship proxy] skim-tx.u.res] pos.u.res]
^- res=(unit [=skim-tx pos=@ud])
=^ op pos (take 0 7)
?+ op (debug %strange-opcode ~)
%0
=^ reset=@ pos (take 0)
=^ =address pos (take 3 20)
`[[%transfer-point address =(0 reset)] pos]
::
%1
=^ pad=@ pos (take 0)
=^ =ship pos (take 3 4)
=^ =address pos (take 3 20)
`[[%spawn ship address] pos]
::
%2
=^ breach=@ pos (take 0)
=^ encrypt=@ pos (take 3 32)
=^ auth=@ pos (take 3 32)
=^ crypto-suite=@ pos (take 3 4)
`[[%configure-keys encrypt auth crypto-suite =(0 breach)] pos]
::
%3 =^(res pos take-ship `[[%escape res] pos])
%4 =^(res pos take-ship `[[%cancel-escape res] pos])
%5 =^(res pos take-ship `[[%adopt res] pos])
%6 =^(res pos take-ship `[[%reject res] pos])
%7 =^(res pos take-ship `[[%detach res] pos])
%8 =^(res pos take-address `[[%set-management-proxy res] pos])
%9 =^(res pos take-address `[[%set-spawn-proxy res] pos])
%10 =^(res pos take-address `[[%set-transfer-proxy res] pos])
==
::
:: Take a bite
::
++ take
|= =bite
^- [@ @ud]
=/ =step
?@ bite (bex bite)
(mul step.bite (bex bloq.bite))
[(cut 0 [pos step] batch) (add pos step)]
:: Encode ship and address
::
++ take-address
^- [address @ud]
=^ pad=@ pos (take 0)
=^ =address pos (take 3 20)
[address pos]
:: Encode escape-related txs
::
++ take-ship
^- [ship @ud]
=^ pad=@ pos (take 0)
=^ other=ship pos (take 3 4)
[other pos]
--
::
++ proxy-from-point
|= [=proxy point]
^- [=address =nonce]
?- proxy
%own owner.own
%spawn spawn-proxy.own
%manage management-proxy.own
%vote voting-proxy.own
%transfer transfer-proxy.own
==
::
++ verify-sig-and-nonce
|= [=verifier chain-t=@t =state =raw-tx]
^- ?
|^
=/ point (get-point state ship.from.tx.raw-tx)
?> ?=(^ point) :: we never parse more than four bytes for a ship
=/ need=[=address =nonce]
(proxy-from-point proxy.from.tx.raw-tx u.point)
:: We include a domain separator to avoid letting signatures be
:: accidentally reused with other applications. We include the name
:: UrbitID, a signature format version number, and the EIP-155 chain
:: ID.
::
:: We also include a nonce so that a transaction cannot be
:: rebroadcast.
::
=/ prepared-data=octs
%: cad 3
14^'UrbitIDV1Chain'
(met 3 chain-t)^chain-t
1^':'
4^nonce.need
raw.raw-tx
~
==
:: Wallets which support personal_sign include this preamble to avoid
:: letting personal_sign be used to sign ethereum transactions
::
=/ signed-data=octs
=/ len (ud-to-ascii p.prepared-data)
%: cad 3
26^'\19Ethereum Signed Message:\0a'
(met 3 len)^len
prepared-data
~
==
=/ dress (verify-sig sig.raw-tx signed-data)
?~ dress
|
=(address.need u.dress)
:: Verify signature and produce signer address
::
++ verify-sig
|= [sig=@ txdata=octs]
^- (unit address)
|^
:: Reversed of the usual r-s-v order because Ethereum integers are
:: big-endian
::
=^ v sig (take 3)
=^ s sig (take 3 32)
=^ r sig (take 3 32)
:: In Ethereum, v is generally 27 + recid, and verifier expects a
:: recid. Old versions of geth used 0 + recid, so most software
:: now supports either format. See:
::
:: https://github.com/ethereum/go-ethereum/issues/2053
::
=? v (gte v 27) (sub v 27)
(verifier txdata v r s)
::
++ take
|= =bite
[(end bite sig) (rsh bite sig)]
--
--
:: ASCII-decimal encode
::
++ ud-to-ascii
|= n=@ud
?~ n '0'
=| l=(list @)
|- ^- @t
?~ n (rep 3 l)
=+ (dvr n 10)
$(n p, l [(add '0' q) l])
::
++ ship-rank
|= =ship
^- ?(%0 %1 %2 %3 %4)
?: (lth ship 0x100) %0
?: (lth ship 0x1.0000) %1
?: (lth ship 0x1.0000.0000) %2
?: (lth ship 0x1.0000.0000.0000.0000) %3
%4
::
++ sein :: autoboss
|= who=ship
^- ship
=/ mir (ship-rank who)
?- mir
%0 who
%1 (end 3 who)
%2 (end 4 who)
%3 (end 5 who)
%4 (end 4 who)
==
::
:: Produces null only if ship is not a galaxy, star, or planet
::
++ get-point
|= [=state =ship]
^- (unit point)
=/ existing (get:orm points.state ship)
?^ existing
`u.existing
=| =point
=. who.sponsor.net.point (sein ship)
?+ (ship-rank ship) (debug %strange-point ~)
%0 `point(dominion %l1)
?(%1 %2)
=/ existing-parent $(ship (sein ship))
?~ existing-parent ~
:- ~
%= point
dominion
?- dominion.u.existing-parent
%l1 %l1
%l2 %l2
%spawn %l2
==
==
==
-- =>
|%
:: Receive log from L1 transaction
::
++ receive-log
|= [=state log=event-log]
^- [effects ^state]
=* log-name i.topics.log
?: =(log-name activated:log-names) `state
?: =(log-name spawned:log-names) `state
?: =(log-name ownership-transferred:log-names) `state
?: =(log-name changed-dns:log-names)
?> ?=(~ t.topics.log)
=/ words (rip 8 data.log)
:: This is only true if each domain is <= 32 bytes
::
?. ?=([c=@ @ b=@ @ a=@ @ @ @ @ ~] words) `state
=* one &5.words
=* two &3.words
=* tri &1.words
=/ domains ~[(swp 3 one) (swp 3 two) (swp 3 tri)]
:- [%dns domains]~
state(dns domains)
::
?: =(log-name approval-for-all:log-names)
?> ?=([@ @ ~] t.topics.log)
=* owner i.t.topics.log
=* operator i.t.t.topics.log
=/ approved !=(0 data.log)
:- [%operator owner operator approved]~
=- state(operators -)
?: approved
(~(put ju operators.state) owner operator)
(~(del ju operators.state) owner operator)
::
:: The rest of the logs modify a particular ship, specified in the
:: second topic. We fetch it, and insert the modification back into
:: our state.
::
?> ?=([@ *] t.topics.log)
=* ship=@ i.t.topics.log
=/ the-point (get-point state ship)
?> ?=(^ the-point)
=* point u.the-point
::
:: Important to fully no-op on failure so we don't insert an entry
:: into points.state
::
=- ?~ res
`state
[effects.u.res state(points (put:orm points.state ship new-point.u.res))]
^- res=(unit [=effects new-point=^point])
::
?: =(log-name changed-spawn-proxy:log-names)
?. ?=(%l1 -.point) ~
?> ?=([@ ~] t.t.topics.log)
=* to i.t.t.topics.log
:: Depositing to L2 is represented by a spawn proxy change on L1,
:: but it doesn't change the actual spawn proxy.
::
?: =(deposit-address to)
:+ ~ [%point ship %dominion %spawn]~
point(dominion %spawn)
:+ ~ [%point ship %spawn-proxy to]~
point(address.spawn-proxy.own to)
::
?: =(log-name escape-accepted:log-names)
?> ?=([@ ~] t.t.topics.log)
=* parent=@ i.t.t.topics.log
=/ parent-point (get-point state parent)
?> ?=(^ parent-point)
?: ?=(%l2 -.u.parent-point) ~
:+ ~ [%point ship %sponsor `parent]~
point(escape.net ~, sponsor.net [%& parent])
::
?: =(log-name lost-sponsor:log-names)
?> ?=([@ ~] t.t.topics.log)
=* parent=@ i.t.t.topics.log
:: If the sponsor we lost was not our actual sponsor, we didn't
:: actually lose anything.
::
?. =(parent who.sponsor.net.point) ~
::
=/ parent-point (get-point state parent)
?> ?=(^ parent-point)
::
:: We can detach even if the child is on L2, as long as the parent
:: is on L1.
::
?: ?=(%l2 -.u.parent-point) ~
:+ ~ [%point ship %sponsor ~]~
point(has.sponsor.net %|)
::
:: The rest can be done by any ship on L1, even if their spawn proxy
:: is set to L2
::
?: ?=(%l2 -.point) ~
::
?: =(log-name escape-requested:log-names)
?> ?=([@ ~] t.t.topics.log)
=* parent=@ i.t.t.topics.log
=/ parent-point (get-point state parent)
?> ?=(^ parent-point)
:+ ~ [%point ship %escape `parent]~
point(escape.net `parent)
::
?: =(log-name escape-canceled:log-names)
?> ?=([@ ~] t.t.topics.log)
=* parent=@ i.t.t.topics.log
=/ parent-point (get-point state parent)
?> ?=(^ parent-point)
:+ ~ [%point ship %escape ~]~
point(escape.net ~)
::
?: =(log-name broke-continuity:log-names)
?> ?=(~ t.t.topics.log)
=* rift=@ data.log
:+ ~ [%point ship %rift rift]~
point(rift.net rift)
::
?: =(log-name changed-keys:log-names)
?> ?=(~ t.t.topics.log)
=/ =keys
:* life=(cut 8 [0 1] data.log)
suite=(cut 8 [1 1] data.log)
auth=(cut 8 [2 1] data.log)
crypt=(cut 8 [3 1] data.log)
==
:+ ~ [%point ship %keys keys]~
point(keys.net keys)
::
?: =(log-name owner-changed:log-names)
?> ?=([@ ~] t.t.topics.log)
=* to i.t.t.topics.log
:: Depositing to L2 is represented by an ownership change on L1,
:: but it doesn't change who actually owns the ship.
::
?: =(deposit-address to)
:+ ~ [%point ship %dominion %l2]~
point(dominion %l2)
:+ ~ [%point ship %owner to]~
point(address.owner.own to)
::
?: =(log-name changed-transfer-proxy:log-names)
?> ?=([@ ~] t.t.topics.log)
=* to i.t.t.topics.log
:+ ~ [%point ship %transfer-proxy to]~
point(address.transfer-proxy.own to)
::
?: =(log-name changed-management-proxy:log-names)
?> ?=([@ ~] t.t.topics.log)
=* to i.t.t.topics.log
:+ ~ [%point ship %management-proxy to]~
point(address.management-proxy.own to)
::
?: =(log-name changed-voting-proxy:log-names)
?> ?=([@ ~] t.t.topics.log)
=* to i.t.t.topics.log
:+ ~ [%point ship %voting-proxy to]~
point(address.voting-proxy.own to)
::
(debug %unknown-log ~)
::
:: Receive batch of L2 transactions
::
++ receive-batch
|= [=verifier chain-id=@ud =state batch=@]
=/ chain-t (ud-to-ascii chain-id)
=/ =roll (parse-roll batch)
|- ^- [effects ^state]
?~ roll
[~ state]
:: Verify signature, else skip tx
::
?. (verify-sig-and-nonce verifier chain-t state i.roll)
%+ debug %l2-sig-failed
=^ effects state $(roll t.roll)
:_ state
[[%tx i.roll `%sig-or-nonce-failed] effects]
:: Increment nonce, even if it later fails
::
=^ effects-1 points.state (increment-nonce state from.tx.i.roll)
:: Process tx
::
=^ effects-2 state
=/ tx-result=(unit [=effects =^state]) (receive-tx state tx.i.roll)
?~ tx-result
%+ debug %l2-tx-failed
[[%tx i.roll `%tx-failed]~ state]
[[[%tx i.roll ~] effects.u.tx-result] state.u.tx-result]
=^ effects-3 state $(roll t.roll)
[:(welp effects-1 effects-2 effects-3) state]
::
++ increment-nonce
|= [=state =ship =proxy]
=/ point (get-point state ship)
?> ?=(^ point) :: we only parsed 4 bytes
=* own own.u.point
=^ nonce u.point
?- proxy
%own
:- nonce.owner.own
u.point(nonce.owner.own +(nonce.owner.own))
::
%spawn
:- nonce.spawn-proxy.own
u.point(nonce.spawn-proxy.own +(nonce.spawn-proxy.own))
::
%manage
:- nonce.management-proxy.own
u.point(nonce.management-proxy.own +(nonce.management-proxy.own))
::
%vote
:- nonce.voting-proxy.own
u.point(nonce.voting-proxy.own +(nonce.voting-proxy.own))
::
%transfer
:- nonce.transfer-proxy.own
u.point(nonce.transfer-proxy.own +(nonce.transfer-proxy.own))
==
::
:- [%nonce ship proxy nonce]~
(put:orm points.state ship u.point)
::
:: Receive an individual L2 transaction
::
++ receive-tx
|= [=state =tx]
|^
^- (unit [effects ^state])
?- +<.tx
%spawn (process-spawn +>.tx)
%transfer-point (w-point process-transfer-point ship.from.tx +>.tx)
%configure-keys (w-point process-configure-keys ship.from.tx +>.tx)
%escape (w-point-esc process-escape ship.from.tx +>.tx)
%cancel-escape (w-point-esc process-cancel-escape ship.from.tx +>.tx)
%adopt (w-point-esc process-adopt ship.tx +>.tx)
%reject (w-point-esc process-reject ship.tx +>.tx)
%detach (w-point-esc process-detach ship.tx +>.tx)
%set-spawn-proxy
(w-point-spawn process-set-spawn-proxy ship.from.tx +>.tx)
::
%set-transfer-proxy
(w-point process-set-transfer-proxy ship.from.tx +>.tx)
::
%set-management-proxy
(w-point process-set-management-proxy ship.from.tx +>.tx)
==
::
++ w-point
|* [fun=$-([ship point *] (unit [effects point])) =ship rest=*]
^- (unit [effects ^state])
=/ point (get-point state ship)
?~ point (debug %strange-ship ~)
?. ?=(%l2 -.u.point) (debug %ship-not-on-l2 ~)
:: Important to fully no-op on failure so we don't insert an entry
:: into points.state
::
=/ res=(unit [=effects new-point=^point]) (fun u.point rest)
?~ res
~
`[effects.u.res state(points (put:orm points.state ship new-point.u.res))]
::
++ w-point-esc
|* [fun=$-([ship point *] (unit [effects point])) =ship rest=*]
^- (unit [effects ^state])
=/ point (get-point state ship)
?~ point (debug %strange-ship ~)
=/ res=(unit [=effects new-point=^point]) (fun u.point rest)
?~ res
~
`[effects.u.res state(points (put:orm points.state ship new-point.u.res))]
::
++ w-point-spawn
|* [fun=$-([ship point *] (unit [effects point])) =ship rest=*]
^- (unit [effects ^state])
=/ point (get-point state ship)
?~ point (debug %strange-ship ~)
?: ?=(%l1 -.u.point) (debug %ship-on-l2 ~)
=/ res=(unit [=effects new-point=^point]) (fun u.point rest)
?~ res
~
`[effects.u.res state(points (put:orm points.state ship new-point.u.res))]
::
++ process-transfer-point
|= [=point to=address reset=?]
=* ship ship.from.tx
:: Assert from owner or transfer prxoy
::
?. |(=(%own proxy.from.tx) =(%transfer proxy.from.tx))
(debug %bad-permission ~)
:: Execute transfer
::
=/ effects-1
~[[%point ship %owner to] [%point ship %transfer-proxy *address]]
=: address.owner.own.point to
address.transfer-proxy.own.point *address
==
:: Execute reset if requested
::
?. reset
`[effects-1 point]
::
=^ effects-2 net.point
?: =([0 0 0] +.keys.net.point)
`net.point
=/ =keys [+(life.keys.net.point) 0 0 0]
:- [%point ship %keys keys]~
[rift.net.point keys sponsor.net.point escape.net.point]
=^ effects-3 rift.net.point
?: =(0 life.keys.net.point)
`rift.net.point
:- [%point ship %rift +(rift.net.point)]~
+(rift.net.point)
=/ effects-4
:~ [%point ship %spawn-proxy *address]
[%point ship %management-proxy *address]
[%point ship %voting-proxy *address]
[%point ship %transfer-proxy *address]
==
=: address.spawn-proxy.own.point *address
address.management-proxy.own.point *address
address.voting-proxy.own.point *address
address.transfer-proxy.own.point *address
==
`[:(welp effects-1 effects-2 effects-3 effects-4) point]
::
++ process-spawn
|= [=ship to=address]
^- (unit [effects ^state])
=/ parent=^ship (sein ship)
:: Assert parent is on L2
::
=/ parent-point (get-point state parent)
?~ parent-point ~
?. ?=(?(%l2 %spawn) -.u.parent-point) ~
:: Assert from owner or spawn proxy
::
?. ?& =(parent ship.from.tx)
|(=(%own proxy.from.tx) =(%spawn proxy.from.tx))
==
(debug %bad-permission ~)
:: Assert child not already spawned
::
?^ (get:orm points.state ship) (debug %spawn-exists ~)
:: Assert one-level-down
::
?. =(+((ship-rank parent)) (ship-rank ship)) (debug %bad-rank ~)
::
=/ [=effects new-point=point]
=/ point=(unit point) (get-point state ship)
?> ?=(^ point) :: only parsed 4 bytes
:: If spawning to self, just do it
::
?: ?| ?& =(%own proxy.from.tx)
=(to address.owner.own.u.parent-point)
==
?& =(%spawn proxy.from.tx)
=(to address.spawn-proxy.own.u.parent-point)
==
==
:- ~[[%point ship %dominion %l2] [%point ship %owner to]]
u.point(address.owner.own to)
:: Else spawn to parent and set transfer proxy
::
:- :~ [%point ship %dominion %l2]
[%point ship %owner address.owner.own.u.parent-point]
[%point ship %transfer-proxy to]
==
%= u.point
address.owner.own address.owner.own.u.parent-point
address.transfer-proxy.own to
==
`[effects state(points (put:orm points.state ship new-point))]
::
++ process-configure-keys
|= [=point crypt=@ auth=@ suite=@ breach=?]
=* ship ship.from.tx
::
?. |(=(%own proxy.from.tx) =(%manage proxy.from.tx))
(debug %bad-permission ~)
::
=^ rift-effects rift.net.point
?. breach
`rift.net.point
[[%point ship %rift +(rift.net.point)]~ +(rift.net.point)]
::
=^ keys-effects keys.net.point
?: =(+.keys.net.point [suite auth crypt])
`keys.net.point
=/ =keys
[+(life.keys.net.point) suite auth crypt]
[[%point ship %keys keys]~ keys]
::
`[(welp rift-effects keys-effects) point]
::
++ process-escape
|= [=point parent=ship]
=* ship ship.from.tx
?. |(=(%own proxy.from.tx) =(%manage proxy.from.tx))
(debug %bad-permission ~)
::
?. =(+((ship-rank parent)) (ship-rank ship))
(debug %bad-rank ~)
::
:+ ~ [%point ship %escape `parent]~
point(escape.net `parent)
::
++ process-cancel-escape
|= [=point parent=ship]
=* ship ship.from.tx
?. |(=(%own proxy.from.tx) =(%manage proxy.from.tx))
(debug %bad-permission ~)
::
:+ ~ [%point ship %escape ~]~
point(escape.net ~)
::
++ process-adopt
|= [=point =ship]
=* parent ship.from.tx
?. |(=(%own proxy.from.tx) =(%manage proxy.from.tx))
(debug %bad-permission ~)
::
?. =(escape.net.point `parent) (debug %no-adopt ~)
:+ ~ [%point ship %sponsor `parent]~
point(escape.net ~, sponsor.net [%& parent])
::
++ process-reject
|= [=point =ship]
=* parent ship.from.tx
?. |(=(%own proxy.from.tx) =(%manage proxy.from.tx))
(debug %bad-permission ~)
::
?. =(escape.net.point `parent) (debug %no-reject ~)
:+ ~ [%point ship %escape ~]~
point(escape.net ~)
::
++ process-detach
|= [=point =ship]
=* parent ship.from.tx
?. |(=(%own proxy.from.tx) =(%manage proxy.from.tx))
(debug %bad-permission ~)
::
?. =(who.sponsor.net.point parent) (debug %no-detach ~)
:+ ~ [%point ship %sponsor ~]~
point(has.sponsor.net %|)
::
++ process-set-management-proxy
|= [=point =address]
?. |(=(%own proxy.from.tx) =(%manage proxy.from.tx))
(debug %bad-permission ~)
::
:+ ~ [%point ship.from.tx %management-proxy address]~
point(address.management-proxy.own address)
::
++ process-set-spawn-proxy
|= [=point =address]
?. |(=(%own proxy.from.tx) =(%spawn proxy.from.tx))
(debug %bad-permission ~)
::
?: (gte (ship-rank ship.from.tx) 2)
(debug %spawn-proxy-planet ~)
::
:+ ~ [%point ship.from.tx %spawn-proxy address]~
point(address.spawn-proxy.own address)
::
++ process-set-transfer-proxy
|= [=point =address]
?. |(=(%own proxy.from.tx) =(%transfer proxy.from.tx))
(debug %bad-permission ~)
::
:+ ~ [%point ship.from.tx %transfer-proxy address]~
point(address.transfer-proxy.own address)
--
--
::
:: State transition function
::
|= [=verifier chain-id=@ud =state =input]
^- [effects ^state]
?: ?=(%log +<.input)
:: Received log from L1 transaction
::
(receive-log state event-log.input)
:: Received L2 batch
::
:: %+ debug %batch
(receive-batch verifier chain-id state batch.input)

670
pkg/arvo/lib/tiny.hoon Normal file
View File

@ -0,0 +1,670 @@
!.
=> %a50
~% %a.50 ~ ~
|%
:: Types
::
+$ ship @p
+$ life @ud
+$ rift @ud
+$ pass @
+$ bloq @
+$ step _`@u`1
+$ bite $@(bloq [=bloq =step])
+$ octs [p=@ud q=@]
+$ mold $~(* $-(* *))
++ unit |$ [item] $@(~ [~ u=item])
++ list |$ [item] $@(~ [i=item t=(list item)])
++ lest |$ [item] [i=item t=(list item)]
++ tree |$ [node] $@(~ [n=node l=(tree node) r=(tree node)])
++ pair |$ [head tail] [p=head q=tail]
++ map
|$ [key value]
$| (tree (pair key value))
|=(a=(tree (pair)) ?:(=(~ a) & ~(apt by a)))
::
++ set
|$ [item]
$| (tree item)
|=(a=(tree) ?:(=(~ a) & ~(apt in a)))
::
++ jug |$ [key value] (map key (set value))
::
:: Bits
::
++ dec :: decrement
~/ %dec
|= a=@
~_ leaf+"decrement-underflow"
?< =(0 a)
=+ b=0
|- ^- @
?: =(a +(b)) b
$(b +(b))
::
++ add :: plus
~/ %add
|= [a=@ b=@]
^- @
?: =(0 a) b
$(a (dec a), b +(b))
::
++ sub :: subtract
~/ %sub
|= [a=@ b=@]
~_ leaf+"subtract-underflow"
:: difference
^- @
?: =(0 b) a
$(a (dec a), b (dec b))
::
++ mul :: multiply
~/ %mul
|: [a=`@`1 b=`@`1]
^- @
=+ c=0
|-
?: =(0 a) c
$(a (dec a), c (add b c))
::
++ div :: divide
~/ %div
|: [a=`@`1 b=`@`1]
^- @
~_ leaf+"divide-by-zero"
?< =(0 b)
=+ c=0
|-
?: (lth a b) c
$(a (sub a b), c +(c))
::
++ dvr :: divide w/remainder
~/ %dvr
|: [a=`@`1 b=`@`1]
^- [p=@ q=@]
[(div a b) (mod a b)]
::
++ mod :: modulus
~/ %mod
|: [a=`@`1 b=`@`1]
^- @
?< =(0 b)
(sub a (mul b (div a b)))
::
++ bex :: binary exponent
~/ %bex
|= a=bloq
^- @
?: =(0 a) 1
(mul 2 $(a (dec a)))
::
++ lsh :: left-shift
~/ %lsh
|= [a=bite b=@]
=/ [=bloq =step] ?^(a a [a *step])
(mul b (bex (mul (bex bloq) step)))
::
++ rsh :: right-shift
~/ %rsh
|= [a=bite b=@]
=/ [=bloq =step] ?^(a a [a *step])
(div b (bex (mul (bex bloq) step)))
::
++ con :: binary or
~/ %con
|= [a=@ b=@]
=+ [c=0 d=0]
|- ^- @
?: ?&(=(0 a) =(0 b)) d
%= $
a (rsh 0 a)
b (rsh 0 b)
c +(c)
d %+ add d
%+ lsh [0 c]
?& =(0 (end 0 a))
=(0 (end 0 b))
==
==
::
++ dis :: binary and
~/ %dis
|= [a=@ b=@]
=| [c=@ d=@]
|- ^- @
?: ?|(=(0 a) =(0 b)) d
%= $
a (rsh 0 a)
b (rsh 0 b)
c +(c)
d %+ add d
%+ lsh [0 c]
?| =(0 (end 0 a))
=(0 (end 0 b))
==
==
::
++ mix :: binary xor
~/ %mix
|= [a=@ b=@]
^- @
=+ [c=0 d=0]
|-
?: ?&(=(0 a) =(0 b)) d
%= $
a (rsh 0 a)
b (rsh 0 b)
c +(c)
d (add d (lsh [0 c] =((end 0 a) (end 0 b))))
==
::
++ lth :: less
~/ %lth
|= [a=@ b=@]
^- ?
?& !=(a b)
|-
?| =(0 a)
?& !=(0 b)
$(a (dec a), b (dec b))
== == ==
::
++ lte :: less or equal
~/ %lte
|= [a=@ b=@]
|(=(a b) (lth a b))
::
++ gte :: greater or equal
~/ %gte
|= [a=@ b=@]
^- ?
!(lth a b)
::
++ gth :: greater
~/ %gth
|= [a=@ b=@]
^- ?
!(lte a b)
::
++ swp :: naive rev bloq order
~/ %swp
|= [a=bloq b=@]
(rep a (flop (rip a b)))
::
++ met :: measure
~/ %met
|= [a=bloq b=@]
^- @
=+ c=0
|-
?: =(0 b) c
$(b (rsh a b), c +(c))
::
++ end :: tail
~/ %end
|= [a=bite b=@]
=/ [=bloq =step] ?^(a a [a *step])
(mod b (bex (mul (bex bloq) step)))
::
++ cat :: concatenate
~/ %cat
|= [a=bloq b=@ c=@]
(add (lsh [a (met a b)] c) b)
::
++ cut :: slice
~/ %cut
|= [a=bloq [b=step c=step] d=@]
(end [a c] (rsh [a b] d))
::
++ can :: assemble
~/ %can
|= [a=bloq b=(list [p=step q=@])]
^- @
?~ b 0
(add (end [a p.i.b] q.i.b) (lsh [a p.i.b] $(b t.b)))
::
++ cad :: assemble specific
~/ %cad
|= [a=bloq b=(list [p=step q=@])]
^- [=step @]
:_ (can a b)
|-
?~ b
0
(add p.i.b $(b t.b))
::
++ rep :: assemble fixed
~/ %rep
|= [a=bite b=(list @)]
=/ [=bloq =step] ?^(a a [a *step])
=| i=@ud
|- ^- @
?~ b 0
%+ add $(i +(i), b t.b)
(lsh [bloq (mul step i)] (end [bloq step] i.b))
::
++ rip :: disassemble
~/ %rip
|= [a=bite b=@]
^- (list @)
?: =(0 b) ~
[(end a b) $(b (rsh a b))]
::
::
:: Lists
::
++ lent :: length
~/ %lent
|= a=(list)
^- @
=+ b=0
|-
?~ a b
$(a t.a, b +(b))
::
++ slag :: suffix
~/ %slag
|* [a=@ b=(list)]
|- ^+ b
?: =(0 a) b
?~ b ~
$(b t.b, a (dec a))
::
++ snag :: index
~/ %snag
|* [a=@ b=(list)]
|- ^+ ?>(?=(^ b) i.b)
?~ b
~_ leaf+"snag-fail"
!!
?: =(0 a) i.b
$(b t.b, a (dec a))
::
++ homo :: homogenize
|* a=(list)
^+ =< $
|@ ++ $ ?:(*? ~ [i=(snag 0 a) t=$])
--
a
::
++ flop :: reverse
~/ %flop
|* a=(list)
=> .(a (homo a))
^+ a
=+ b=`_a`~
|-
?~ a b
$(a t.a, b [i.a b])
::
++ welp :: concatenate
~/ %welp
=| [* *]
|@
++ $
?~ +<-
+<-(. +<+)
+<-(+ $(+<- +<->))
--
::
++ reap :: replicate
~/ %reap
|* [a=@ b=*]
|- ^- (list _b)
?~ a ~
[b $(a (dec a))]
::
:: Modular arithmetic
::
++ fe :: modulo bloq
|_ a=bloq
++ rol |= [b=bloq c=@ d=@] ^- @ :: roll left
=+ e=(sit d)
=+ f=(bex (sub a b))
=+ g=(mod c f)
(sit (con (lsh [b g] e) (rsh [b (sub f g)] e)))
++ sum |=([b=@ c=@] (sit (add b c))) :: wrapping add
++ sit |=(b=@ (end a b)) :: enforce modulo
--
::
:: Hashes
::
++ muk :: standard murmur3
~% %muk ..muk ~
=+ ~(. fe 5)
|= [syd=@ len=@ key=@]
=. syd (end 5 syd)
=/ pad (sub len (met 3 key))
=/ data (welp (rip 3 key) (reap pad 0))
=/ nblocks (div len 4) :: intentionally off-by-one
=/ h1 syd
=+ [c1=0xcc9e.2d51 c2=0x1b87.3593]
=/ blocks (rip 5 key)
=/ i nblocks
=. h1 =/ hi h1 |-
?: =(0 i) hi
=/ k1 (snag (sub nblocks i) blocks) :: negative array index
=. k1 (sit (mul k1 c1))
=. k1 (rol 0 15 k1)
=. k1 (sit (mul k1 c2))
=. hi (mix hi k1)
=. hi (rol 0 13 hi)
=. hi (sum (sit (mul hi 5)) 0xe654.6b64)
$(i (dec i))
=/ tail (slag (mul 4 nblocks) data)
=/ k1 0
=/ tlen (dis len 3)
=. h1
?+ tlen h1 :: fallthrough switch
%3 =. k1 (mix k1 (lsh [0 16] (snag 2 tail)))
=. k1 (mix k1 (lsh [0 8] (snag 1 tail)))
=. k1 (mix k1 (snag 0 tail))
=. k1 (sit (mul k1 c1))
=. k1 (rol 0 15 k1)
=. k1 (sit (mul k1 c2))
(mix h1 k1)
%2 =. k1 (mix k1 (lsh [0 8] (snag 1 tail)))
=. k1 (mix k1 (snag 0 tail))
=. k1 (sit (mul k1 c1))
=. k1 (rol 0 15 k1)
=. k1 (sit (mul k1 c2))
(mix h1 k1)
%1 =. k1 (mix k1 (snag 0 tail))
=. k1 (sit (mul k1 c1))
=. k1 (rol 0 15 k1)
=. k1 (sit (mul k1 c2))
(mix h1 k1)
==
=. h1 (mix h1 len)
|^ (fmix32 h1)
++ fmix32
|= h=@
=. h (mix h (rsh [0 16] h))
=. h (sit (mul h 0x85eb.ca6b))
=. h (mix h (rsh [0 13] h))
=. h (sit (mul h 0xc2b2.ae35))
=. h (mix h (rsh [0 16] h))
h
--
::
++ mug :: mug with murmur3
~/ %mug
|= a=*
|^ ?@ a (mum 0xcafe.babe 0x7fff a)
=/ b (cat 5 $(a -.a) $(a +.a))
(mum 0xdead.beef 0xfffe b)
::
++ mum
|= [syd=@uxF fal=@F key=@]
=/ wyd (met 3 key)
=| i=@ud
|- ^- @F
?: =(8 i) fal
=/ haz=@F (muk syd wyd key)
=/ ham=@F (mix (rsh [0 31] haz) (end [0 31] haz))
?.(=(0 ham) ham $(i +(i), syd +(syd)))
--
::
++ gor :: mug order
~/ %gor
|= [a=* b=*]
^- ?
=+ [c=(mug a) d=(mug b)]
?: =(c d)
(dor a b)
(lth c d)
::
++ mor :: more mug order
~/ %mor
|= [a=* b=*]
^- ?
=+ [c=(mug (mug a)) d=(mug (mug b))]
?: =(c d)
(dor a b)
(lth c d)
::
++ dor :: tree order
~/ %dor
|= [a=* b=*]
^- ?
?: =(a b) &
?. ?=(@ a)
?: ?=(@ b) |
?: =(-.a -.b)
$(a +.a, b +.b)
$(a -.a, b -.b)
?. ?=(@ b) &
(lth a b)
::
++ por :: parent order
~/ %por
|= [a=@p b=@p]
^- ?
?: =(a b) &
=| i=@
|-
?: =(i 2)
:: second two bytes
(lte a b)
:: first two bytes
=+ [c=(end 3 a) d=(end 3 b)]
?: =(c d)
$(a (rsh 3 a), b (rsh 3 b), i +(i))
(lth c d)
::
:: Maps
::
++ by
~/ %by
=| a=(tree (pair)) :: (map)
=* node ?>(?=(^ a) n.a)
|@
++ get
~/ %get
|* b=*
=> .(b `_?>(?=(^ a) p.n.a)`b)
|- ^- (unit _?>(?=(^ a) q.n.a))
?~ a
~
?: =(b p.n.a)
`q.n.a
?: (gor b p.n.a)
$(a l.a)
$(a r.a)
::
++ put
~/ %put
|* [b=* c=*]
|- ^+ a
?~ a
[[b c] ~ ~]
?: =(b p.n.a)
?: =(c q.n.a)
a
a(n [b c])
?: (gor b p.n.a)
=+ d=$(a l.a)
?> ?=(^ d)
?: (mor p.n.a p.n.d)
a(l d)
d(r a(l r.d))
=+ d=$(a r.a)
?> ?=(^ d)
?: (mor p.n.a p.n.d)
a(r d)
d(l a(r l.d))
::
++ del
~/ %del
|* b=*
|- ^+ a
?~ a
~
?. =(b p.n.a)
?: (gor b p.n.a)
a(l $(a l.a))
a(r $(a r.a))
|- ^- [$?(~ _a)]
?~ l.a r.a
?~ r.a l.a
?: (mor p.n.l.a p.n.r.a)
l.a(r $(l.a r.l.a))
r.a(l $(r.a l.r.a))
::
++ apt
=< $
~/ %apt
=| [l=(unit) r=(unit)]
|. ^- ?
?~ a &
?& ?~(l & &((gor p.n.a u.l) !=(p.n.a u.l)))
?~(r & &((gor u.r p.n.a) !=(u.r p.n.a)))
?~ l.a &
&((mor p.n.a p.n.l.a) !=(p.n.a p.n.l.a) $(a l.a, l `p.n.a))
?~ r.a &
&((mor p.n.a p.n.r.a) !=(p.n.a p.n.r.a) $(a r.a, r `p.n.a))
==
--
::
++ on :: ordered map
~/ %on
|* [key=mold val=mold]
=> |%
+$ item [key=key val=val]
--
::
~% %comp +>+ ~
|= compare=$-([key key] ?)
~% %core + ~
|%
::
++ apt
~/ %apt
|= a=(tree item)
=| [l=(unit key) r=(unit key)]
|- ^- ?
?~ a %.y
?& ?~(l %.y (compare key.n.a u.l))
?~(r %.y (compare u.r key.n.a))
?~(l.a %.y &((mor key.n.a key.n.l.a) $(a l.a, l `key.n.a)))
?~(r.a %.y &((mor key.n.a key.n.r.a) $(a r.a, r `key.n.a)))
==
::
++ get
~/ %get
|= [a=(tree item) b=key]
^- (unit val)
?~ a ~
?: =(b key.n.a)
`val.n.a
?: (compare b key.n.a)
$(a l.a)
$(a r.a)
::
++ has
~/ %has
|= [a=(tree item) b=key]
^- ?
!=(~ (get a b))
::
++ put
~/ %put
|= [a=(tree item) =key =val]
^- (tree item)
?~ a [n=[key val] l=~ r=~]
?: =(key.n.a key) a(val.n val)
?: (compare key key.n.a)
=/ l $(a l.a)
?> ?=(^ l)
?: (mor key.n.a key.n.l)
a(l l)
l(r a(l r.l))
=/ r $(a r.a)
?> ?=(^ r)
?: (mor key.n.a key.n.r)
a(r r)
r(l a(r l.r))
--
::
:: Sets
::
++ in
~/ %in
=| a=(tree) :: (set)
|@
++ put
~/ %put
|* b=*
|- ^+ a
?~ a
[b ~ ~]
?: =(b n.a)
a
?: (gor b n.a)
=+ c=$(a l.a)
?> ?=(^ c)
?: (mor n.a n.c)
a(l c)
c(r a(l r.c))
=+ c=$(a r.a)
?> ?=(^ c)
?: (mor n.a n.c)
a(r c)
c(l a(r l.c))
::
++ del
~/ %del
|* b=*
|- ^+ a
?~ a
~
?. =(b n.a)
?: (gor b n.a)
a(l $(a l.a))
a(r $(a r.a))
|- ^- [$?(~ _a)]
?~ l.a r.a
?~ r.a l.a
?: (mor n.l.a n.r.a)
l.a(r $(l.a r.l.a))
r.a(l $(r.a l.r.a))
::
++ apt
=< $
~/ %apt
=| [l=(unit) r=(unit)]
|. ^- ?
?~ a &
?& ?~(l & (gor n.a u.l))
?~(r & (gor u.r n.a))
?~(l.a & ?&((mor n.a n.l.a) $(a l.a, l `n.a)))
?~(r.a & ?&((mor n.a n.r.a) $(a r.a, r `n.a)))
==
--
::
:: Jugs
::
++ ju
=| a=(tree (pair * (tree))) :: (jug)
|@
++ get
|* b=*
=+ c=(~(get by a) b)
?~(c ~ u.c)
::
++ del
|* [b=* c=*]
^+ a
=+ d=(get b)
=+ e=(~(del in d) c)
?~ e
(~(del by a) b)
(~(put by a) b e)
::
++ put
|* [b=* c=*]
^+ a
=+ d=(get b)
(~(put by a) b (~(put in d) c))
--
--

View File

@ -44,23 +44,10 @@
:: |give:dawn: produce requests for pre-boot validation
::
++ give
=, rpc:ethereum
=, abi:ethereum
=/ tract azimuth:contracts:azimuth
|%
:: +bloq:give:dawn: Eth RPC for latest block number
::
++ bloq
^- octs
%- as-octt:mimes:html
%- en-json:html
%+ request-to-json
`~.0
[%eth-block-number ~]
:: +czar:give:dawn: Eth RPC for galaxy table
::
++ czar
|= boq=@ud
^- octs
%- as-octt:mimes:html
%- en-json:html
@ -68,40 +55,43 @@
%+ turn (gulf 0 255)
|= gal=@
%+ request-to-json
`(cat 3 'gal-' (scot %ud gal))
:+ %eth-call
=- [from=~ to=tract gas=~ price=~ value=~ data=-]
(encode-call 'points(uint32)' [%uint gal]~)
[%number boq]
(cat 3 'gal-' (scot %ud gal))
:- 'getPoint'
(~(put by *(map @t json)) 'ship' s+(scot %p gal))
:: +point:give:dawn: Eth RPC for ship's contract state
::
++ point
|= [boq=@ud who=ship]
|= who=ship
^- octs
%- as-octt:mimes:html
%- en-json:html
%+ request-to-json
`~.0
:+ %eth-call
=- [from=~ to=tract gas=~ price=~ value=~ data=-]
(encode-call 'points(uint32)' [%uint `@`who]~)
[%number boq]
~.
:- 'getPoint'
(~(put by *(map @t json)) 'ship' s+(scot %p who))
:: +turf:give:dawn: Eth RPC for network domains
::
++ turf
|= boq=@ud
^- octs
%- as-octt:mimes:html
%- en-json:html
:- %a
%+ turn (gulf 0 2)
|= idx=@
%+ request-to-json
`(cat 3 'turf-' (scot %ud idx))
:+ %eth-call
=- [from=~ to=tract gas=~ price=~ value=~ data=-]
(encode-call 'dnsDomains(uint256)' [%uint idx]~)
[%number boq]
'turf'
['getDns' ~]
:: +request-to-json:give:dawn: internally used for request generation
::
::NOTE we could import this from /lib/json/rpc, but adding that as a
:: dependency seems a bit unclean
::
++ request-to-json
|= [id=@t method=@t params=(map @t json)]
^- json
%- pairs:enjs:format
:~ jsonrpc+s+'2.0'
id+s+id
method+s+method
params+o+params
==
--
:: |take:dawn: parse responses for pre-boot validation
::
@ -111,23 +101,6 @@
=, azimuth
=, dejs-soft:format
|%
:: +bloq:take:dawn: parse block number
::
++ bloq
|= rep=octs
^- (unit @ud)
=/ jon=(unit json) (de-json:html q.rep)
?~ jon
~&([%bloq-take-dawn %invalid-json] ~)
=/ res=(unit cord) ((ot result+so ~) u.jon)
?~ res
~&([%bloq-take-dawn %invalid-response rep] ~)
=/ out
%- mule |.
(hex-to-num:ethereum u.res)
?: ?=(%& -.out)
(some p.out)
~&([%bloq-take-dawn %invalid-block-number] ~)
:: +czar:take:dawn: parse galaxy table
::
++ czar
@ -136,58 +109,94 @@
=/ jon=(unit json) (de-json:html q.rep)
?~ jon
~&([%czar-take-dawn %invalid-json] ~)
=/ res=(unit (list [@t @t]))
((ar (ot id+so result+so ~)) u.jon)
=/ res=(unit (list [@t @ud @ud @]))
%. u.jon
=, dejs-soft:format
=- (ar (ot id+so result+(ot network+- ~) ~))
%- ot
:~ :- 'rift' (su dim:ag)
:- 'keys' (ot 'life'^(su dim:ag) ~)
:- 'keys' %+ cu pass-from-eth:azimuth
%- ot
:~ 'crypt'^(cu (lead 32) (su ;~(pfix (jest '0x') hex)))
'auth'^(cu (lead 32) (su ;~(pfix (jest '0x') hex)))
'suite'^(su dim:ag)
==
==
?~ res
~&([%czar-take-dawn %invalid-response rep] ~)
=/ dat=(unit (list [who=@p point:azimuth-types]))
=- ?:(?=(%| -.out) ~ (some p.out))
^= out %- mule |.
%+ turn u.res
|= [id=@t result=@t]
^- [who=ship point:azimuth-types]
=/ who `@p`(slav %ud (rsh [3 4] id))
:- who
%+ point-from-eth
who
:_ *deed:eth-noun
%+ decode-results
result
point:eth-type
?~ dat
~&([%bloq-take-dawn %invalid-galaxy-table] ~)
~&([%czar-take-dawn %incomplete-json] ~)
:- ~
%+ roll u.dat
|= $: [who=ship =point:azimuth-types]
%+ roll u.res
|= $: [id=@t deet=[=rift =life =pass]]
kyz=(map ship [=rift =life =pass])
==
^+ kyz
?~ net.point
?: =(0 life.deet)
kyz
(~(put by kyz) who [continuity-number life pass]:u.net.point)
%+ ~(put by kyz)
(slav %ud (rsh [3 4] id))
deet
:: +point:take:dawn: parse ship's contract state
::
++ point
|= [who=ship rep=octs]
^- (unit point:azimuth)
~! *point:azimuth
=/ jon=(unit json) (de-json:html q.rep)
?~ jon
~&([%point-take-dawn %invalid-json] ~)
=/ res=(unit cord) ((ot result+so ~) u.jon)
?~ res
~&([%point-take-dawn %invalid-response rep] ~)
~? =(u.res '0x')
:- 'bad result from node; is azimuth address correct?'
azimuth:contracts
=/ out
%- mule |.
%+ point-from-eth
who
:_ *deed:eth-noun ::TODO call rights to fill
(decode-results u.res point:eth-type)
?: ?=(%& -.out)
(some p.out)
~&([%point-take-dawn %invalid-point] ~)
=- ?~ res
~&([%point-take-dawn %incomplete-json] ~)
=, u.res
%- some
:+ own
?: =(0 life) ~
`[life pass rift sponsor ~] ::NOTE escape unknown ::TODO could be!
?. (gth who 0xffff) ~
`[spawn ~] ::NOTE spawned unknown
^- $= res
%- unit
$: [spawn=@ own=[@ @ @ @]]
[=rift =life =pass sponsor=[? ship]]
==
%. u.jon
=, dejs-soft:format
=- (ot result+- ~)
%- ot
:~ :- 'ownership'
%- ot
|^ :~ 'spawnProxy'^address
'owner'^address
'managementProxy'^address
'votingProxy'^address
'transferProxy'^address
==
::
++ address
(ot 'address'^(cu hex-to-num:ethereum so) ~)
--
::
:- 'network'
%- ot
::TODO dedupe with +czar
:~ 'rift'^(su dim:ag)
'keys'^(ot 'life'^(su dim:ag) ~)
::
:- 'keys'
%+ cu pass-from-eth:azimuth
%- ot
:~ 'crypt'^(cu (lead 32) (su ;~(pfix (jest '0x') hex)))
'auth'^(cu (lead 32) (su ;~(pfix (jest '0x') hex)))
'suite'^(su dim:ag)
==
::
::TODO inconsistent @p string
'sponsor'^(ot 'has'^bo 'who'^ni ~)
::
::TODO escape
::TODO what if escape or sponsor not present? possible?
==
==
:: +turf:take:dawn: parse network domains
::
++ turf
@ -196,38 +205,21 @@
=/ jon=(unit json) (de-json:html q.rep)
?~ jon
~&([%turf-take-dawn %invalid-json] ~)
=/ res=(unit (list [@t @t]))
((ar (ot id+so result+so ~)) u.jon)
=/ res=(unit (list @t))
((ot result+(ar so) ~) u.jon)
?~ res
~&([%turf-take-dawn %invalid-response rep] ~)
=/ dat=(unit (list (pair @ud ^turf)))
=- ?:(?=(%| -.out) ~ (some p.out))
^= out %- mule |.
%+ turn u.res
|= [id=@t result=@t]
^- (pair @ud ^turf)
:- (slav %ud (rsh [3 5] id))
=/ dom=tape
(decode-results result [%string]~)
=/ hot=host:eyre
(scan dom thos:de-purl:html)
?>(?=(%& -.hot) p.hot)
?~ dat
~&([%turf-take-dawn %invalid-domains] ~)
:- ~
=* dom u.dat
:: sort by id, ascending, removing duplicates
~&([%turf-take-dawn %invalid-response] ~)
:: remove duplicates, parse into turfs
::
=| tuf=(map ^turf @ud)
|- ^- (list ^turf)
?~ dom
%+ turn
%+ sort ~(tap by tuf)
|=([a=(pair ^turf @ud) b=(pair ^turf @ud)] (lth q.a q.b))
head
=? tuf !(~(has by tuf) q.i.dom)
(~(put by tuf) q.i.dom p.i.dom)
$(dom t.dom)
=- `doz
%+ roll u.res
|= [dom=@t doh=(set @t) doz=(list ^turf)]
?: (~(has in doh) dom) [doh doz]
:- (~(put in doh) dom)
=/ hot=host:eyre
(rash dom thos:de-purl:html)
?. ?=(%& -.hot) doz
(snoc doz p.hot)
--
:: +veri:dawn: validate keys, life, discontinuity, &c
::

View File

@ -0,0 +1,20 @@
:: list of ethereum logs
::
/+ ethereum
::
|_ logs=(list event-log:rpc:ethereum)
++ grab
|%
++ noun (list event-log:rpc:ethereum)
++ mime
|= [mite =octs]
(noun (cue q.octs))
--
::
++ grow
|%
++ mime
[/application/x-ethereum-logs (as-octs:mimes:html (jam logs))]
--
++ grad %mime
--

View File

@ -1,5 +1,5 @@
|%
+$ bump [%kiln-bump except=(set desk) force=_|]
+$ bump [except=(set desk) force=_|]
--
|_ b=bump
++ grad %noun
@ -9,7 +9,6 @@
++ json
^- $-(^json bump)
=, dejs:format
%+ pe %kiln-bump
%- ot
:~ except+(as so)
force+bo

96
pkg/arvo/sur/dice.hoon Normal file
View File

@ -0,0 +1,96 @@
:: dice: structures for L2 rollers
::
/+ naive, ethereum
::
|%
+$ owner [=proxy:naive =address:naive]
+$ owners (jug owner ship)
+$ sponsors (map ship [residents=(set ship) requests=(set ship)])
+$ net ?(%mainnet %ropsten %local %default)
::
+$ config
$% [%frequency frequency=@dr]
[%setkey pk=@]
[%endpoint endpoint=@t =net]
[%resend-time time=@dr]
[%update-rate rate=@dr]
[%slice slice=@dr]
[%quota quota=@ud]
==
::
+$ indices
$: nas=^state:naive
own=owners
spo=sponsors
==
::
+$ azimuth-config
$: refresh-rate=@dr
==
::
+$ roller-config
$: next-batch=time
frequency=@dr
resend-time=@dr
update-rate=@dr
contract=@ux
chain-id=@
slice=@dr
quota=@ud
==
::
+$ keccak @ux
::
+$ status
?(%unknown %pending %sending %confirmed %failed %cancelled)
::
+$ tx-status
$: =status
pointer=(unit l1-tx-pointer)
==
::
+$ l1-tx-pointer
$: =address:ethereum
nonce=@ud
==
::
+$ l2-tx
$? %transfer-point
%spawn
%configure-keys
%escape
%cancel-escape
%adopt
%reject
%detach
%set-management-proxy
%set-spawn-proxy
%set-transfer-proxy
==
::
+$ update
$% [%point =ship =point:naive new=owner old=(unit owner)]
[%tx =address:ethereum =roll-tx]
==
::
+$ hist-tx [p=time q=roll-tx]
+$ roll-tx [=ship =status hash=keccak type=l2-tx]
+$ pend-tx [force=? =address:naive =time =raw-tx:naive]
+$ send-tx [next-gas-price=@ud sent=? txs=(list raw-tx:naive)]
+$ part-tx
$% [%raw raw=octs]
[%don =tx:naive]
[%ful raw=octs =tx:naive] ::TODO redundant?
==
::
+$ rpc-send-roll
$: endpoint=@t
contract=address:ethereum
chain-id=@
pk=@
::
nonce=@ud
next-gas-price=@ud
txs=(list raw-tx:naive)
==
--

View File

@ -18,6 +18,7 @@
timeout-time=@dr
from=number:block
contracts=(list address:ethereum)
batchers=(list address:ethereum)
=topics
==
::

View File

@ -1 +1 @@
[%zuse 420]
[%zuse 419]

View File

@ -5962,7 +5962,14 @@
++ spat |=(pax=path (crip (spud pax))) :: render path to cord
++ spud |=(pax=path ~(ram re (smyt pax))) :: render path to tape
++ stab |=(zep=@t `path`(rash zep stap)) :: parse cord to path
++ stap ;~(pfix fas (more fas urs:ab)) :: path parser
++ stap :: path parser
%+ sear
|= p=path
^- (unit path)
?: ?=([~ ~] p) `~
?. =(~ (rear p)) `p
~
;~(pfix fas (most fas urs:ab))
::
:::: 4n: virtualization
::
@ -9247,144 +9254,6 @@
hag [q.p.dix q.q.dix]
==
::
++ ad
|%
++ arc
|%
++ deft :: generic
|%
++ bath * :: leg match type
++ claw * :: arm match type
++ form |*([* *] p=+<-) :: attach build state
++ skin |*(p=* p) :: reveal build state
++ meat |*(p=* p) :: remove build state
--
++ make :: for mint
|%
++ bath type :: leg match type
++ claw onyx :: arm
++ form |*([* *] [p=+<- q=+<+]) ::
++ skin |*([p=* q=*] q) :: unwrap baggage
++ meat |*([p=* q=*] p) :: unwrap filling
--
--
++ def
=+ deft:arc
|@ ++ $
=> +<
|%
++ pord |*(* (form +< *nock)) :: wrap mint formula
++ rosh |*(* (form +< *(list pock))) :: wrap mint changes
++ fleg _(pord $:bath) :: legmatch + code
++ fram _(pord $:claw) :: armmatch +
++ foat _(rosh $:bath) :: leg with changes
++ fult _(rosh $:claw) :: arm with changes
-- --
::
++ lib
|%
++ deft
=> (def deft:arc)
|%
++ halp ^|(|:($:hoon $:fleg))
++ vant
|% ++ trep ^|(|:($:,[bath wing bath] $:,[axis bath]))
++ tasp ^|(|:($:,[[axis bath] fleg foat] $:foat))
++ tyle ^|(|:($:foat $:foat))
--
++ vunt
|% ++ trep ^|(|:($:,[claw wing bath] $:,[axis claw]))
++ tasp ^|(|:($:,[[axis claw] fleg fult] $:fult))
++ tyle ^|(|:($:fult $:foat))
-- --
::
++ make
=> (def make:arc)
|%
++ halp |~ a=hoon
^- fleg
(mint %noun a)
++ vant
|% ++ trep |: $:,[a=type b=wing c=type]
^- [axis type]
(tack(sut a) b c)
++ tasp |: $:,[a=(pair axis type) b=fleg c=foat]
^- foat
[q.a [[p.a (skin b)] (skin c)]]
++ tyle |:($:foat +<)
--
++ vunt
|% ++ trep |: $:,[a=claw b=wing c=bath]
^- (pair axis claw)
(toss b c a)
++ tasp |: $:,[a=(pair axis claw) b=fleg c=fult]
^- fult
[q.a [[p.a (skin b)] (skin c)]]
++ tyle |: $:fult
^- foat
[(fire +<-) +<+]
-- -- --
::
++ bin
=+ deft:lib
|@ ++ $
=> +<
|%
++ rame
=> vant |%
++ clom bath
++ chog fleg
++ ceut foat
--
++ gelp
=> vunt |%
++ clom claw
++ chog fram
++ ceut fult
--
++ ecbo (ecco rame)
++ eclo (ecco gelp)
++ ecco
=+ rame
|@ ++ $
=> +<
|: $:,[rum=clom rig=(list (pair wing hoon))]
^- foat
%- tyle
|- ^- ceut
?~ rig (rosh rum)
=+ mor=$(rig t.rig)
=+ zil=(halp q.i.rig)
=+ dar=(trep (meat mor) p.i.rig (meat zil))
(tasp dar zil mor)
-- -- -- --
::
++ oc
=+ inc=(bin:ad)
|@ ++ $
=> inc
|%
++ echo
|: $:,[rum=bath rig=(list (pair wing hoon))]
(ecbo rum rig)
::
++ ecmo
|: $:,[hag=claw rig=(list (pair wing hoon))]
(eclo hag rig)
-- --
::
++ etco
|= [lop=palo rig=(list (pair wing hoon))]
^- (pair type nock)
=+ cin=(oc (bin:ad make:lib:ad))
=. rig (flop rig) :: XX this unbreaks, void order in devulc
=+ axe=(tend p.lop)
?: ?=(%& -.q.lop)
=- [p.- (hike axe q.-)]
(echo:cin p.q.lop rig)
=- [p.- [%9 p.q.lop (hike axe q.-)]]
(ecmo:cin ~(tap in q.q.lop) rig)
::
++ et
|_ [hyp=wing rig=(list (pair wing hoon))]
::
@ -9400,7 +9269,7 @@
=+ lug=(find %read hyp)
?: ?=(%| -.lug) ~>(%mean.'hoon' ?>(?=(~ rig) p.lug))
=- ?>(?|(!vet (nest(sut gol) & p.-)) -)
(etco p.lug rig)
(ergo p.lug rig)
::
++ mull
|= [gol=type dox=type]
@ -10088,7 +9957,6 @@
[(nice %noun) [%2 q:$(gen p.gen, gol %noun) q:$(gen q.gen, gol %noun)]]
::
[%dtts *]
=+ [one two]=[$(gen p.gen, gol %noun) $(gen q.gen, gol %noun)]
[(nice bool) [%5 q:$(gen p.gen, gol %noun) q:$(gen q.gen, gol %noun)]]
::
[%dtwt *] [(nice bool) [%3 q:$(gen p.gen, gol %noun)]]

View File

@ -850,7 +850,7 @@
+$ mool [=case paths=(set (pair care path))] :: requests in desk
+$ nori :: repository action
$% [%& p=soba] :: delta
[%| p=@tas] :: label
[%| p=@tas q=(unit aeon)] :: label
== ::
+$ nuri :: repository action
$% [%& p=suba] :: delta
@ -1906,6 +1906,7 @@
[%private-keys ~] :: sub to privates
[%public-keys ships=(set ship)] :: sub to publics
[%rekey =life =ring] :: update private keys
[%ruin ships=(set ship)] :: pretend breach
$>(%trim vane-task) :: trim state
[%turf ~] :: view domains
$>(%vega vane-task) :: report upgrade

View File

@ -1445,6 +1445,32 @@
==
==
::
:: Attach label to aeon
::
++ label
|= [bel=@tas aey=(unit aeon)]
^+ ..park
=/ yon ?~(aey let.dom u.aey)
=/ yen (~(get by lab.dom) bel) :: existing aeon?
:: no existing aeon is bound to this label
::
?~ yen
=. lab.dom (~(put by lab.dom) bel yon)
..park
:: an aeon is bound to this label,
:: but it is the same as the existing one, so we no-op
::
?: =(u.yen yon)
~& "clay: tried to rebind existing label {<bel>} to equivalent aeon {<yon>}"
..park
:: an existing aeon bound to the label
:: that is distinct from the requested one.
:: rewriting would violate referential transparency
::
~| %tried-to-rewrite-existing-label
~| "requested aeon: {<yon>}, existing aeon: {<u.yen>}"
!!
::
:: Porcelain commit
::
++ info
@ -4374,8 +4400,12 @@
::
%info
?: ?=(%| -.dit.req)
~| %labelling-not-implemented
!!
=/ bel=@tas p.dit.req
=/ aey=(unit aeon) q.dit.req
=^ mos ruf
=/ den ((de now rof hen ruf) our des.req)
abet:(label:den bel aey)
[mos ..^$]
=/ [deletes=(set path) changes=(map path cage)]
=/ =soba p.dit.req
=| deletes=(set path)

View File

@ -34,18 +34,16 @@
:: manage subscriptions efficiently.
::
=> |%
+$ state-1
$: %1
pki=state-pki-1 ::
+$ state-2
$: %2
pki=state-pki-2 ::
etn=state-eth-node :: eth connection state
== ::
+$ state-pki-1 :: urbit metadata
+$ state-pki-2 :: urbit metadata
$: $= own :: vault (vein)
$: yen=(set duct) :: trackers
sig=(unit oath) :: for a moon
tuf=(list turf) :: domains
boq=@ud :: boot block
nod=purl:eyre :: eth gateway
fak=_| :: fake keys
lyf=life :: version
step=@ud :: login code step
@ -181,7 +179,7 @@
==
:: all vane state
::
state-1
state-2
==
:: lex: all durable state
:: moz: pending actions
@ -207,8 +205,8 @@
[our our]
app
%poke
%azimuth-tracker-poke
!>([%watch (crip (en-purl:html purl))])
%azimuth-poke
!>([%watch (crip (en-purl:html purl)) %default])
==
::
++ sein :: sponsor
@ -254,14 +252,6 @@
::
~| [our who.seed.tac]
?> =(our who.seed.tac)
:: save our boot block
::
=. boq.own.pki bloq.tac
:: save our ethereum gateway (required for galaxies)
::
=. nod.own.pki
%+ fall node.tac
(need (de-purl:html 'http://eth-mainnet.urbit.org:8545'))
:: save our parent signature (only for moons)
::
=. sig.own.pki sig.seed.tac
@ -312,26 +302,29 @@
::
:: start subscriptions
::
=. +>.$ (poke-watch hen %azimuth-tracker nod.own.pki)
=. +>.$
:: get everything from azimuth-tracker because jael subscriptions
%^ poke-watch hen %azimuth
%+ fall node.tac
(need (de-purl:html 'http://eth-mainnet.urbit.org:8545'))
=. +>.$
:: get everything from /app/azimuth because jael subscriptions
:: seem to be flaky for now
::
?: &
%- curd =< abet
(sources:~(feel su hen now pki etn) ~ [%| %azimuth-tracker])
(sources:~(feel su hen now pki etn) ~ [%| %azimuth])
::
?- (clan:title our)
%czar
%- curd =< abet
(sources:~(feel su hen now pki etn) ~ [%| %azimuth-tracker])
(sources:~(feel su hen now pki etn) ~ [%| %azimuth])
::
*
=. +>.$
%- curd =< abet
%+ sources:~(feel su hen now pki etn)
(silt (turn spon-points head))
[%| %azimuth-tracker]
[%| %azimuth]
%- curd =< abet
(sources:~(feel su hen now pki etn) ~ [%& (need spon-ship)])
==
@ -489,6 +482,7 @@
:: [%trim p=@ud]
::
%trim
::TODO consider %ruin-ing long-offline comets
+>.$
::
:: watch private keys
@ -521,6 +515,20 @@
=. moz [[hen %give %done ~] moz]
$(tac message)
==
::
:: pretend ships breached
:: [%ruin ships=(set ship)]
::
%ruin
::NOTE we blast this out to _all_ known ducts, because the common
:: use case for this is comets, about who nobody cares.
=/ dus ~(key by yen.zim.pki)
=/ sus ~(. su hen now pki etn)
=/ sis ~(tap in ships.tac)
|-
?~ sis (curd abet:sus)
=. sus (exec:sus dus %give %public-keys %breach i.sis)
$(sis t.sis)
==
::
++ take
@ -548,7 +556,7 @@
[%behn %wake *]
?^ error.hin
%- %+ slog
leaf+"jael unable to resubscribe, run :azimuth-tracker|listen"
leaf+"jael unable to resubscribe, run :azimuth|listen"
u.error.hin
+>.$
?> ?=([%breach @ ~] tea)
@ -565,7 +573,14 @@
[%gall %unto *]
?- +>-.hin
%raw-fact !!
%kick ~|([%jael-unexpected-quit tea hin] !!)
::
%kick
?> ?=([@ *] tea)
=* app i.tea
::NOTE we expect azimuth-tracker to be kill
?: =(%azimuth-tracker app) +>.$
~|([%jael-unexpected-quit tea hin] !!)
::
%poke-ack
?~ p.p.+>.hin
+>.$
@ -589,7 +604,7 @@
:: :: ++curd:of
++ curd :: relative moves
|= $: moz=(list move)
pki=state-pki-1
pki=state-pki-2
etn=state-eth-node
==
+>(pki pki, etn etn, moz (weld (flop moz) ^moz))
@ -609,7 +624,7 @@
=| moz=(list move)
=| $: hen=duct
now=@da
state-pki-1
state-pki-2
state-eth-node
==
:: moz: moves in reverse order
@ -990,7 +1005,7 @@
::
:: lex: all durable %jael state
::
=| lex=state-1
=| lex=state-2
|= $: :: now: current time
:: eny: unique entropy
:: ski: namespace resolver
@ -1020,8 +1035,42 @@
[did ..^$]
:: :: ++load
++ load :: upgrade
|= old=state-1
=> |%
::
+$ any-state $%(state-1 state-2)
+$ state-1
$: %1
pki=state-pki-1
etn=state-eth-node
==
+$ state-pki-1
$: $= own
$: yen=(set duct)
sig=(unit oath)
tuf=(list turf)
boq=@ud
nod=purl:eyre
fak=_|
lyf=life
step=@ud
jaw=(map life ring)
==
$= zim
$: yen=(jug duct ship)
ney=(jug ship duct)
nel=(set duct)
dns=dnses
pos=(map ship point)
== ==
--
|= old=any-state
^+ ..^$
=? old ?=(%1 -.old)
%= old
- %2
own.pki own.pki.old(+>+ +>.+>+.own.pki.old)
==
?> ?=(%2 -.old)
..^$(lex old)
:: :: ++scry
++ scry :: inspect
@ -1064,6 +1113,12 @@
=/ sec (~(got by jaw.own.pki.lex) lyf.own.pki.lex)
=/ sal (add %pass step.own.pki.lex)
``[%noun !>((end 6 (shaf sal (shax sec))))]
::
%fake
?. ?=(~ tyl) [~ ~]
?. =([%& our] why)
[~ ~]
``[%noun !>(fak.own.pki.lex)]
::
%life
?. ?=([@ ~] tyl) [~ ~]

View File

@ -4,7 +4,7 @@
=> ..lull
~% %zuse ..part ~
|%
++ zuse %420
++ zuse %419
:: :: ::
:::: :: :: (2) engines
:: :: ::
@ -4910,13 +4910,20 @@
++ cite :: render ship
|= who=@p
^- tape
=+ kind=(clan who)
=+ name=(scow %p who)
?: =(%earl kind)
:(weld "~" (swag [15 6] name) "^" (swag [22 6] name))
?: =(%pawn kind)
:(weld (swag [0 7] name) "_" (swag [51 6] name))
name
=/ wid (met 4 who)
?: (lte wid 2) (scow %p who)
?: (lte wid 4)
=/ nom (scow %p (end 5 who))
:(weld (scag 7 nom) "^" (slag 8 nom))
%- trip
%+ rap 3
:~ '~'
(tos:po (cut 3 [(dec (mul wid 2)) 1] who))
(tod:po (cut 3 [(mul (dec wid) 2) 1] who))
'_'
(tos:po (cut 3 [1 1] who))
(tod:po (end 3 who))
==
:: :: ++saxo:title
++ saxo :: autocanon
|= [our=ship now=@da who=ship]

View File

@ -1,7 +1,7 @@
:: eth-watcher: ethereum event log collector
::
/- spider, *eth-watcher
/+ strandio, ethio
/+ strandio, ethio, azimuth
=, ethereum-types
=, jael
::
@ -12,21 +12,22 @@
=+ !<([~ pup=watchpup] args)
=/ m (strand:strandio ,vase)
^- form:m
;< =latest=block bind:m (get-latest-block:ethio url.pup)
;< pup=watchpup bind:m (zoom pup number.id.latest-block)
;< =latest=block bind:m (get-latest-block:ethio url.pup)
;< pup=watchpup bind:m (zoom pup number.id.latest-block)
=| vows=disavows
?. eager.pup
;< pup=watchpup bind:m (fetch-batches pup)
::?. eager.pup
(pure:m !>([vows pup]))
|- ^- form:m
=* loop $
?: (gth number.pup number.id.latest-block)
(pure:m !>([vows pup]))
;< =block bind:m (get-block-by-number:ethio url.pup number.pup)
;< [=new=disavows pup=watchpup] bind:m (take-block pup block)
%= loop
pup pup
vows (weld vows new-disavows)
==
:: |- ^- form:m
:: =* loop $
:: ?: (gth number.pup number.id.latest-block)
:: (pure:m !>([vows pup]))
:: ;< =block bind:m (get-block-by-number:ethio url.pup number.pup)
:: ;< [=new=disavows pup=watchpup] bind:m (take-block pup block)
:: %= loop
:: pup pup
:: vows (weld vows new-disavows)
:: ==
::
:: Process a block, detecting and handling reorgs
::
@ -37,8 +38,9 @@
:: if this next block isn't direct descendant of our logs, reorg happened
?: &(?=(^ blocks.pup) !=(parent-hash.block hash.id.i.blocks.pup))
(rewind pup block)
=/ contracts (weld contracts.pup batchers.pup)
;< =new=loglist bind:m :: oldest first
(get-logs-by-hash:ethio url.pup hash.id.block contracts.pup topics.pup)
(get-logs-by-hash:ethio url.pup hash.id.block contracts topics.pup)
%- pure:m
:- ~
%_ pup
@ -80,21 +82,38 @@
|= [pup=watchpup =latest=number:block]
=/ m (strand:strandio ,watchpup)
^- form:m
=/ zoom-margin=number:block 30
=/ zoom-margin=number:block 0 :: TODO: 30!
=/ zoom-step=number:block 100.000
?: (lth latest-number (add number.pup zoom-margin))
(pure:m pup)
=/ up-to-number=number:block (sub latest-number zoom-margin)
=/ up-to-number=number:block
(min (add 10.000.000 number.pup) (sub latest-number zoom-margin))
|-
=* loop $
?: (gth number.pup up-to-number)
(pure:m pup(blocks ~))
=/ to-number=number:block
(min up-to-number (add number.pup zoom-step))
=; step
(min up-to-number (add number.pup step))
:: Between "launch" (6.784.800) and "public" (7.033.765) blocks,
:: there are a lot events belonging to all the pre-ethereum ships
:: being established on-chain. By reducing the step, we avoid crashing.
::
?. =(contracts:azimuth mainnet-contracts:azimuth)
zoom-step
?: ?| &((gte number.pup 6.951.132) (lth number.pup 6.954.242))
&((gte number.pup 7.011.857) (lth number.pup 7.021.881))
==
50
?: ?& (gte number.pup launch:mainnet-contracts:azimuth)
(lth number.pup public:mainnet-contracts:azimuth)
==
500
zoom-step
;< =loglist bind:m :: oldest first
%: get-logs-by-range:ethio
url.pup
contracts.pup
(weld contracts.pup batchers.pup)
topics.pup
number.pup
to-number
@ -102,4 +121,53 @@
=? pending-logs.pup ?=(^ loglist)
(~(put by pending-logs.pup) to-number loglist)
loop(number.pup +(to-number))
:: Fetch input for any logs in batchers.pup
::
++ fetch-batches
|= pup=watchpup
=/ m (strand:strandio ,watchpup)
=| res=(list [number:block loglist])
=/ pending=(list [=number:block =loglist]) ~(tap by pending-logs.pup)
|- ^- form:m
=* loop $
?~ pending
(pure:m pup(pending-logs (malt res)))
;< logs=(list event-log:rpc:ethereum) bind:m
(fetch-inputs pup loglist.i.pending)
=. res [[number.i.pending logs] res]
loop(pending t.pending)
:: Fetch inputs for a list of logs
::
++ fetch-inputs
|= [pup=watchpup logs=(list event-log:rpc:ethereum)]
=/ m (strand:strandio ,(list event-log:rpc:ethereum))
=| res=(list event-log:rpc:ethereum)
|- ^- form:m
=* loop $
?~ logs
(pure:m (flop res))
;< log=event-log:rpc:ethereum bind:m (fetch-input pup i.logs)
=. res [log res]
loop(logs t.logs)
:: Fetch input for a log
::
++ fetch-input
|= [pup=watchpup log=event-log:rpc:ethereum]
=/ m (strand:strandio ,event-log:rpc:ethereum)
^- form:m
?~ mined.log
(pure:m log)
?^ input.u.mined.log
(pure:m log)
?. (lien batchers.pup |=(=@ux =(ux address.log)))
(pure:m log)
;< res=transaction-result:rpc:ethereum bind:m
(get-tx-by-hash:ethio url.pup transaction-hash.u.mined.log)
(pure:m log(input.u.mined `(data-to-hex input.res)))
::
++ data-to-hex
|= data=@t
?~ data *@ux
?: =(data '0x') *@ux
(hex-to-num:ethereum data)
--

View File

@ -0,0 +1,15 @@
:: aggregator/nonce: get next nonce
::
/- rpc=json-rpc
/+ ethereum, ethio, strandio
::
|= args=vase
=+ !<([endpoint=@t pk=@] args)
=/ m (strand:strandio ,vase)
^- form:m
::
=/ =address:ethereum
(address-from-prv:key:ethereum pk)
;< expected-nonce=@ud bind:m
(get-next-nonce:ethio endpoint address)
(pure:m !>(expected-nonce))

View File

@ -0,0 +1,134 @@
:: roller/send: send rollup tx
::
/- rpc=json-rpc, *dice
/+ naive, ethereum, ethio, strandio
::
::
|= args=vase
=+ !<(rpc-send-roll args)
=/ m (strand:strandio ,vase)
|^
^- form:m
:: =* not-sent (pure:m !>(%.n^next-gas-price))
::
=/ =address:ethereum (address-from-prv:key:ethereum pk)
;< expected-nonce=@ud bind:m
(get-next-nonce:ethio endpoint address)
:: if chain expects a different nonce, don't send this transaction
::
?. =(nonce expected-nonce)
~& [%unexpected-nonce nonce expected+expected-nonce]
(pure:m !>(%.n^[%not-sent %unexpected-nonce]))
:: if a gas-price of 0 was specified, fetch the recommended one
::
;< use-gas-price=@ud bind:m
?: =(0 next-gas-price) fetch-gas-price
(pure:(strand:strandio @ud) next-gas-price)
::
=/ batch-data=octs
%+ cad:naive 3
%- flop
%+ roll txs
|= [=raw-tx:naive out=(list octs)]
[raw.raw-tx 65^sig.raw-tx out]
:: TODO: keep this to avoid sending bad batches or disregard?
::
?~ (parse-roll:naive q.batch-data)
(pure:m !>(%.n^[%not-sent %batch-parse-error]))
::
:: each l2 signature is 65 bytes + XX bytes for the raw data
:: from the ethereum yellow paper:
:: gasLimit = G_transaction + G_txdatanonzero × dataByteLength
:: where
:: G_transaction = 21000 gas (base fee)
:: + G_txdatanonzero = 68 gas
:: * dataByteLength = (65 + raw) * (lent txs) bytes
::
:: TODO: enforce max number of tx in batch?
::
=/ gas-limit=@ud (add 21.000 (mul 68 p.batch-data))
:: if we cannot pay for the transaction, don't bother sending it out
::
=/ max-cost=@ud (mul gas-limit use-gas-price)
;< balance=@ud bind:m
(get-balance:ethio endpoint address)
?: (gth max-cost balance)
(pure:m !>(%.n^[%not-sent %insufficient-roller-balance]))
::
::NOTE this fails the thread if sending fails, which in the app gives us
:: the "retry with same gas price" behavior we want
;< =response:rpc bind:m
%+ send-batch endpoint
=; tx=transaction:rpc:ethereum
(sign-transaction:key:ethereum tx pk)
:* nonce
use-gas-price
gas-limit
contract
0
q.batch-data
chain-id
==
:: log batch tx-hash to getTransactionReceipt(tx-hash)
::
~? &(?=(%result -.response) ?=(%s -.res.response))
^-([nonce=@ud batch-hash=@t] nonce^(so:dejs:format res.response))
%- pure:m
!> ^- (each @ud [term @t])
:: TODO: capture if the tx fails (e.g. Runtime Error: revert)
:: check that tx-hash in +.response is non-zero?
:: enforce max here, or in app?
::
?+ -.response %.n^[%error 'unexpected rpc response']
%error %.n^[%error message.response]
:: add five gwei to gas price of next attempt
::
%result %.y^(add use-gas-price 5.000.000.000)
==
::
::TODO should be distilled further, partially added to strandio?
++ fetch-gas-price
=/ m (strand:strandio @ud) ::NOTE return in wei
^- form:m
=/ =request:http
:* method=%'GET'
url='https://api.etherscan.io/api?module=gastracker&action=gasoracle'
header-list=~
~
==
;< ~ bind:m
(send-request:strandio request)
;< rep=(unit client-response:iris) bind:m
take-maybe-response:strandio
=* fallback
~& %fallback-gas-price
(pure:m 10.000.000.000)
?. ?& ?=([~ %finished *] rep)
?=(^ full-file.u.rep)
==
fallback
?~ jon=(de-json:html q.data.u.full-file.u.rep)
fallback
=; res=(unit @ud)
?~ res fallback
%- pure:m
(mul 1.000.000.000 u.res) ::NOTE gwei to wei
%. u.jon
=, dejs-soft:format
(ot 'result'^(ot 'FastGasPrice'^ni ~) ~)
::
++ send-batch
|= [endpoint=@ta batch=@ux]
=/ m (strand:strandio ,response:rpc)
^- form:m
=/ req=[(unit @t) request:rpc:ethereum]
[`'sendRawTransaction' %eth-send-raw-transaction batch]
;< res=(list response:rpc) bind:m
(request-batch-rpc-loose:ethio endpoint [req]~)
?: ?=([* ~] res)
(pure:m i.res)
%+ strand-fail:strandio
%unexpected-multiple-results
[>(lent res)< ~]
::
--

File diff suppressed because it is too large Load Diff

View File

@ -29,15 +29,6 @@
%+ weld "0x"
(render-hex-bytes:ethereum 20 `@`azimuth:contracts:^azimuth)
::
++ test-give-bloq
=/ oct
%- as-octs:mimes:html
'{"params":[],"id":"0","jsonrpc":"2.0","method":"eth_blockNumber"}'
%+ expect-eq
!> oct
!> bloq:give:dawn
:: this produces a 1000+ line payload, so we just check that it doesn't crash
::
++ test-give-czar
=/ zar czar:give:dawn
~! zar
@ -45,146 +36,6 @@
!> &
!> ?=(^ zar)
::
++ test-give-point
=/ oct
%- as-octs:mimes:html
%+ rap 3
:~ '{"params":[{"to":"' azimuth '","data":"'
'0x63fa9a87'
'0000000000000000000000000000000000000000000000000000000000000000'
'"},"0x0"],"id":"0","jsonrpc":"2.0","method":"eth_call"}'
==
%+ expect-eq
!> oct
!> (point:give:dawn 0 ~zod)
::
++ test-give-turf
=/ oct
%- as-octs:mimes:html
%+ rap 3
:~ '[{"params":[{"to":"' azimuth '","data":"'
'0xeccc8ff1'
'0000000000000000000000000000000000000000000000000000000000000000'
'"},"0x0"],"id":"turf-0","jsonrpc":"2.0","method":"eth_call"},'
'{"params":[{"to":"' azimuth '","data":"'
'0xeccc8ff1'
'0000000000000000000000000000000000000000000000000000000000000001'
'"},"0x0"],"id":"turf-1","jsonrpc":"2.0","method":"eth_call"},'
'{"params":[{"to":"' azimuth '","data":"'
'0xeccc8ff1'
'0000000000000000000000000000000000000000000000000000000000000002'
'"},"0x0"],"id":"turf-2","jsonrpc":"2.0","method":"eth_call"}]'
==
%+ expect-eq
!> oct
!> (turf:give:dawn 0)
::
++ test-take-bloq
=/ oct
%- as-octs:mimes:html
'{"id":"0","jsonrpc":"2.0","result":"0x20"}'
=/ boq 32
%+ expect-eq
!> [~ boq]
!> (bloq:take:dawn oct)
::
++ test-take-czar
=/ oct
%- as-octs:mimes:html
%+ rap 3
:~ '[{"id":"gal-0","jsonrpc":"2.0","result":"'
'0xb69b6818b17b7cc22f8e0a2291f58e4aa840cbf44cb2f1c94dc3d71e3cda0d94'
'3defb87516f42ce4327820b588002aa53e52527af8d23bee4aa215fa296bdf5f'
'0000000000000000000000000000000000000000000000000000000000000001'
'0000000000000000000000000000000000000000000000000000000000000001'
'0000000000000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000000000001'
'0000000000000000000000000000000000000000000000000000000000000001'
'0000000000000000000000000000000000000000000000000000000000000002'
'"},{"id":"gal-1","jsonrpc":"2.0","result":"'
'0xb727e38d031162e50913b2e37a2e29d4ba457eff4f7fd4ac47dc68fcb54260d3'
'b8bfe4789483c171f7fa359438cdcc8d268d40fe08d6c1d8b36267748d2139f8'
'0000000000000000000000000000000000000000000000000000000000000001'
'0000000000000000000000000000000000000000000000000000000000000001'
'0000000000000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000000000001'
'0000000000000000000000000000000000000000000000000000000000000001'
'0000000000000000000000000000000000000000000000000000000000000003'
'"},{"id":"gal-2","jsonrpc":"2.0","result":"'
'0x0000000000000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000000000001'
'0000000000000000000000000000000000000000000000000000000000000001'
'0000000000000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000000000001'
'0000000000000000000000000000000000000000000000000000000000000001'
'0000000000000000000000000000000000000000000000000000000000000004'
'"}]'
==
=/ kyz
^- [zod=pass nec=pass]
:- 2.448.360.348.730.164.860.814.441.775.703.143.856.915.192.920.639.124.
529.297.987.279.849.833.790.775.864.413.949.853.880.667.744.188.597.545.
066.664.466.963.044.328.182.155.965.137.512.758.548.384.637.214.562
::
2.455.718.000.840.284.920.492.237.722.671.938.413.341.955.411.945.312.
638.361.167.187.097.711.481.986.932.531.569.955.478.938.087.263.286.158.
823.313.739.767.009.446.819.531.923.255.637.798.148.055.143.938.146
%+ expect-eq
!> :- ~
%- ~(gas by *(map ship [=rift =life =pass]))
[[~zod 2 1 zod.kyz] [~nec 3 1 nec.kyz] [~bud 4 1 'b'] ~]
!> (czar:take:dawn oct)
::
++ test-take-point
=/ oct
%- as-octs:mimes:html
%+ rap 3
:~ '{"jsonrpc":"2.0","result":"'
'0xb69b6818b17b7cc22f8e0a2291f58e4aa840cbf44cb2f1c94dc3d71e3cda0d94'
'3defb87516f42ce4327820b588002aa53e52527af8d23bee4aa215fa296bdf5f'
'0000000000000000000000000000000000000000000000000000000000000001'
'0000000000000000000000000000000000000000000000000000000000000001'
'0000000000000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000000000001'
'0000000000000000000000000000000000000000000000000000000000000001'
'0000000000000000000000000000000000000000000000000000000000000000'
'"}'
==
%+ expect-eq
!> [~ pot]
!> (point:take:dawn ~zod oct)
::
++ test-take-turf
=/ oct
%- as-octs:mimes:html
%+ rap 3
:~ '[{"id":"turf-0","jsonrpc":"2.0","result":"'
'0x0000000000000000000000000000000000000000000000000000000000000020'
'0000000000000000000000000000000000000000000000000000000000000009'
'75726269742e6f72670000000000000000000000000000000000000000000000'
'"},{"id":"turf-1","jsonrpc":"2.0","result":"'
'0x0000000000000000000000000000000000000000000000000000000000000020'
'0000000000000000000000000000000000000000000000000000000000000009'
'75726269742e6f72670000000000000000000000000000000000000000000000'
'"},{"id":"turf-2","jsonrpc":"2.0","result":"'
'0x0000000000000000000000000000000000000000000000000000000000000020'
'0000000000000000000000000000000000000000000000000000000000000009'
'75726269742e6f72670000000000000000000000000000000000000000000000'
'"}]'
==
%+ expect-eq
!> [~ [/org/urbit ~]]
!> (turf:take:dawn oct)
::
++ test-veri-good
=/ sed [~zod 1 sec ~]
%+ expect-eq

View File

@ -0,0 +1,28 @@
:: tests for |title
::
/+ *test
=, title
|%
++ test-cite
;: weld
%+ expect-eq
!> "~zod^"
!> (cite ~dister-dozzod-dozzod)
::
%+ expect-eq
!> "~marzod^"
!> (cite ~dister-dozzod-marzod)
::
%+ expect-eq
!> "~palfun^foslup"
!> (cite ~littel-palfun-foslup)
::
%+ expect-eq
!> "~palfun^foslup"
!> (cite ~littel-bittel-palfun-foslup)
::
%+ expect-eq
!> "~sampel_sampel"
!> (cite ~sampel--dozzod-dozzod-dozzod-sampel)
==
--

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1d227633641c8abb68d16633e110467fd4a4330c921496312d75b471677e2a02
size 3057639

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:66e64f702b542347f1d8e267dc87c542e3f8f537278f6a221aa6d7d793b21d55
size 461160

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fb475f30c6d6c68b3c31ce46155a1e3d98b18359b6750b7bb6b00e429187e1ef
size 376635

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:45a54c6e05e3db80b3cc9746a65f185da29d8644d7a0bf953fade9f15a78dad4
size 1812725

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8fe9b7b9b38fa7f16f8ec234984c44c616856937eff50353e11eb62c173f6b09
size 306377

View File

@ -1,5 +0,0 @@
:~ :- %apes
~
:- %fish
~
==

View File

@ -553,7 +553,9 @@
top=(list ?(@ux (list @ux)))
==
[%eth-get-filter-changes fid=@ud]
[%eth-get-transaction-by-hash txh=@ux]
[%eth-get-transaction-count adr=address =block]
[%eth-get-balance adr=address =block]
[%eth-get-transaction-receipt txh=@ux]
[%eth-send-raw-transaction dat=@ux]
==
@ -569,10 +571,20 @@
[%eth-transaction-hash haz=@ux]
==
::
++ transaction-result
$: block-hash=(unit @ux)
block-number=(unit @ud)
transaction-index=(unit @ud)
from=@ux
to=(unit @ux)
input=@t
==
::
++ event-log
$: :: null for pending logs
$= mined %- unit
$: log-index=@ud
$: input=(unit @ux)
log-index=@ud
transaction-index=@ud
transaction-hash=@ux
block-number=@ud
@ -778,6 +790,15 @@
:~ (tape (address-to-hex adr.req))
(block-to-json block.req)
==
::
%eth-get-balance
:- 'eth_getBalance'
:~ (tape (address-to-hex adr.req))
(block-to-json block.req)
==
::
%eth-get-transaction-by-hash
['eth_getTransactionByHash' (tape (transaction-to-hex txh.req)) ~]
::
%eth-get-transaction-receipt
['eth_getTransactionReceipt' (tape (transaction-to-hex txh.req)) ~]
@ -854,6 +875,8 @@
::
++ parse-eth-get-transaction-count parse-hex-result
::
++ parse-eth-get-balance parse-hex-result
::
++ parse-event-logs
(ar:dejs:format parse-event-log)
::
@ -865,7 +888,7 @@
:~ =- ['logIndex'^(cu - (mu so))]
|= li=(unit @t)
?~ li ~
=- `((ou -) log) ::TODO not sure if elegant or hacky.
=- ``((ou -) log) ::TODO not sure if elegant or hacky.
:~ 'logIndex'^(un (cu hex-to-num so))
'transactionIndex'^(un (cu hex-to-num so))
'transactionHash'^(un (cu hex-to-num so))
@ -884,6 +907,27 @@
:- (hex-to-num i.r)
(turn t.r hex-to-num)
==
::
++ parse-transaction-result
=, dejs:format
|= jon=json
~| jon=jon
^- transaction-result
=- ((ot -) jon)
:~ 'blockHash'^_~ :: TODO: fails if maybe-num?
'blockNumber'^maybe-num
'transactionIndex'^maybe-num
from+(cu hex-to-num so)
to+maybe-num
input+so
==
::
++ maybe-num
=, dejs:format
=- (cu - (mu so))
|= r=(unit @t)
?~ r ~
`(hex-to-num u.r)
--
::
:: utilities

View File

@ -108,16 +108,25 @@
++ parse-one-response
|= =json
^- (unit response:rpc)
=/ res=(unit [@t ^json])
?. &(?=([%o *] json) (~(has by p.json) 'error'))
=/ res=(unit [@t ^json])
%. json
=, dejs-soft:format
(ot id+so result+some ~)
?~ res ~
`[%result u.res]
~| parse-one-response=json
=/ error=(unit [id=@t ^json code=@ta mssg=@t])
%. json
=, dejs-soft:format
(ot id+so result+some ~)
?^ res `[%result u.res]
~| parse-one-response=json
:+ ~ %error %- need
%. json
=, dejs-soft:format
(ot id+so error+(ot code+no message+so ~) ~)
:: A 'result' member is present in the error
:: response when using ganache, even though
:: that goes against the JSON-RPC spec
::
(ot id+so result+some error+(ot code+no message+so ~) ~)
?~ error ~
=* err u.error
`[%error id.err code.err mssg.err]
--
::
:: +read-contract: calls a read function on a contract, produces result hex
@ -209,6 +218,19 @@
++ parse-hex |=(=json `(unit @)`(some (parse-hex-result:rpc:ethereum json)))
--
::
++ get-tx-by-hash
|= [url=@ta tx-hash=@ux]
=/ m (strand:strandio transaction-result:rpc:ethereum)
^- form:m
;< =json bind:m
%+ request-rpc url
:* `'tx by hash'
%eth-get-transaction-by-hash
tx-hash
==
%- pure:m
(parse-transaction-result:rpc:ethereum json)
::
++ get-logs-by-hash
|= [url=@ta =hash:block contracts=(list address) =topics]
=/ m (strand:strandio (list event-log:rpc:ethereum))
@ -254,4 +276,14 @@
[%eth-get-transaction-count address [%label %latest]]
%- pure:m
(parse-eth-get-transaction-count:rpc:ethereum json)
::
++ get-balance
|= [url=@ta =address]
=/ m (strand:strandio ,@ud)
^- form:m
;< =json bind:m
%^ request-rpc url `'balance'
[%eth-get-balance address [%label %latest]]
%- pure:m
(parse-eth-get-balance:rpc:ethereum json)
--

View File

@ -191,7 +191,7 @@
==
^- [jolt=(list dude) idle=(list dude)]
=/ all=(list dude) (read-bill local)
=/ want (get-apps-want all rein)
=/ want (get-apps-want local all rein)
=/ have (get-apps-live local)
[want (skip have ~(has in (sy want)))]
::
@ -223,9 +223,10 @@
:: +get-apps-want: find which apps should be running on a desk
::
++ get-apps-want
|= [duz=(list dude) =rein]
|= [local=[our=ship =desk now=@da] duz=(list dude) =rein]
^- (list dude)
?. liv.rein ~
?. |(=(`zuse+zuse (read-kelvin-local local)) =(%base desk.local)) ~
=. duz (skip duz ~(has in sub.rein))
=. duz (weld duz (skip ~(tap in add.rein) ~(has in (sy duz))))
duz

View File

@ -1,14 +1,21 @@
:: json-rpc: protocol types
::
|%
+$ batch-request
$% [%a p=(list request)]
[%o p=request]
==
::
+$ request
$: id=@t
jsonrpc=@t
method=@t
params=request-params
==
::
+$ request-params
$% [%list (list json)]
[%map (map @t json)]
[%object (list (pair @t json))]
==
+$ response

View File

@ -1,10 +1,10 @@
:~ title+'System'
info+'An app launcher for Urbit.'
color+0xee.5432
glob-http+['https://bootstrap.urbit.org/glob-0v5.fdf99.nph65.qecq3.ncpjn.q13mb.glob' 0v5.fdf99.nph65.qecq3.ncpjn.q13mb]
glob-http+['https://bootstrap.urbit.org/glob-0v4.64ana.19ug9.ik7l6.og080.68ce4.glob' 0v4.64ana.19ug9.ik7l6.og080.68ce4]
::glob-ames+~zod^0v0
base+'grid'
version+[1 0 1]
version+[1 0 2]
website+'https://tlon.io'
license+'MIT'
==

View File

@ -49,8 +49,6 @@ const AppRoutes = () => {
}
}, [isDarkMode, theme]);
useEffect(() => {}, []);
useEffect(
handleError(() => {
window.name = 'grid';

View File

@ -227,6 +227,7 @@ export const Leap = React.forwardRef(
[selection, rawInput, match, matches, selectedMatch]
);
return (
<div className="relative z-50 w-full">
<form
@ -234,6 +235,7 @@ export const Leap = React.forwardRef(
'flex items-center h-full w-full px-2 rounded-full bg-white default-ring focus-within:ring-2',
shouldDim && 'opacity-60',
!navOpen ? 'bg-gray-50' : '',
menu === 'upgrading' ? 'bg-orange-500' : '',
className
)}
onSubmit={onSubmit}
@ -241,28 +243,32 @@ export const Leap = React.forwardRef(
<label
htmlFor="leap"
className={classNames(
'inline-block flex-none p-2 h4 text-blue-400',
!selection && 'sr-only'
'inline-block flex-none p-2 h4 ',
menu === 'upgrading' ? 'text-white' : !selection ? 'sr-only' : 'text-blue-400'
)}
>
{selection || 'Search'}
{menu === 'upgrading'
? 'Your Urbit is being updated, this page will update when ready'
: selection || 'Search'}
</label>
<input
id="leap"
type="text"
ref={inputRef}
placeholder={selection ? '' : 'Search'}
className="flex-1 w-full h-full px-2 h4 text-base rounded-full bg-transparent outline-none"
value={rawInput}
onClick={toggleSearch}
onFocus={onFocus}
onChange={onChange}
onKeyDown={onKeyDown}
autoComplete="off"
aria-autocomplete="both"
aria-controls={dropdown}
aria-activedescendant={selectedMatch?.display || selectedMatch?.value}
/>
{menu !== 'upgrading' ? (
<input
id="leap"
type="text"
ref={inputRef}
placeholder={selection ? '' : 'Search'}
className="flex-1 w-full h-full px-2 h4 text-base rounded-full bg-transparent outline-none"
value={rawInput}
onClick={toggleSearch}
onFocus={onFocus}
onChange={onChange}
onKeyDown={onKeyDown}
autoComplete="off"
aria-autocomplete="both"
aria-controls={dropdown}
aria-activedescendant={selectedMatch?.display || selectedMatch?.value}
/>
) : null}
</form>
{menu === 'search' && (
<Link

View File

@ -52,7 +52,8 @@ export type MenuState =
| 'search'
| 'notifications'
| 'help-and-support'
| 'system-preferences';
| 'system-preferences'
| 'upgrading';
interface NavProps {
menu?: MenuState;
@ -68,7 +69,7 @@ export const Nav: FunctionComponent<NavProps> = ({ menu }) => {
const select = useLeapStore((state) => state.select);
const menuState = menu || 'closed';
const isOpen = menuState !== 'closed';
const isOpen = menuState !== 'upgrading' && menuState !== 'closed';
const eitherOpen = isOpen || systemMenuOpen;
useEffect(() => {

View File

@ -12,7 +12,7 @@ function renderNotification(notification: Notification, key: string, lid: HarkLi
if (notification.bin.place.path === '/lag') {
return <RuntimeLagNotification key={key} />;
}
if (notification.bin.place.path === '/blocked') {
if (notification.bin.path === '/blocked' && notification.bin.place.path === '/desk/base') {
return <BaseBlockedNotification key={key} />;
}
if (notification.bin.place.path === '/onboard') {

View File

@ -1,4 +1,4 @@
import { pick } from 'lodash';
import { pick, pickBy, partition } from 'lodash';
import React, { useCallback } from 'react';
import { kilnBump } from '@urbit/api/hood';
import { AppList } from '../../components/AppList';
@ -7,9 +7,12 @@ import { Dialog, DialogClose, DialogContent, DialogTrigger } from '../../compone
import { Elbow } from '../../components/icons/Elbow';
import api from '../../state/api';
import { useCharges } from '../../state/docket';
import useKilnState, { useVat } from '../../state/kiln';
import { NotificationButton } from './NotificationButton';
import { disableDefault } from '../../state/util';
import { Vat } from '@urbit/api';
import {useHistory} from 'react-router-dom';
export const RuntimeLagNotification = () => (
<section
@ -35,16 +38,29 @@ export const RuntimeLagNotification = () => (
</section>
);
function vatIsBlocked(newKelvin: number, vat: Vat) {
return !(vat.arak?.rail?.next || []).find(({ aeon, weft }) => weft.kelvin === newKelvin);
}
export const BaseBlockedNotification = () => {
const desks: string[] = [];
const base = useVat('base');
const { push } = useHistory();
// TODO: assert weft.name === 'zuse'??
const newKelvin = base?.arak?.rail?.next?.[0]?.weft?.kelvin || 420;
const charges = useCharges();
const blockedCharges = Object.values(pick(charges, desks));
const [blocked, unblocked] = useKilnState((s) => {
const [b, u] = partition(Object.entries(s.vats), ([desk, vat]) => vatIsBlocked(newKelvin, vat));
return [b.map(([d]) => d), u.map(([d]) => d)] as const;
});
const blockedCharges = Object.values(pick(charges, blocked));
const count = blockedCharges.length;
const handlePauseOTAs = useCallback(() => {}, []);
const handleArchiveApps = useCallback(async () => {
api.poke(kilnBump(true));
push('/leap/upgrading');
}, []);
return (

View File

@ -1,27 +1,51 @@
import { map, omit } from 'lodash';
import React, { FunctionComponent } from 'react';
import React, { FunctionComponent, useEffect } from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import { Route, RouteComponentProps } from 'react-router-dom';
import { Route, RouteComponentProps, useHistory, useParams } from 'react-router-dom';
import { ErrorAlert } from '../components/ErrorAlert';
import { MenuState, Nav } from '../nav/Nav';
import { useCharges } from '../state/docket';
import useKilnState from '../state/kiln';
import { RemoveApp } from '../tiles/RemoveApp';
import { SuspendApp } from '../tiles/SuspendApp';
import { Tile } from '../tiles/Tile';
import { TileInfo } from '../tiles/TileInfo';
type GridProps = RouteComponentProps<{
interface RouteProps {
menu?: MenuState;
}>;
}
export const Grid: FunctionComponent<GridProps> = ({ match, history }) => {
export const Grid: FunctionComponent<{}> = () => {
const charges = useCharges();
const { push } = useHistory();
const { menu } = useParams<RouteProps>();
const chargesLoaded = Object.keys(charges).length > 0;
useEffect(() => {
// TOOD: rework
// Heuristically detect reload completion and redirect
async function attempt(count = 0) {
if(count > 5) {
window.location.reload();
}
const start = performance.now();
await useKilnState.getState().fetchVats();
await useKilnState.getState().fetchVats();
if((performance.now() - start) > 5000) {
attempt(count+1);
} else {
push('/');
}
}
if(menu === 'upgrading') {
attempt();
}
}, [menu])
return (
<div className="flex flex-col">
<header className="fixed sm:sticky bottom-0 sm:bottom-auto sm:top-0 left-0 z-30 flex justify-center w-full px-4">
<Nav menu={match.params.menu} />
<Nav menu={menu} />
</header>
<main className="h-full w-full flex justify-center pt-4 md:pt-16 pb-32 relative z-0">
@ -30,11 +54,11 @@ export const Grid: FunctionComponent<GridProps> = ({ match, history }) => {
<div className="grid justify-center grid-cols-2 sm:grid-cols-[repeat(auto-fit,minmax(auto,250px))] gap-4 px-4 md:px-8 w-full max-w-6xl">
{charges &&
map(omit(charges, window.desk), (charge, desk) => (
<Tile key={desk} charge={charge} desk={desk} />
<Tile key={desk} charge={charge} desk={desk} disabled={menu === 'upgrading'} />
))}
</div>
)}
<ErrorBoundary FallbackComponent={ErrorAlert} onReset={() => history.push('/')}>
<ErrorBoundary FallbackComponent={ErrorAlert} onReset={() => push('/')}>
<Route exact path="/app/:desk">
<TileInfo />
</Route>

View File

@ -241,7 +241,17 @@ function createMockSysNotification(path: string, body: HarkBody[] = []) {
}
const lag = createMockSysNotification('/lag');
const blocked = createMockSysNotification('/blocked');
const blocked = {
bin: {
place: {
desk: window.desk,
path: '/desk/base'
},
path: '/blocked'
},
time: Date.now() - 3_600,
body: []
};
const onboard = createMockSysNotification('/onboard');
const updateNotification = createMockSysNotification('/desk/bitcoin', [

View File

@ -13,19 +13,20 @@ import { Bullet } from '../components/icons/Bullet';
type TileProps = {
charge: ChargeWithDesk;
desk: string;
disabled?: boolean;
};
export const Tile: FunctionComponent<TileProps> = ({ charge, desk }) => {
export const Tile: FunctionComponent<TileProps> = ({ charge, desk, disabled = false }) => {
const addRecentApp = useRecentsStore((state) => state.addRecentApp);
const { title, image, color, chad, href } = charge;
const vat = useVat(desk);
const { lightText, tileColor, menuColor, suspendColor, suspendMenuColor } = useTileColor(color);
const loading = 'install' in chad;
const suspended = 'suspend' in chad;
const loading = !disabled && 'install' in chad;
const suspended = disabled || 'suspend' in chad;
const hung = 'hung' in chad;
const active = chadIsRunning(chad);
const active = !disabled && chadIsRunning(chad);
const link = getAppHref(href);
const backgroundColor = active ? tileColor || 'purple' : suspendColor;
const backgroundColor = suspended ? suspendColor : active ? tileColor || 'purple' : suspendColor;
return (
<a
@ -47,14 +48,12 @@ export const Tile: FunctionComponent<TileProps> = ({ charge, desk }) => {
<>
{loading && <Spinner className="h-6 w-6 mr-2" />}
<span className="text-gray-500">
{suspended && 'Suspended'}
{loading && 'Installing'}
{hung && 'Errored'}
{suspended ? 'Suspended' : loading ? 'Installing' : hung ? 'Errored' : null }
</span>
</>
)}
</div>
{vat?.arak.rail?.paused && (
{vat?.arak.rail?.paused && !disabled && (
<Bullet className="absolute z-10 top-5 left-5 sm:top-7 sm:left-7 w-4 h-4 text-orange-500 dark:text-black" />
)}
<TileMenu

View File

@ -439,7 +439,7 @@ data PierVersionNegotiationFailed = PierVersionNegotiationFailed
deriving (Show, Exception)
zuseVersion :: Word
zuseVersion = 420
zuseVersion = 419
wyrd :: HasKingEnv e => RIO e Ev
wyrd = do

View File

@ -1,5 +1,5 @@
name: urbit-king
version: 1.7
version: 1.8
license: MIT
license-file: LICENSE
data-files:

View File

@ -444,13 +444,14 @@ u3_ve_usage(c3_i argc, c3_c** argv)
"-c pier Create a new urbit in pier/\n",
"-D Recompute from events\n",
"-d Daemon mode; implies -t\n",
"-e url Ethereum gateway\n",
"-e url Urbit ID (L2) gateway\n",
"-F ship Fake keys; also disables networking\n",
"-G string Private key string (see also -k)\n",
"-g Set GC flag\n",
"-i jam_file import pier state\n",
"-j Create json trace file in .urb/put/trace\n",
"-K stage Start at Hoon kernel version stage\n",
"-k keys Private key file\n",
"-k file-path Private key file (see also -G)\n",
"-L local networking only\n",
"-P Profiling\n",
"-p ames_port Set the ames port to bind to\n",

View File

@ -768,6 +768,99 @@ _ce_image_fine(u3e_image* img_u,
}
#endif
/* _ce_image_copy():
*/
static c3_o
_ce_image_copy(u3e_image* fom_u, u3e_image* tou_u)
{
c3_w i_w;
// resize images
//
_ce_image_resize(tou_u, fom_u->pgs_w);
// seek to begining of patch and images
//
if ( (-1 == lseek(fom_u->fid_i, 0, SEEK_SET))
|| (-1 == lseek(tou_u->fid_i, 0, SEEK_SET)) )
{
fprintf(stderr, "loom: image copy seek 0: %s\r\n", strerror(errno));
return c3n;
}
// 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 off_w = i_w;
if ( -1 == read(fom_u->fid_i, mem_w, (1 << (u3a_page + 2))) ) {
fprintf(stderr, "loom: image copy read: %s\r\n", strerror(errno));
return c3n;
}
else {
if ( -1 == lseek(tou_u->fid_i, (off_w << (u3a_page + 2)), SEEK_SET) ) {
fprintf(stderr, "loom: image copy seek: %s\r\n", strerror(errno));
return c3n;
}
if ( -1 == write(tou_u->fid_i, mem_w, (1 << (u3a_page + 2))) ) {
fprintf(stderr, "loom: image copy write: %s\r\n", strerror(errno));
return c3n;
}
}
}
return c3y;
}
/* _ce_backup();
*/
static void
_ce_backup(void)
{
u3e_image nop_u = { .nam_c = "north", .pgs_w = 0 };
u3e_image sop_u = { .nam_c = "south", .pgs_w = 0 };
c3_i mod_i = O_RDWR | O_CREAT;
c3_c ful_c[8193];
snprintf(ful_c, 8192, "%s/.urb/bhk", u3P.dir_c);
if ( mkdir(ful_c, 0700) ) {
if ( EEXIST != errno ) {
fprintf(stderr, "loom: image backup: %s\r\n", strerror(errno));
}
return;
}
snprintf(ful_c, 8192, "%s/.urb/bhk/%s.bin", u3P.dir_c, nop_u.nam_c);
if ( -1 == (nop_u.fid_i = open(ful_c, mod_i, 0666)) ) {
fprintf(stderr, "loom: open %s: %s\r\n", ful_c, strerror(errno));
return;
}
snprintf(ful_c, 8192, "%s/.urb/bhk/%s.bin", u3P.dir_c, sop_u.nam_c);
if ( -1 == (sop_u.fid_i = open(ful_c, mod_i, 0666)) ) {
fprintf(stderr, "loom: open %s: %s\r\n", ful_c, strerror(errno));
return;
}
if ( (c3n == _ce_image_copy(&u3P.nor_u, &nop_u))
|| (c3n == _ce_image_copy(&u3P.sou_u, &sop_u)) )
{
unlink(ful_c);
snprintf(ful_c, 8192, "%s/.urb/bhk/%s.bin", u3P.dir_c, nop_u.nam_c);
unlink(ful_c);
snprintf(ful_c, 8192, "%s/.urb/bhk", u3P.dir_c);
rmdir(ful_c);
}
close(nop_u.fid_i);
close(sop_u.fid_i);
}
/*
u3e_save(): save current changes.
@ -830,6 +923,8 @@ u3e_save(void)
_ce_image_sync(&u3P.sou_u);
_ce_patch_free(pat_u);
_ce_patch_delete();
_ce_backup();
}
/* u3e_live(): start the checkpointing system.

View File

@ -236,50 +236,6 @@ _dawn_need_unit(u3_noun nit, c3_c* msg_c)
}
}
/* _dawn_purl(): ethereum gateway url as (unit purl)
*/
static u3_noun
_dawn_purl(u3_noun rac)
{
u3_noun url;
if ( 0 == u3_Host.ops_u.eth_c ) {
if ( c3__czar == rac ) {
u3l_log("boot: galaxy requires ethereum gateway via -e\r\n");
exit(1);
}
url = u3_nul;
}
else {
// XX call de-purl directly
//
u3_noun par = u3v_wish("auru:de-purl:html");
u3_noun lur = u3i_string(u3_Host.ops_u.eth_c);
u3_noun rul = u3dc("rush", u3k(lur), u3k(par));
if ( u3_nul == rul ) {
if ( c3__czar == rac ) {
u3l_log("boot: galaxy requires ethereum gateway via -e\r\n");
exit(1);
}
url = u3_nul;
}
else {
// XX revise for de-purl
// auru:de-purl:html parses to (pair user purl)
// we need (unit purl)
//
url = u3nc(u3_nul, u3k(u3t(u3t(rul))));
}
u3z(par); u3z(lur); u3z(rul);
}
return url;
}
/* _dawn_turf(): override contract domains with -H
*/
static u3_noun
@ -330,30 +286,13 @@ _dawn_sponsor(u3_noun who, u3_noun rac, u3_noun pot)
u3_noun
u3_dawn_vent(u3_noun ship, u3_noun feed)
{
u3_noun url, bok, sed, pos, pon, zar, tuf;
u3_noun sed, pos, pon, zar, tuf;
u3_noun rank = u3do("clan:title", u3k(ship));
url = _dawn_purl(rank);
// XX require https?
//
c3_c* url_c = ( 0 != u3_Host.ops_u.eth_c ) ?
u3_Host.ops_u.eth_c :
"http://eth-mainnet.urbit.org:8545";
// pin block number
//
{
u3l_log("boot: retrieving latest block\r\n");
u3_noun oct = u3v_wish("bloq:give:dawn");
u3_noun kob = _dawn_eth_rpc(url_c, u3k(oct));
bok = _dawn_need_unit(u3do("bloq:take:dawn", u3k(kob)),
"boot: block retrieval failed");
u3z(oct); u3z(kob);
}
"https://roller.urbit.org/v1/azimuth";
{
// +point:azimuth: on-chain state
@ -373,7 +312,7 @@ u3_dawn_vent(u3_noun ship, u3_noun feed)
u3_Host.ops_u.who_c);
{
u3_noun oct = u3dc("point:give:dawn", u3k(bok), u3k(ship));
u3_noun oct = u3do("point:give:dawn", u3k(ship));
u3_noun luh = _dawn_eth_rpc(url_c, u3k(oct));
pot = _dawn_need_unit(u3dc("point:take:dawn", u3k(ship), u3k(luh)),
@ -390,10 +329,6 @@ u3_dawn_vent(u3_noun ship, u3_noun feed)
u3l_log("boot: verifying keys\r\n");
// TODO: remove when L2 is supported
u3l_log("boot: if you're trying to start an L2 ship,"
" upgrade your binary\r\n");
// (each seed (lest error=@tas))
//
sed = u3dq("veri:dawn", u3k(ship), u3k(feed), u3k(pot), u3k(liv));
@ -415,7 +350,7 @@ u3_dawn_vent(u3_noun ship, u3_noun feed)
{
u3l_log("boot: retrieving galaxy table\r\n");
u3_noun oct = u3do("czar:give:dawn", u3k(bok));
u3_noun oct = u3v_wish("czar:give:dawn");
u3_noun raz = _dawn_eth_rpc(url_c, u3k(oct));
zar = _dawn_need_unit(u3do("czar:take:dawn", u3k(raz)),
@ -431,7 +366,7 @@ u3_dawn_vent(u3_noun ship, u3_noun feed)
else {
u3l_log("boot: retrieving network domains\r\n");
u3_noun oct = u3do("turf:give:dawn", u3k(bok));
u3_noun oct = u3v_wish("turf:give:dawn");
u3_noun fut = _dawn_eth_rpc(url_c, u3k(oct));
tuf = _dawn_need_unit(u3do("turf:take:dawn", u3k(fut)),
@ -455,7 +390,7 @@ u3_dawn_vent(u3_noun ship, u3_noun feed)
// retrieve +point:azimuth of pos (sponsor of ship)
//
{
u3_noun oct = u3dc("point:give:dawn", u3k(bok), u3k(pos));
u3_noun oct = u3do("point:give:dawn", u3k(pos));
u3_noun luh = _dawn_eth_rpc(url_c, u3k(oct));
son = _dawn_need_unit(u3dc("point:take:dawn", u3k(pos), u3k(luh)),
@ -478,8 +413,10 @@ u3_dawn_vent(u3_noun ship, u3_noun feed)
// [%dawn seed sponsors galaxies domains block eth-url snap]
//
//NOTE blocknum of 0 is fine because jael ignores it.
// should probably be removed from dawn event.
u3_noun ven = u3nc(c3__dawn,
u3nq(u3k(u3t(sed)), pon, zar, u3nt(tuf, bok, url)));
u3nq(u3k(u3t(sed)), pon, zar, u3nt(tuf, 0, u3_nul)));
u3z(sed); u3z(rank); u3z(pos); u3z(ship); u3z(feed);

View File

@ -751,7 +751,7 @@ u3_disk_init(c3_c* pax_c, u3_disk_cb cb_u)
// "[..] on 64-bit there is no penalty for making this huge (say 1TB)."
//
{
#if defined(U3_CPU_aarch64) && defined(U3_OS_linux)
#if (defined(U3_CPU_aarch64) && defined(U3_OS_linux)) || defined(U3_OS_mingw)
const size_t siz_i = 64424509440;
#else
const size_t siz_i = 1099511627776;

View File

@ -1 +1 @@
1.7
1.8