diff --git a/sys/zuse.hoon b/sys/zuse.hoon index e90ca0f93c..836e17b10c 100644 --- a/sys/zuse.hoon +++ b/sys/zuse.hoon @@ -362,7 +362,7 @@ ++ contracts |% ++ ships - 0x6c22.3e68.fefe.b0d2.aaa1.3d5a.3b12.f50f.8b6b.498a + 0x84b3.7fbc.6188.da8a.e866.1eae.322a.f4d9.2db4.5ecc -- :: :: hashes of ship event signatures @@ -7942,4 +7942,149 @@ -- -- -- +:: |dawn: pre-boot request/response de/serialization and validation +:: +++ dawn + => |% + :: +live: public network state of a ship + :: + +$ live (unit [=life breach=?]) + :: +seed: private boot parameters + :: + +$ seed [who=ship lyf=life key=ring sig=(unit oath:pki:jael)] + -- + |% + :: |give:dawn: produce requests for pre-boot validation + :: + ++ give + =/ tract ships:contracts:constitution:ethe + |% + :: +czar:give:dawn: Eth RPC for galaxy table + :: + ++ czar + ^- octs + %- as-octt:mimes:html + %- en-json:html + %- batch-read-request:ethereum + %+ turn (gulf 0 255) + |=(gal=@ [`(scot %ud gal) tract ['getKeys(uint32)' [%uint gal]~]]) + :: +hull:give:dawn: Eth RPC for ship's contract state + :: + ++ hull + |= who=ship + ^- octs + %- as-octt:mimes:html + %- en-json:html + (read-request:ethereum [~ tract ['ships(uint32)' [%uint `@`who]~]]) + :: +turf:give:dawn: Eth RPC for network domains + :: + ++ turf + ^- octs + %- as-octt:mimes:html + %- en-json:html + %- batch-read-request:ethereum + %+ turn (gulf 0 2) + |=(idx=@ [`(scot %ud idx) tract ['dnsDomains(uint256)' [%uint idx]~]]) + -- + :: |take:dawn: parse responses for pre-boot validation + :: + ++ take + =, dejs:format + |% + :: +czar:take:dawn: parse galaxy table + :: + ++ czar + |= rep=octs + ^- (map ship [=life =pass]) + =/ jon=json (need (de-json:html q.rep)) + =/ res=(list [@t @t]) + ((ar (ot id+so result+so ~)) jon) + %+ roll res + |= $: res=[id=@t result=@t] + kyz=(map ship [=life =pass]) + == + ^+ kyz + =/ who=ship (slav %ud id.res) + =+ ^- [enc=octs aut=octs sut=@ud rev=@ud] + %+ decode-results:ethereum + result.res + ~[[%bytes-n 32] [%bytes-n 32] %uint %uint] + =/ pub=(unit pass) + (pass-from-eth:constitution:ethereum enc aut sut) + ?~ pub kyz + (~(put by kyz) who [rev u.pub]) + :: +hull:take:dawn: parse ship's contract state + :: + ++ hull + |= [who=ship rep=octs] + ^- hull:constitution:ethe + =/ jon=json (need (de-json:html q.rep)) + =/ res=cord ((ot result+so ~) jon) + %+ hull-from-eth:constitution:ethereum + who + :_ *deed:eth-noun:constitution:ethereum + (decode-results:ethereum res hull:eth-type:constitution:ethe) + :: +turf:take:dawn: parse network domains + :: + ++ turf + |= rep=octs + ^- (list [@ud (list @ta)]) + =/ jon=json (need (de-json:html q.rep)) + =/ res=(list [@t @t]) + ((ar (ot id+so result+so ~)) jon) + %+ turn res + |= [id=@t result=@t] + :- (slav %ud id) + =/ dom=tape + (decode-results:ethereum result [%string]~) + =/ hot=host:eyre + (scan dom thos:de-purl:html) + ?>(?=(%& -.hot) p.hot) + -- + :: +veri:dawn: validate keys, life, discontinuity, &c + :: + ++ veri + |= [=seed =hull:constitution:ethe =live] + ^- $% [%& ^seed (unit ship)] + [%| rank:ames @tas] + == + =/ rac (clan:title who.seed) + =/ cub (nol:nu:crub:crypto key.seed) + ?- rac + %pawn + ?. =(who.seed `@`fig:ex:cub) + [%| rac %key-mismatch] + ?^ live + [%| rac %already-booted] + ?. ?=(%1 lyf.seed) + [%| rac %invalid-life] + [%& seed ~] + :: + %earl + ?~ sig.seed + [%| rac %missing-sig] + ?~ net.hull + [%| rac %parent-not-keyed] + =/ loy (com:nu:crub:crypto pass.u.net.hull) + =/ hax (shaf %earl (sham lyf.seed pub:ex:cub)) + ?. =((some hax) (sure:as:loy u.sig.seed)) + [%| rac %invalid-sig] + :: XX revisit for rekey + ?^ live + [%| rac %already-booted] + [%& seed ~] + :: + * + ?~ net.hull + [%| rac %not-keyed] + ?. =(pub:ex:cub pass.u.net.hull) + [%| rac %key-mismatch] + ?: ?& ?=(^ live) + ?| ?=(%| breach.u.live) + (lte life.u.net.hull life.u.live) + == == + [%| rac %already-booted] + [%& seed sponsor.u.net.hull] + == + -- -- :: diff --git a/tests/sys/zuse/dawn.hoon b/tests/sys/zuse/dawn.hoon new file mode 100644 index 0000000000..f5401e29aa --- /dev/null +++ b/tests/sys/zuse/dawn.hoon @@ -0,0 +1,282 @@ +/+ *test +|% +:: example hull for ~zod +:: +++ hul + ^- hull:constitution:ethe + :+ [0x0 0x0 0x0 0x0] + :* ~ + life=1 + 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 + continuity-number=0 + sponsor=[~ u=~zod] + escape=~ + == + [~ u=[spawn-proxy=0x0 spawn-count=2 spawned=~]] +:: secret key for ~zod +:: +++ sec + ^- ring + 0w8.Ugyke.eUOf2.NcHRo.tZA7r.P8vP6.DGKp4.yn-BI.etdzb.ucv75.WgRob.H1-7n. + 4qCje.gc7z7.1i-3T.9~8UR.IGkGH.6NWR2 +:: Ships contract address +:: +++ ships + %- crip + %+ weld "0x" + (render-hex-bytes:ethereum 20 `@`ships:contracts:constitution:ethe) +:: this produces a 1000+ line payload, so we just check that it doesn't crash +:: +++ test-give-czar + =/ zar czar:give:dawn + ~! zar + %+ expect-eq + !> & + !> ?=(^ zar) +:: +++ test-give-hull + =/ oct + %- as-octs:mimes:html + %+ rap 3 + :~ '{"jsonrpc":"2.0","method":"eth_call","params":[{"data":"' + '0xb3220694' + '0000000000000000000000000000000000000000000000000000000000000000' + '","to":"' ships '"},"latest"]}' + == + %+ expect-eq + !> oct + !> (hull:give:dawn ~zod) +:: +++ test-give-turf + =/ oct + %- as-octs:mimes:html + %+ rap 3 + :~ '[{"jsonrpc":"2.0","id":"0","method":"eth_call","params":[{"data":"' + '0xeccc8ff1' + '0000000000000000000000000000000000000000000000000000000000000000' + '","to":"' ships '"},"latest"]},' + '{"jsonrpc":"2.0","id":"1","method":"eth_call","params":[{"data":"' + '0xeccc8ff1' + '0000000000000000000000000000000000000000000000000000000000000001' + '","to":"' ships '"},"latest"]},' + '{"jsonrpc":"2.0","id":"2","method":"eth_call","params":[{"data":"' + '0xeccc8ff1' + '0000000000000000000000000000000000000000000000000000000000000002' + '","to":"' ships '"},"latest"]}]' + == + %+ expect-eq + !> oct + !> turf:give:dawn +:: +++ test-take-czar + =/ oct + %- as-octs:mimes:html + %+ rap 3 + :~ '[{"id":"0","jsonrpc":"2.0","result":"' + '0xb69b6818b17b7cc22f8e0a2291f58e4aa840cbf44cb2f1c94dc3d71e3cda0d94' + '3defb87516f42ce4327820b588002aa53e52527af8d23bee4aa215fa296bdf5f' + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000001' + '"},{"id":"1","jsonrpc":"2.0","result":"' + '0xb727e38d031162e50913b2e37a2e29d4ba457eff4f7fd4ac47dc68fcb54260d3' + 'b8bfe4789483c171f7fa359438cdcc8d268d40fe08d6c1d8b36267748d2139f8' + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000001' + '"},{"id":"2","jsonrpc":"2.0","result":"' + '0x0000000000000000000000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000000000000' + '"}]' + == + =/ 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 [=life =pass])) + [[~zod 1 zod.kyz] [~nec 1 nec.kyz] ~] + !> (czar:take:dawn oct) +:: +++ test-take-hull + =/ oct + %- as-octs:mimes:html + %+ rap 3 + :~ '{"jsonrpc":"2.0","result":"' + '0x0000000000000000000000000000000000000000000000000000000000000001' + 'b69b6818b17b7cc22f8e0a2291f58e4aa840cbf44cb2f1c94dc3d71e3cda0d94' + '3defb87516f42ce4327820b588002aa53e52527af8d23bee4aa215fa296bdf5f' + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000000000000' + '"}' + == + %+ expect-eq + !> hul + !> (hull:take:dawn ~zod oct) +:: +++ test-take-turf + =/ oct + %- as-octs:mimes:html + %+ rap 3 + :~ '[{"id":"0","jsonrpc":"2.0","result":"' + '0x0000000000000000000000000000000000000000000000000000000000000020' + '0000000000000000000000000000000000000000000000000000000000000009' + '75726269742e6f72670000000000000000000000000000000000000000000000' + '"},{"id":"1","jsonrpc":"2.0","result":"' + '0x0000000000000000000000000000000000000000000000000000000000000020' + '0000000000000000000000000000000000000000000000000000000000000009' + '75726269742e6f72670000000000000000000000000000000000000000000000' + '"},{"id":"2","jsonrpc":"2.0","result":"' + '0x0000000000000000000000000000000000000000000000000000000000000020' + '0000000000000000000000000000000000000000000000000000000000000009' + '75726269742e6f72670000000000000000000000000000000000000000000000' + '"}]' + == + %+ expect-eq + !> [[0 /org/urbit] [1 /org/urbit] [2 /org/urbit] ~] + !> (turf:take:dawn oct) +:: +++ test-veri-good + =/ sed [~zod 1 sec ~] + %+ expect-eq + !> [%& sed `~zod] + !> (veri:dawn sed hul ~) +:: +++ test-veri-not-spawned + =/ sed [~zod 1 sec ~] + %+ expect-eq + !> [%| %czar %not-keyed] + !> (veri:dawn sed =>(hul .(net ~)) ~) +:: +++ test-veri-wrong-key + =/ sed [~zod 1 sec:ex:(pit:nu:crub:crypto 24 %foo) ~] + %+ expect-eq + !> [%| %czar %key-mismatch] + !> (veri:dawn sed hul ~) +:: +++ test-veri-already-booted + =/ sed [~zod 1 sec ~] + ;: weld + %+ expect-eq + !> [%| %czar %already-booted] + !> (veri:dawn sed hul `[1 |]) + :: + %+ expect-eq + !> [%| %czar %already-booted] + !> (veri:dawn sed hul `[2 &]) + == +:: +++ test-veri-earl-good + =/ cub (pit:nu:crub:crypto 24 %foo) + =/ who ~simtel-mithet-dozzod-dozzod + =/ sed + =/ sig + %- sign:as:(nol:nu:crub:crypto sec) + (shaf %earl (sham 1 pub:ex:cub)) + [who 1 sec:ex:cub `sig] + %+ expect-eq + !> [%& sed ~] + !> (veri:dawn sed hul ~) +:: +++ test-veri-earl-missing-sig + =/ cub (pit:nu:crub:crypto 24 %foo) + =/ who ~simtel-mithet-dozzod-dozzod + =/ sed + [who 1 sec:ex:cub ~] + %+ expect-eq + !> [%| %earl %missing-sig] + !> (veri:dawn sed hul ~) +:: +++ test-veri-earl-parent-not-keyed + =/ cub (pit:nu:crub:crypto 24 %foo) + =/ who ~simtel-mithet-dozzod-dozzod + =/ sed + =/ sig + %- sign:as:(nol:nu:crub:crypto sec) + (shaf %earl (sham 1 pub:ex:cub)) + [who 1 sec:ex:cub `sig] + %+ expect-eq + !> [%| %earl %parent-not-keyed] + !> (veri:dawn sed =>(hul .(net ~)) ~) +:: +++ test-veri-earl-invalid-sig + =/ cub (pit:nu:crub:crypto 24 %foo) + =/ who ~simtel-mithet-dozzod-dozzod + ;: weld + =/ sed + =/ sig + %- sign:as:cub + (shaf %earl (sham 1 pub:ex:cub)) + [who 1 sec:ex:cub `sig] + %+ expect-eq + !> [%| %earl %invalid-sig] + !> (veri:dawn sed hul ~) + :: + =/ sed + =/ sig + %- sign:as:(nol:nu:crub:crypto sec) + (shaf %earl (sham 2 pub:ex:cub)) + [who 1 sec:ex:cub `sig] + %+ expect-eq + !> [%| %earl %invalid-sig] + !> (veri:dawn sed hul ~) + == +:: +++ test-veri-earl-already-booted + =/ cub (pit:nu:crub:crypto 24 %foo) + =/ who ~simtel-mithet-dozzod-dozzod + =/ sed + =/ sig + %- sign:as:(nol:nu:crub:crypto sec) + (shaf %earl (sham 1 pub:ex:cub)) + [who 1 sec:ex:cub `sig] + %+ expect-eq + !> [%| %earl %already-booted] + !> (veri:dawn sed hul `[1 |]) +:: +++ test-veri-pawn-good + =/ cub (pit:nu:crub:crypto 24 %foo) + =/ who=ship `@`fig:ex:cub + =/ sed [who 1 sec:ex:cub ~] + %+ expect-eq + !> [%& sed ~] + !> (veri:dawn sed *hull:constitution:ethe ~) +:: +++ test-veri-pawn-key-mismatch + =/ cub (pit:nu:crub:crypto 24 %foo) + =/ who=ship `@`fig:ex:cub + =/ sed [who 1 sec:ex:(pit:nu:crub:crypto 24 %bar) ~] + %+ expect-eq + !> [%| %pawn %key-mismatch] + !> (veri:dawn sed *hull:constitution:ethe ~) +:: +++ test-veri-pawn-invalid-life + =/ cub (pit:nu:crub:crypto 24 %foo) + =/ who=ship `@`fig:ex:cub + =/ sed [who 2 sec:ex:cub ~] + %+ expect-eq + !> [%| %pawn %invalid-life] + !> (veri:dawn sed *hull:constitution:ethe ~) +:: +++ test-veri-pawn-already-booted + =/ cub (pit:nu:crub:crypto 24 %foo) + =/ who=ship `@`fig:ex:cub + =/ sed [who 1 sec:ex:cub ~] + %+ expect-eq + !> [%| %pawn %already-booted] + !> (veri:dawn sed *hull:constitution:ethe `[1 |]) +--