adds pre-boot ethereum validation (|dawn) and tests

This commit is contained in:
Joe Bryan 2018-08-29 17:04:08 -07:00
parent b2611debb0
commit 536bf47095
2 changed files with 428 additions and 1 deletions

View File

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

282
tests/sys/zuse/dawn.hoon Normal file
View File

@ -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 |])
--