mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-09-21 07:28:30 +03:00
naive: move signature verification inside loop
Before this change, signatures were verified according to the owners at the beginning of batch, which is wrong. Now we do it per wrap, but this is *also* wrong because they should actually be verified per tx, in case the owner changes within a wrap. Also introduces the roll/wrap terminology.
This commit is contained in:
parent
f9e93fa660
commit
05dbd8cddd
@ -28,6 +28,8 @@
|
|||||||
--
|
--
|
||||||
::
|
::
|
||||||
|%
|
|%
|
||||||
|
:: TODO: is `dat` supposed to be a 32-byte hash? I guess so
|
||||||
|
::
|
||||||
++ verifier
|
++ verifier
|
||||||
^- ^verifier:naive
|
^- ^verifier:naive
|
||||||
|= [dat=@ v=@ r=@ s=@]
|
|= [dat=@ v=@ r=@ s=@]
|
||||||
|
@ -31,6 +31,10 @@
|
|||||||
::
|
::
|
||||||
:: TODO: could remove `ship` from most txs since it's in `from`
|
:: TODO: could remove `ship` from most txs since it's in `from`
|
||||||
::
|
::
|
||||||
|
:: TODO: hmm i don't think wraps can be done easily? because how do
|
||||||
|
:: you keep track of intra-wrap ownership changes. you need to verify
|
||||||
|
:: the eth signature outside, then verify owner as you go along
|
||||||
|
::
|
||||||
/+ std
|
/+ std
|
||||||
=> => std
|
=> => std
|
||||||
:: Laconic bit
|
:: Laconic bit
|
||||||
@ -186,8 +190,9 @@
|
|||||||
+$ operators (jug address address)
|
+$ operators (jug address address)
|
||||||
+$ effects (list diff)
|
+$ effects (list diff)
|
||||||
+$ proxy ?(%own %spawn %manage %vote %transfer)
|
+$ proxy ?(%own %spawn %manage %vote %transfer)
|
||||||
+$ tx
|
+$ roll (list wrap)
|
||||||
[from=[=ship =proxy] skim-tx]
|
+$ wrap [raw=@ txs=(list tx)]
|
||||||
|
+$ tx [from=[=ship =proxy] skim-tx]
|
||||||
+$ skim-tx
|
+$ skim-tx
|
||||||
$% [%transfer-point =ship =address reset=?]
|
$% [%transfer-point =ship =address reset=?]
|
||||||
[%spawn =ship =address]
|
[%spawn =ship =address]
|
||||||
@ -224,43 +229,36 @@
|
|||||||
~> %slog.[0 meg]
|
~> %slog.[0 meg]
|
||||||
+<+
|
+<+
|
||||||
::
|
::
|
||||||
++ parse-batch
|
++ parse-roll
|
||||||
|= [=verifier =state batch=@]
|
|= [=state batch=@]
|
||||||
^- (list tx)
|
=| =roll
|
||||||
=| txs=(list tx)
|
|- ^+ roll
|
||||||
|- ^- (list tx)
|
|
||||||
?~ batch
|
?~ batch
|
||||||
(flop txs)
|
(flop roll)
|
||||||
=/ parse-result (parse-tx verifier state batch)
|
=/ parse-result (parse-wrap state batch)
|
||||||
:: Parsing failed, abort batch
|
:: Parsing failed, abort batch
|
||||||
::
|
::
|
||||||
?~ parse-result
|
?~ parse-result
|
||||||
(debug %parse-failed ~)
|
(debug %parse-failed ~)
|
||||||
=^ signed=(list tx) batch u.parse-result
|
=^ =wrap batch u.parse-result
|
||||||
$(txs (welp (flop signed) txs))
|
$(roll [wrap roll])
|
||||||
::
|
::
|
||||||
:: TODO: change batch to be a cursor to avoid allocating atoms
|
:: TODO: change batch to be a cursor to avoid allocating atoms
|
||||||
::
|
::
|
||||||
++ parse-tx
|
++ parse-wrap
|
||||||
|= [=verifier =state batch=@]
|
|= [=state batch=@]
|
||||||
^- (unit [(list tx) rest=@])
|
^- (unit [wrap rest=@])
|
||||||
=/ batch [len=0 rest=batch]
|
=/ batch [len=0 rest=batch]
|
||||||
|^
|
|
||||||
=^ sig batch (take 3 65)
|
|
||||||
:: TODO: reset len?
|
|
||||||
::
|
|
||||||
=/ signed-batch +.batch
|
|
||||||
=- ?~ res
|
=- ?~ res
|
||||||
~
|
~
|
||||||
:- ~
|
`[[(end [0 len.batch.u.res] rest.batch) txs.u.res] rest.batch.u.res]
|
||||||
?. (verify-sig-and-nonce txs.u.res sig len.batch.u.res signed-batch)
|
|^
|
||||||
[(debug %sig-failed ~) rest.batch.u.res]
|
=^ sig batch (take 3 65)
|
||||||
[txs.u.res rest.batch.u.res]
|
|
||||||
^- res=(unit [txs=(list tx) =_batch])
|
^- res=(unit [txs=(list tx) =_batch])
|
||||||
=^ single=@ batch (take 0)
|
=^ single=@ batch (take 0)
|
||||||
?: =(0 single)
|
?: =(0 single)
|
||||||
:: Single tx
|
:: Single tx
|
||||||
=/ single-res=(unit [=tx batch=_batch]) parse-single-tx
|
=/ single-res=(unit [=tx batch=_batch]) parse-tx
|
||||||
?~ single-res
|
?~ single-res
|
||||||
~
|
~
|
||||||
`[[tx.u.single-res ~] batch.u.single-res]
|
`[[tx.u.single-res ~] batch.u.single-res]
|
||||||
@ -274,7 +272,7 @@
|
|||||||
?: =(count 0)
|
?: =(count 0)
|
||||||
`[~ batch]
|
`[~ batch]
|
||||||
=^ pad batch (take 0) :: byte align
|
=^ pad batch (take 0) :: byte align
|
||||||
=/ next-res=(unit [=tx batch=_batch]) parse-single-tx
|
=/ next-res=(unit [=tx batch=_batch]) parse-tx
|
||||||
?~ next-res
|
?~ next-res
|
||||||
~
|
~
|
||||||
=. batch batch.u.next-res
|
=. batch batch.u.next-res
|
||||||
@ -284,7 +282,7 @@
|
|||||||
=. batch batch.u.rest-res
|
=. batch batch.u.rest-res
|
||||||
`[[tx.u.next-res txs.u.rest-res] batch]
|
`[[tx.u.next-res txs.u.rest-res] batch]
|
||||||
::
|
::
|
||||||
++ parse-single-tx
|
++ parse-tx
|
||||||
^- (unit [tx _batch])
|
^- (unit [tx _batch])
|
||||||
=^ from-proxy=@ batch (take 0 3)
|
=^ from-proxy=@ batch (take 0 3)
|
||||||
?: (gth from-proxy 4) (debug %bad-proxy ~)
|
?: (gth from-proxy 4) (debug %bad-proxy ~)
|
||||||
@ -355,33 +353,33 @@
|
|||||||
=^ child=ship batch (take 3 4)
|
=^ child=ship batch (take 3 4)
|
||||||
=^ parent=ship batch (take 3 4)
|
=^ parent=ship batch (take 3 4)
|
||||||
[[child parent] batch]
|
[[child parent] batch]
|
||||||
::
|
--
|
||||||
++ verify-sig-and-nonce
|
::
|
||||||
|= [txs=(list tx) sig=@ len=@ud signed-batch=@]
|
++ verify-sig-and-nonce
|
||||||
^- ?
|
|= [=verifier =state =wrap]
|
||||||
=/ creds=(list [=address =nonce])
|
^- ?
|
||||||
%+ turn txs
|
|^
|
||||||
|= =tx
|
=/ creds=(list [=address =nonce])
|
||||||
=/ point (get-point state ship.from.tx)
|
%+ turn txs.wrap
|
||||||
?> ?=(^ point) :: we never parse more than four bytes
|
|= =tx
|
||||||
?- proxy.from.tx
|
=/ point (get-point state ship.from.tx)
|
||||||
%own owner.own.u.point
|
?> ?=(^ point) :: we never parse more than four bytes
|
||||||
%spawn spawn-proxy.own.u.point
|
?- proxy.from.tx
|
||||||
%manage management-proxy.own.u.point
|
%own owner.own.u.point
|
||||||
%vote voting-proxy.own.u.point
|
%spawn spawn-proxy.own.u.point
|
||||||
%transfer transfer-proxy.own.u.point
|
%manage management-proxy.own.u.point
|
||||||
==
|
%vote voting-proxy.own.u.point
|
||||||
=/ nonces (turn creds |=([* =nonce] nonce))
|
%transfer transfer-proxy.own.u.point
|
||||||
=/ signed-data
|
==
|
||||||
%: can 0
|
=/ nonces (turn creds |=([* =nonce] nonce))
|
||||||
[(mul (bex 5) (lent nonces)) (rep 5 nonces)]
|
=/ sig (end [3 65] raw.wrap)
|
||||||
[len (end [0 len] signed-batch)]
|
=/ signed-data
|
||||||
~
|
%^ dad [5 (lent nonces)] (rep 5 nonces)
|
||||||
==
|
(rsh [3 65] raw.wrap)
|
||||||
=/ dress (verify-sig sig signed-data)
|
=/ dress (verify-sig sig signed-data)
|
||||||
?~ dress
|
?~ dress
|
||||||
|
|
|
|
||||||
(levy creds |=([=address *] =(address u.dress)))
|
(levy creds |=([=address *] =(address u.dress)))
|
||||||
:: Verify signature and produce signer address
|
:: Verify signature and produce signer address
|
||||||
::
|
::
|
||||||
++ verify-sig
|
++ verify-sig
|
||||||
@ -596,21 +594,36 @@
|
|||||||
::
|
::
|
||||||
++ receive-batch
|
++ receive-batch
|
||||||
|= [=verifier =state batch=@]
|
|= [=verifier =state batch=@]
|
||||||
=/ txs=(list tx) (parse-batch verifier state batch)
|
=/ =roll (parse-roll state batch)
|
||||||
|
:: Handle each wrap
|
||||||
|
::
|
||||||
|- ^- [effects ^state]
|
|- ^- [effects ^state]
|
||||||
?~ txs
|
=* roll-loop $
|
||||||
|
?~ roll
|
||||||
[~ state]
|
[~ state]
|
||||||
|
:: Verify signature, else skip wrap
|
||||||
|
::
|
||||||
|
=* wrap i.roll
|
||||||
|
?. (verify-sig-and-nonce verifier state wrap)
|
||||||
|
%+ debug %l2-sig-failed
|
||||||
|
roll-loop(roll t.roll)
|
||||||
|
:: Handle each transaction in this wrap
|
||||||
|
::
|
||||||
|
|- ^- [effects ^state]
|
||||||
|
=* wrap-loop $
|
||||||
|
?~ txs.wrap
|
||||||
|
roll-loop(roll t.roll)
|
||||||
:: Increment nonce, even if it later fails
|
:: Increment nonce, even if it later fails
|
||||||
::
|
::
|
||||||
=^ effects-1 points.state (increment-nonce state from.i.txs)
|
=^ effects-1 points.state (increment-nonce state from.i.txs.wrap)
|
||||||
:: Process tx
|
:: Process tx
|
||||||
::
|
::
|
||||||
=^ effects-2 state
|
=^ effects-2 state
|
||||||
=/ tx-result=(unit [effects ^state]) (receive-tx state i.txs)
|
=/ tx-result=(unit [effects ^state]) (receive-tx state i.txs.wrap)
|
||||||
?~ tx-result
|
?~ tx-result
|
||||||
(debug %l2-tx-failed `state)
|
(debug %l2-tx-failed `state)
|
||||||
u.tx-result
|
u.tx-result
|
||||||
=^ effects-3 state $(txs t.txs)
|
=^ effects-3 state wrap-loop(txs.wrap t.txs.wrap)
|
||||||
[:(welp effects-1 effects-2 effects-3) state]
|
[:(welp effects-1 effects-2 effects-3) state]
|
||||||
::
|
::
|
||||||
++ increment-nonce
|
++ increment-nonce
|
||||||
|
Loading…
Reference in New Issue
Block a user