summaryrefslogtreecommitdiff
path: root/lib/naive.hoon
diff options
context:
space:
mode:
authorpolwex <polwex@sortug.com>2025-06-22 06:14:42 +0700
committerpolwex <polwex@sortug.com>2025-06-22 06:14:42 +0700
commit6dccba9bb5100329209ad01732f9d63f4c4fb43b (patch)
tree140b33d2e25084174fce057056de9dea0e2dcbea /lib/naive.hoon
metamask login getting there
Diffstat (limited to 'lib/naive.hoon')
-rw-r--r--lib/naive.hoon926
1 files changed, 926 insertions, 0 deletions
diff --git a/lib/naive.hoon b/lib/naive.hoon
new file mode 100644
index 0000000..7f46eaf
--- /dev/null
+++ b/lib/naive.hoon
@@ -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)