diff --git a/pkg/arvo/app/azimuth-tracker.hoon b/pkg/arvo/app/azimuth-tracker.hoon index 4b6766e4d..3bb450579 100644 --- a/pkg/arvo/app/azimuth-tracker.hoon +++ b/pkg/arvo/app/azimuth-tracker.hoon @@ -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] diff --git a/pkg/arvo/app/eth-watcher.hoon b/pkg/arvo/app/eth-watcher.hoon index 419e041f3..b6fd6f0a0 100644 --- a/pkg/arvo/app/eth-watcher.hoon +++ b/pkg/arvo/app/eth-watcher.hoon @@ -8,7 +8,7 @@ => |% +$ card card:agent:gall +$ app-state - $: %4 + $: %5 dogs=(map path watchdog) == :: @@ -111,14 +111,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] :: @@ -128,10 +130,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 @@ -142,8 +214,8 @@ $: config-3 running=(unit =tid:spider) =number:block - =pending-logs - =history + =pending-logs-4 + =history-4 blocks=(list block) == :: @@ -170,8 +242,8 @@ $: config-1 running=(unit =tid:spider) =number:block - =pending-logs - =history + =pending-logs-4 + =history-4 blocks=(list block) == :: @@ -192,8 +264,8 @@ $: config-0 running=(unit =tid:spider) =number:block - =pending-logs - =history + =pending-logs-4 + =history-4 blocks=(list block) == :: @@ -225,6 +297,7 @@ == :: =/ already (~(has by dogs.state) path.poke) + ~& [already=already restart=restart] ~? &(already restart) [dap.bowl 'overwriting existing watchdog on' path.poke] =/ wait-cards=(list card) @@ -389,9 +462,10 @@ ++ release-logs |= [=path dog=watchdog] ^- (quip card watchdog) - ?: (lth number.dog 30) + ~& > release-logs=pending-logs.dog + ?: (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 diff --git a/pkg/arvo/app/gaze.hoon b/pkg/arvo/app/gaze.hoon index 342348028..8b7cef5b4 100644 --- a/pkg/arvo/app/gaze.hoon +++ b/pkg/arvo/app/gaze.hoon @@ -210,6 +210,7 @@ public:mainnet-contracts ~[azimuth delegated-sending]:mainnet-contracts ~ + ~ == :: :: see also comment in +setup-cards diff --git a/pkg/arvo/app/naive.hoon b/pkg/arvo/app/naive.hoon index e09cb9379..3e65091a6 100644 --- a/pkg/arvo/app/naive.hoon +++ b/pkg/arvo/app/naive.hoon @@ -3,7 +3,7 @@ =, jael |% ++ app-state - $: %0 + $: %1 url=@ta whos=(set ship) nas=^state:naive @@ -39,39 +39,41 @@ ++ topics |= ships=(set ship) ^- (list ?(@ux (list @ux))) - ?: & ~ - :: The first topic should be one of these event types - :: - :- => azimuth-events:azimuth - :~ broke-continuity - changed-keys - lost-sponsor - escape-accepted - == - :: If we're looking for a specific set of ships, specify them as - :: the second topic. Otherwise don't specify the second topic so - :: we will match all ships. - :: - ?: =(~ ships) - ~ - [(turn ~(tap in ships) ,@) ~] + ~ +:: +++ data-to-hex + |= data=@t + ?~ data *@ux + ?: =(data '0x') *@ux + (hex-to-num:ethereum data) :: ++ run-logs |= [nas=^state:naive logs=(list event-log:rpc:ethereum)] ^- [(list tagged-diff) ^state:naive] + ~& > run-logs=logs ?~ logs + ~& >> %done `nas ?~ mined.i.logs + ~& >> %majored $(logs t.logs) =^ raw-effects nas - =/ data - ?~ data.i.logs *@ux - ?: =(data.i.logs '0x') *@ux - ~| data.i.logs - (hex-to-num:ethereum data.i.logs) - =/ =event-log:naive - [address.i.logs data topics.i.logs] - =/ res (mule |.((naive verifier nas %log event-log))) + =/ =^input:naive + ?: =(azimuth:contracts:azimuth address.i.logs) + ~& >> %amizuth + =/ data (data-to-hex data.i.logs) + =/ =event-log:naive + [address.i.logs data topics.i.logs] + [%log event-log] + ~& >> %layer-2 + ?~ input.u.mined.i.logs + ~& [%strange-no-batch-2 i.logs] + [%bat *@] + ?. =(0x2688.7f26 (end [3 4] (swp 5 u.input.u.mined.i.logs))) + ~& [%strange-no-batch-3 i.logs `@ux`(end [3 4] (swp 5 u.input.u.mined.i.logs))] + [%bat *@] + [%bat (rsh [3 4] u.input.u.mined.i.logs)] + =/ res (mule |.((%*(. naive lac |) verifier nas input))) ?- -.res %& p.res %| ((slog 'naive-fail' p.res) `nas) @@ -85,7 +87,7 @@ ++ run-batch |= [nas=^state:naive batch=@] ^+ *naive - (naive verifier nas %bat batch) + (%*(. naive lac |) verifier nas %bat batch) :: ++ to-udiffs |= effects=(list tagged-diff) @@ -122,7 +124,8 @@ ^- config:eth-watcher :* url.state =(%czar (clan:title our)) ~m5 ~h30 launch:contracts:azimuth - ~[azimuth:contracts:azimuth] + ~ :: ~[azimuth:contracts:azimuth] + ~[naive:contracts:azimuth] (topics whos.state) == [%pass /wa %agent [our %eth-watcher] %poke %eth-watcher-poke args] @@ -145,7 +148,42 @@ ++ on-save !>(state) ++ on-load |= old=vase - `this(state !<(app-state old)) + |^ + =+ !<(old-state=app-states old) + =? old-state ?=(%0 -.old-state) + %= old-state + - %1 + logs + %+ turn logs.old-state + |= =event-log-0 + event-log-0(mined ?~(mined.event-log-0 ~ `mined.event-log-0)) + == + `this(state ?>(?=(%1 -.old-state) old-state)) + :: + ++ app-states $%(app-state-0 app-state) + ++ app-state-0 + $: %0 + url=@ta + whos=(set ship) + nas=^state:naive + logs=(list =event-log-0) + == + :: + +$ event-log-0 + $: $= 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) + == + -- :: ++ on-poke |= [=mark =vase] @@ -207,13 +245,16 @@ :: =. logs.state ?- -.diff - %history loglist.diff + :: %history loglist.diff + %history (welp logs.state loglist.diff) %logs (welp logs.state loglist.diff) == + =? nas.state ?=(%history -.diff) *^state:naive =^ effects nas.state %+ run-logs ?- -.diff - %history *^state:naive + :: %history *^state:naive + %history nas.state %logs nas.state == loglist.diff diff --git a/pkg/arvo/lib/azimuth.hoon b/pkg/arvo/lib/azimuth.hoon index 0d42991ad..dbfeb31ae 100644 --- a/pkg/arvo/lib/azimuth.hoon +++ b/pkg/arvo/lib/azimuth.hoon @@ -78,7 +78,7 @@ :: # constants :: :: contract addresses - ++ contracts mainnet-contracts + ++ contracts local-contracts ++ mainnet-contracts |% :: azimuth: data contract @@ -98,6 +98,9 @@ ++ delegated-sending 0xf790.8ab1.f1e3.52f8.3c5e.bc75.051c.0565.aeae.a5fb :: + ++ naive + 0x45bc.b745.a1af.e67a.c877.e107.5478.2329.4ba9.0899 + :: :: launch: block number of azimuth deploy :: ++ launch 6.784.800 @@ -149,6 +152,8 @@ 0x35eb.3b10.2d9c.1b69.ac14.69c1.b1fe.1799.850c.d3eb ++ launch 0 ++ public 0 + ++ naive + 0xe604.2703.475d.0dd1.bc2e.b564.a55f.1832.c252.7171 -- :: :: ++ azimuth 0x863d.9c2e.5c4c.1335.96cf.ac29.d552.55f0.d0f8.6381 :: local bridge diff --git a/pkg/arvo/lib/ethereum.hoon b/pkg/arvo/lib/ethereum.hoon index cd1c54972..e2ae7a228 100644 --- a/pkg/arvo/lib/ethereum.hoon +++ b/pkg/arvo/lib/ethereum.hoon @@ -481,6 +481,7 @@ 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-transaction-receipt txh=@ux] [%eth-send-raw-transaction dat=@ux] @@ -497,10 +498,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 @@ -706,6 +717,9 @@ :~ (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)) ~] @@ -793,7 +807,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)) @@ -812,6 +826,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 diff --git a/pkg/arvo/lib/ethio.hoon b/pkg/arvo/lib/ethio.hoon index a377290e3..fb919460f 100644 --- a/pkg/arvo/lib/ethio.hoon +++ b/pkg/arvo/lib/ethio.hoon @@ -209,6 +209,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)) diff --git a/pkg/arvo/lib/naive.hoon b/pkg/arvo/lib/naive.hoon index d4bfa6771..be323eeed 100644 --- a/pkg/arvo/lib/naive.hoon +++ b/pkg/arvo/lib/naive.hoon @@ -885,6 +885,7 @@ :: Received log from L1 transaction :: (receive-log state event-log.input) +%+ debug %batch :: Received L2 batch :: (receive-batch verifier state batch.input) diff --git a/pkg/arvo/sur/eth-watcher.hoon b/pkg/arvo/sur/eth-watcher.hoon index eb6967d2a..71618721e 100644 --- a/pkg/arvo/sur/eth-watcher.hoon +++ b/pkg/arvo/sur/eth-watcher.hoon @@ -18,6 +18,7 @@ timeout-time=@dr from=number:block contracts=(list address:ethereum) + batchers=(list address:ethereum) =topics == :: diff --git a/pkg/arvo/ted/eth-watcher.hoon b/pkg/arvo/ted/eth-watcher.hoon index b31d43f75..0e2e2d856 100644 --- a/pkg/arvo/ted/eth-watcher.hoon +++ b/pkg/arvo/ted/eth-watcher.hoon @@ -15,6 +15,7 @@ ;< =latest=block bind:m (get-latest-block:ethio url.pup) ;< pup=watchpup bind:m (zoom pup number.id.latest-block) =| vows=disavows +;< pup=watchpup bind:m (fetch-batches pup) ::?. eager.pup (pure:m !>([vows pup])) :: |- ^- form:m @@ -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,8 +82,9 @@ |= [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 10.000 + ~& > [%zoom-start number.pup latest-number] ?: (lth latest-number (add number.pup zoom-margin)) (pure:m pup) =/ up-to-number=number:block (min (add 1.000.000 number.pup) (sub latest-number zoom-margin)) @@ -95,12 +98,62 @@ ;< =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 == + ~& > [%zoom-loglist loglist] =? 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) --