mirror of
https://github.com/urbit/shrub.git
synced 2025-01-04 10:32:34 +03:00
roller: add utilities for handling low-gas batches
This adds support for handling cases where the send-batch thread failed, mainly among them, a thread crash. One of the events that causes this behavior is a ver low gas price for this L1 transaction. Here we add support for manually bumping the price for such transaction, and for increasing the default fallback gas-price, together with discarding any malformed batch from the sending queue.
This commit is contained in:
parent
c467d5aa67
commit
f6ff4f108b
@ -31,7 +31,7 @@
|
|||||||
::
|
::
|
||||||
|%
|
|%
|
||||||
+$ app-state
|
+$ app-state
|
||||||
$: %3
|
$: %4
|
||||||
:: pending: the next l2 txs to be sent
|
:: pending: the next l2 txs to be sent
|
||||||
:: sending: l2 txs awaiting l2 confirmation, ordered by nonce
|
:: sending: l2 txs awaiting l2 confirmation, ordered by nonce
|
||||||
:: finding: sig+raw-tx hash reverse lookup for txs in sending map
|
:: finding: sig+raw-tx hash reverse lookup for txs in sending map
|
||||||
@ -68,6 +68,7 @@
|
|||||||
:: chain-id: mainnet, ropsten, local (https://chainid.network/)
|
:: chain-id: mainnet, ropsten, local (https://chainid.network/)
|
||||||
:: resend-time: time to resend a batch with higher gas prie
|
:: resend-time: time to resend a batch with higher gas prie
|
||||||
:: update-rate: frequency to update the roller's predicted state
|
:: update-rate: frequency to update the roller's predicted state
|
||||||
|
:: fallback-gas-price: default batch gas price
|
||||||
::
|
::
|
||||||
pk=@
|
pk=@
|
||||||
slice=@dr
|
slice=@dr
|
||||||
@ -79,15 +80,11 @@
|
|||||||
chain-id=@
|
chain-id=@
|
||||||
resend-time=@dr
|
resend-time=@dr
|
||||||
update-rate=@dr
|
update-rate=@dr
|
||||||
|
fallback-gas-price=@ud
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
+$ action
|
+$ action
|
||||||
$% :: submit: request to add a l2 tx to the pending queue
|
$% :: submit: request to add a l2 tx to the pending queue
|
||||||
::
|
|
||||||
:: the address needs to be added so pending txs show up
|
|
||||||
:: in the tx history, but because users can send the wrong
|
|
||||||
:: address, in +apply-tx:predicted-state, we replace the
|
|
||||||
:: given address, with the one used when the message was signed
|
|
||||||
::
|
::
|
||||||
[%submit force=? =address:naive sig=@ tx=part-tx]
|
[%submit force=? =address:naive sig=@ tx=part-tx]
|
||||||
:: cancel: cancels a pending transaction
|
:: cancel: cancels a pending transaction
|
||||||
@ -106,10 +103,12 @@
|
|||||||
:: assign: assign an allowance to a ship for submitting l2 txs
|
:: assign: assign an allowance to a ship for submitting l2 txs
|
||||||
::
|
::
|
||||||
[%assign =ship quota=(unit @ud)]
|
[%assign =ship quota=(unit @ud)]
|
||||||
|
:: refuel: bumps the next-gas-price of a sending tx
|
||||||
|
::
|
||||||
|
[%refuel nonce=@ address=(unit address:ethereum) gas=@ud]
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
+$ card card:agent:gall
|
+$ card card:agent:gall
|
||||||
::
|
|
||||||
++ lverb &
|
++ lverb &
|
||||||
--
|
--
|
||||||
:: Helpers
|
:: Helpers
|
||||||
@ -231,13 +230,14 @@
|
|||||||
::
|
::
|
||||||
++ on-init
|
++ on-init
|
||||||
^- (quip card _this)
|
^- (quip card _this)
|
||||||
=: frequency ~h1
|
=: frequency ~h1
|
||||||
quota 25
|
quota 25
|
||||||
slice ~d7
|
slice ~d7
|
||||||
resend-time ~m5
|
resend-time ~m5
|
||||||
update-rate ~m5
|
update-rate ~m5
|
||||||
contract naive:local-contracts:azimuth
|
contract naive:local-contracts:azimuth
|
||||||
chain-id chain-id:local-contracts:azimuth
|
chain-id chain-id:local-contracts:azimuth
|
||||||
|
fallback-gas-price 10.000.000.000
|
||||||
==
|
==
|
||||||
=^ card-1 next-batch (set-roller:timer frequency now.bowl)
|
=^ card-1 next-batch (set-roller:timer frequency now.bowl)
|
||||||
=^ card-2 next-slice (set-quota:timer slice now.bowl)
|
=^ card-2 next-slice (set-quota:timer slice now.bowl)
|
||||||
@ -281,7 +281,7 @@
|
|||||||
resend-time update-rate
|
resend-time update-rate
|
||||||
==
|
==
|
||||||
=? old-state ?=(%2 -.old-state)
|
=? old-state ?=(%2 -.old-state)
|
||||||
^- app-state
|
^- state-3
|
||||||
=, old-state
|
=, old-state
|
||||||
=| allowances=(map ship (unit @ud))
|
=| allowances=(map ship (unit @ud))
|
||||||
=/ next-slice=time (mul +((div now.bowl slice)) slice)
|
=/ next-slice=time (mul +((div now.bowl slice)) slice)
|
||||||
@ -293,10 +293,22 @@
|
|||||||
frequency endpoint contract chain-id
|
frequency endpoint contract chain-id
|
||||||
resend-time update-rate
|
resend-time update-rate
|
||||||
==
|
==
|
||||||
?> ?=(%3 -.old-state)
|
=? old-state ?=(%3 -.old-state)
|
||||||
|
^- app-state
|
||||||
|
=, old-state
|
||||||
|
=/ fallback-gas-price=@ud 10.000.000.000
|
||||||
|
:* %4
|
||||||
|
pending sending finding history
|
||||||
|
ship-quota allowances
|
||||||
|
next-nonce next-batch next-slice
|
||||||
|
pre own spo pk slice quota derive
|
||||||
|
frequency endpoint contract chain-id
|
||||||
|
resend-time update-rate fallback-gas-price
|
||||||
|
==
|
||||||
|
?> ?=(%4 -.old-state)
|
||||||
[cards this(state old-state)]
|
[cards this(state old-state)]
|
||||||
::
|
::
|
||||||
++ app-states $%(state-0 state-1 state-2 app-state)
|
++ app-states $%(state-0 state-1 state-2 state-3 app-state)
|
||||||
++ state-0
|
++ state-0
|
||||||
$: %0
|
$: %0
|
||||||
pending=(list pend-tx)
|
pending=(list pend-tx)
|
||||||
@ -361,6 +373,31 @@
|
|||||||
resend-time=@dr
|
resend-time=@dr
|
||||||
update-rate=@dr
|
update-rate=@dr
|
||||||
==
|
==
|
||||||
|
++ state-3
|
||||||
|
$: %3
|
||||||
|
pending=(list pend-tx)
|
||||||
|
sending=(tree [l1-tx-pointer send-tx])
|
||||||
|
finding=(map keccak ?(%confirmed %failed [=time l1-tx-pointer]))
|
||||||
|
history=(map address:ethereum (tree hist-tx))
|
||||||
|
ship-quota=(map ship @ud)
|
||||||
|
allowances=(map ship (unit @ud))
|
||||||
|
next-nonce=(unit @ud)
|
||||||
|
next-batch=time
|
||||||
|
next-slice=time
|
||||||
|
pre=^state:naive
|
||||||
|
own=owners
|
||||||
|
spo=sponsors
|
||||||
|
pk=@
|
||||||
|
slice=@dr
|
||||||
|
quota=@ud
|
||||||
|
derive=?
|
||||||
|
frequency=@dr
|
||||||
|
endpoint=(unit @t)
|
||||||
|
contract=@ux
|
||||||
|
chain-id=@
|
||||||
|
resend-time=@dr
|
||||||
|
update-rate=@dr
|
||||||
|
==
|
||||||
--
|
--
|
||||||
::
|
::
|
||||||
++ on-poke
|
++ on-poke
|
||||||
@ -561,7 +598,7 @@
|
|||||||
=+ !<([=term =tang] q.cage.sign)
|
=+ !<([=term =tang] q.cage.sign)
|
||||||
%- (slog leaf+"{(trip dap.bowl)} failed" leaf+<term> tang)
|
%- (slog leaf+"{(trip dap.bowl)} failed" leaf+<term> tang)
|
||||||
=^ cards state
|
=^ cards state
|
||||||
(on-batch-result:do address nonce %.n^[%error 'thread failed'])
|
(on-batch-result:do address nonce %.n^[%crash 'thread failed'])
|
||||||
[cards this]
|
[cards this]
|
||||||
::
|
::
|
||||||
%thread-done
|
%thread-done
|
||||||
@ -801,6 +838,7 @@
|
|||||||
%commit ?>(local on-timer)
|
%commit ?>(local on-timer)
|
||||||
%config ?>(local (on-config +.action))
|
%config ?>(local (on-config +.action))
|
||||||
%assign ?>(local `state(allowances (~(put by allowances) +.action)))
|
%assign ?>(local `state(allowances (~(put by allowances) +.action)))
|
||||||
|
%refuel ?>(local (refuel-tx +.action))
|
||||||
%cancel (cancel-tx +.action)
|
%cancel (cancel-tx +.action)
|
||||||
::
|
::
|
||||||
%submit
|
%submit
|
||||||
@ -839,6 +877,7 @@
|
|||||||
^- (quip card _state)
|
^- (quip card _state)
|
||||||
?- -.config
|
?- -.config
|
||||||
%frequency [~ state(frequency frequency.config)]
|
%frequency [~ state(frequency frequency.config)]
|
||||||
|
%fallback [~ state(fallback-gas-price gas.config)]
|
||||||
%resend-time [~ state(resend-time time.config)]
|
%resend-time [~ state(resend-time time.config)]
|
||||||
%update-rate [~ state(update-rate rate.config)]
|
%update-rate [~ state(update-rate rate.config)]
|
||||||
%slice [~ state(slice slice.config)]
|
%slice [~ state(slice slice.config)]
|
||||||
@ -911,6 +950,21 @@
|
|||||||
u.time
|
u.time
|
||||||
[ship %cancelled keccak l2-tx]
|
[ship %cancelled keccak l2-tx]
|
||||||
==
|
==
|
||||||
|
:: +refuel-tx: bumps the gas price for a sending tx
|
||||||
|
::
|
||||||
|
++ refuel-tx
|
||||||
|
|= [nonce=@ud address=(unit address:ethereum) gas=@ud]
|
||||||
|
^- (quip card _state)
|
||||||
|
=/ batch=[address:ethereum @ud]
|
||||||
|
:_ nonce
|
||||||
|
?^(address u.address (get-address pk.state))
|
||||||
|
=. sending
|
||||||
|
?~ send-tx=(get:ors:dice sending batch)
|
||||||
|
sending
|
||||||
|
%^ put:ors:dice sending
|
||||||
|
batch
|
||||||
|
u.send-tx(next-gas-price gas)
|
||||||
|
`state
|
||||||
:: +take-tx: accept submitted l2 tx into the :pending list
|
:: +take-tx: accept submitted l2 tx into the :pending list
|
||||||
::
|
::
|
||||||
++ take-tx
|
++ take-tx
|
||||||
@ -961,7 +1015,7 @@
|
|||||||
:: when the thread that's sending the previous batch
|
:: when the thread that's sending the previous batch
|
||||||
:: has come back and confirms that it was sent to L1
|
:: has come back and confirms that it was sent to L1
|
||||||
::
|
::
|
||||||
?: out-of-sync
|
?: pending-batch
|
||||||
:: this would postpone sending the batch for a whole "frequency"
|
:: this would postpone sending the batch for a whole "frequency"
|
||||||
:: TODO: set up a timer to retry this in ~mX ?
|
:: TODO: set up a timer to retry this in ~mX ?
|
||||||
::
|
::
|
||||||
@ -1022,9 +1076,22 @@
|
|||||||
:: ship has been whitelisted ("?~ u.allow" means no quota restrictions)
|
:: ship has been whitelisted ("?~ u.allow" means no quota restrictions)
|
||||||
::
|
::
|
||||||
?~(u.allow | (gte u.quota u.u.allow))
|
?~(u.allow | (gte u.quota u.u.allow))
|
||||||
:: +out-of-sync: checks if the previous nonce has been sent
|
:: +pending-batch: checks if the previous nonce has been sent
|
||||||
::
|
::
|
||||||
++ out-of-sync
|
:: If %.y, the roller has been trying to send a batch for a whole frequency.
|
||||||
|
::
|
||||||
|
:: The cause of not sending the previous batch can happen because
|
||||||
|
:: of thread failure (see line 1251) or because the private key loaded onto
|
||||||
|
:: the roller was used for outside of the roller (i.e. for other than signing
|
||||||
|
:: L2 batches) right after the send-batch thread started.
|
||||||
|
::
|
||||||
|
:: After reaching this state, any subsequents attempts have failed (L: 1251)
|
||||||
|
:: (prior to updating the sending nonce if we hit the on-out-of-sync case)
|
||||||
|
:: which would possibly require a manual intervention (e.g. changing the
|
||||||
|
:: ethereum node URL, adding funds to the roller's address, manually bumping
|
||||||
|
:: the fall-back-gas-price or refueling the current batch with higher gas)
|
||||||
|
::
|
||||||
|
++ pending-batch
|
||||||
^- ?
|
^- ?
|
||||||
?~ newest-batch=(ram:ors:dice sending) |
|
?~ newest-batch=(ram:ors:dice sending) |
|
||||||
!=(sent.val.u.newest-batch &)
|
!=(sent.val.u.newest-batch &)
|
||||||
@ -1032,8 +1099,10 @@
|
|||||||
::
|
::
|
||||||
++ on-out-of-sync
|
++ on-out-of-sync
|
||||||
|= [nonce=@ud failed-nonce=@ud]
|
|= [nonce=@ud failed-nonce=@ud]
|
||||||
|
^- (quip card _state)
|
||||||
|
~& > %begin-on-out-of-sync
|
||||||
=/ =address:ethereum (get-address pk)
|
=/ =address:ethereum (get-address pk)
|
||||||
:: we only care about nonces >= than the one that failed
|
:: we only consider nonces >= than the one that failed
|
||||||
::
|
::
|
||||||
=/ failed-sending=(list [l1-tx-pointer send-tx])
|
=/ failed-sending=(list [l1-tx-pointer send-tx])
|
||||||
%- tap:ors:dice
|
%- tap:ors:dice
|
||||||
@ -1056,7 +1125,7 @@
|
|||||||
=* txs txs.q
|
=* txs txs.q
|
||||||
:: TODO: this shouldn't be needed
|
:: TODO: this shouldn't be needed
|
||||||
?: (lth nonce.p failed-nonce)
|
?: (lth nonce.p failed-nonce)
|
||||||
~& ["weird case" nonce+nonce.p]
|
~& >>> [%on-out-of-sync nonce+nonce.p failed+failed-nonce]
|
||||||
[new-nonce sending finding history]
|
[new-nonce sending finding history]
|
||||||
:+ +(new-nonce)
|
:+ +(new-nonce)
|
||||||
fix-sending
|
fix-sending
|
||||||
@ -1098,6 +1167,7 @@
|
|||||||
history sih
|
history sih
|
||||||
next-nonce `+(nonce)
|
next-nonce `+(nonce)
|
||||||
==
|
==
|
||||||
|
~& > %end-on-out-of-sync
|
||||||
[(send-roll address nonce) state]
|
[(send-roll address nonce) state]
|
||||||
:: +send-roll: start thread to submit roll from :sending to l1
|
:: +send-roll: start thread to submit roll from :sending to l1
|
||||||
::
|
::
|
||||||
@ -1125,6 +1195,7 @@
|
|||||||
chain-id
|
chain-id
|
||||||
pk
|
pk
|
||||||
nonce
|
nonce
|
||||||
|
fallback-gas-price
|
||||||
::
|
::
|
||||||
=< [next-gas-price txs]
|
=< [next-gas-price txs]
|
||||||
(got:ors:dice sending [address nonce])
|
(got:ors:dice sending [address nonce])
|
||||||
@ -1143,38 +1214,54 @@
|
|||||||
?. (has:ors:dice sending [address nonce])
|
?. (has:ors:dice sending [address nonce])
|
||||||
~? lverb [dap.bowl %done-sending [address nonce]]
|
~? lverb [dap.bowl %done-sending [address nonce]]
|
||||||
`state
|
`state
|
||||||
|
?: ?=([%| %not-sent %batch-parse-error] result)
|
||||||
|
:: if we tried to send a malformed batch, remove it from the queue
|
||||||
|
::
|
||||||
|
~& >>> [dap.bowl %removing-malformed-batch]
|
||||||
|
=^ * sending
|
||||||
|
(del:ors:dice sending [address nonce])
|
||||||
|
`state
|
||||||
=/ =send-tx (got:ors:dice sending [address nonce])
|
=/ =send-tx (got:ors:dice sending [address nonce])
|
||||||
=? sending ?=(%& -.result)
|
=? sending ?| ?=(%& -.result)
|
||||||
|
?=([%| %crash *] result)
|
||||||
|
==
|
||||||
%^ put:ors:dice sending
|
%^ put:ors:dice sending
|
||||||
[address nonce]
|
[address nonce]
|
||||||
:: update gas price for this tx in state
|
:: update gas price for this tx in state
|
||||||
:: and set it as sent to L1
|
|
||||||
::
|
::
|
||||||
send-tx(next-gas-price p.result, sent &)
|
?: ?=(%& -.result)
|
||||||
|
send-tx(next-gas-price p.result, sent &)
|
||||||
|
:: if the thread crashed, we don't know the gas used,
|
||||||
|
:: so we udpate it manually, same as the thread would do
|
||||||
|
::
|
||||||
|
%_ send-tx
|
||||||
|
next-gas-price
|
||||||
|
?: =(0 next-gas-price.send-tx)
|
||||||
|
fallback-gas-price
|
||||||
|
(add next-gas-price.send-tx 5.000.000.000)
|
||||||
|
==
|
||||||
:_ state
|
:_ state
|
||||||
?: ?| ?=(%& -.result)
|
?: ?& !sent.send-tx
|
||||||
:: a general error shouldn't innitiate
|
?=([%| %not-sent %behind-nonce] result)
|
||||||
:: the out-of-sync nonce thread
|
==
|
||||||
::
|
:: start out-of-sync flow if our L1 nonce is behind
|
||||||
?=([%| %error *] result)
|
:: and this transaction hasn't been sent out yet
|
||||||
:: this accounts for a resend with higher gas
|
|
||||||
:: for a previous nonce, so we shouldn't start
|
|
||||||
:: the out-of-sync nonce thread
|
|
||||||
::
|
|
||||||
?& sent.send-tx
|
|
||||||
?=([%| %not-sent *] result)
|
|
||||||
== ==
|
|
||||||
:_ ~
|
|
||||||
:: resend the l1 tx in five minutes
|
|
||||||
::
|
::
|
||||||
%+ wait:b:sys
|
~& > [dap.bowl %start-refresh-nonce-thread]
|
||||||
/resend/(scot %ux address)/(scot %ud nonce)
|
(get-nonce pk.state /refresh-nonce/(scot %ud nonce))
|
||||||
(add resend-time now.bowl)
|
:: resend the l1 tx in five minutes if:
|
||||||
:: TODO: this only accounts for the case where the nonce is out of sync,
|
|
||||||
:: reaching this because of lower funds needs to be addressed manually
|
|
||||||
::
|
::
|
||||||
?> ?=(%not-sent -.p.result)
|
:: - the thread succeeds and returns the next gas price
|
||||||
(get-nonce pk.state /refresh-nonce/(scot %ud nonce))
|
:: - the thread failed because:
|
||||||
|
:: - the roll's eth addres doesn't have enough funds to pay
|
||||||
|
:: - the thread crashes
|
||||||
|
:: - the sending L1 nonce is ahead of the expected one
|
||||||
|
:: - a general ethereum error
|
||||||
|
::
|
||||||
|
:_ ~
|
||||||
|
%+ wait:b:sys
|
||||||
|
/resend/(scot %ux address)/(scot %ud nonce)
|
||||||
|
(add resend-time now.bowl)
|
||||||
:: +on-naive-diff: process l2 tx confirmations
|
:: +on-naive-diff: process l2 tx confirmations
|
||||||
::
|
::
|
||||||
++ on-naive-diff
|
++ on-naive-diff
|
||||||
|
5
pkg/arvo/gen/roller/refuel.hoon
Normal file
5
pkg/arvo/gen/roller/refuel.hoon
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
:: Bumps the gas price for a sending transaction
|
||||||
|
::
|
||||||
|
:- %say
|
||||||
|
|= [* [nonce=@ gas=@ud address=(unit @ux) ~] ~]
|
||||||
|
[%roller-action %refuel nonce address gas]
|
@ -12,6 +12,7 @@
|
|||||||
::
|
::
|
||||||
+$ config
|
+$ config
|
||||||
$% [%frequency frequency=@dr]
|
$% [%frequency frequency=@dr]
|
||||||
|
[%fallback gas=@ud]
|
||||||
[%setkey pk=@]
|
[%setkey pk=@]
|
||||||
[%endpoint endpoint=@t =net]
|
[%endpoint endpoint=@t =net]
|
||||||
[%resend-time time=@dr]
|
[%resend-time time=@dr]
|
||||||
@ -98,6 +99,7 @@
|
|||||||
pk=@
|
pk=@
|
||||||
::
|
::
|
||||||
nonce=@ud
|
nonce=@ud
|
||||||
|
fallback-gas-price=@ud
|
||||||
next-gas-price=@ud
|
next-gas-price=@ud
|
||||||
txs=(list raw-tx:naive)
|
txs=(list raw-tx:naive)
|
||||||
==
|
==
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
=/ m (strand:strandio ,vase)
|
=/ m (strand:strandio ,vase)
|
||||||
|^
|
|^
|
||||||
^- form:m
|
^- form:m
|
||||||
:: =* not-sent (pure:m !>(%.n^next-gas-price))
|
|
||||||
::
|
::
|
||||||
=/ =address:ethereum (address-from-prv:key:ethereum pk)
|
=/ =address:ethereum (address-from-prv:key:ethereum pk)
|
||||||
;< expected-nonce=@ud bind:m
|
;< expected-nonce=@ud bind:m
|
||||||
@ -17,8 +16,18 @@
|
|||||||
:: if chain expects a different nonce, don't send this transaction
|
:: if chain expects a different nonce, don't send this transaction
|
||||||
::
|
::
|
||||||
?. =(nonce expected-nonce)
|
?. =(nonce expected-nonce)
|
||||||
~& [%unexpected-nonce nonce expected+expected-nonce]
|
~& >>> [%unexpected-nonce nonce expected+expected-nonce]
|
||||||
(pure:m !>(%.n^[%not-sent %unexpected-nonce]))
|
%- pure:m
|
||||||
|
!> ^- [%.n @tas @t]
|
||||||
|
:+ %.n
|
||||||
|
%not-sent
|
||||||
|
?: (lth expected-nonce nonce)
|
||||||
|
:: if ahead, it will use the same next-gas-price when resending
|
||||||
|
::
|
||||||
|
%ahead-nonce
|
||||||
|
:: if behind, start out-of-sync flow
|
||||||
|
::
|
||||||
|
%behind-nonce
|
||||||
:: if a gas-price of 0 was specified, fetch the recommended one
|
:: if a gas-price of 0 was specified, fetch the recommended one
|
||||||
::
|
::
|
||||||
;< use-gas-price=@ud bind:m
|
;< use-gas-price=@ud bind:m
|
||||||
@ -72,7 +81,8 @@
|
|||||||
:: log batch tx-hash to getTransactionReceipt(tx-hash)
|
:: log batch tx-hash to getTransactionReceipt(tx-hash)
|
||||||
::
|
::
|
||||||
~? &(?=(%result -.response) ?=(%s -.res.response))
|
~? &(?=(%result -.response) ?=(%s -.res.response))
|
||||||
^-([nonce=@ud batch-hash=@t] nonce^(so:dejs:format res.response))
|
^- [nonce=@ud batch-hash=@t gas=@ud]
|
||||||
|
nonce^(so:dejs:format res.response)^use-gas-price
|
||||||
%- pure:m
|
%- pure:m
|
||||||
!> ^- (each @ud [term @t])
|
!> ^- (each @ud [term @t])
|
||||||
:: TODO: capture if the tx fails (e.g. Runtime Error: revert)
|
:: TODO: capture if the tx fails (e.g. Runtime Error: revert)
|
||||||
@ -102,7 +112,7 @@
|
|||||||
take-maybe-response:strandio
|
take-maybe-response:strandio
|
||||||
=* fallback
|
=* fallback
|
||||||
~& >> %fallback-gas-price
|
~& >> %fallback-gas-price
|
||||||
(pure:m 10.000.000.000)
|
(pure:m fallback-gas-price)
|
||||||
?. ?& ?=([~ %finished *] rep)
|
?. ?& ?=([~ %finished *] rep)
|
||||||
?=(^ full-file.u.rep)
|
?=(^ full-file.u.rep)
|
||||||
==
|
==
|
||||||
|
Loading…
Reference in New Issue
Block a user