diff --git a/app/btc-wallet-hook.hoon b/app/btc-wallet-hook.hoon index 36c059273..344d00d72 100644 --- a/app/btc-wallet-hook.hoon +++ b/app/btc-wallet-hook.hoon @@ -199,24 +199,26 @@ :: add to wallet-store history :: send message to peer `state + :: :: - check that src.bowl isn't past piym-limit in pend-piym :: - check that payment is in piym - :: - add to pend-piym + :: - add payment to pend-piym :: - send tx-info to provider (poke) :: %expect-payment - ~|("Too many %expect-payment sent, or payer+value not found in incoming payments") - =+ num-pend (~(gut by num.pend-piym) payer.act 0) + ~| "Too many %expect-payment sent, or payer+value not found in incoming payments" + =+ num-pend=(~(gut by num.pend-piym) payer.act 0) ?> (gte piym-limit num-pend) =+ pay=(~(get by ps.piym) payer.act) ?~ pay !! ?> ?& =(payer.u.pay payer.act) =(value.u.pay value.act) == - :- ~[(get-tx-info txid.act)] + :- ?~ provider ~ + ~[(get-tx-info host.u.provider txid.act)] %= state - ps.pend-piym (~(put by ps.pend-piym) txid u.pay) - num.pend-piym +(num-pend) + ps.pend-piym (~(put by ps.pend-piym) txid.act [u.pay vout-n.act]) + num.pend-piym (~(put by num.pend-piym) payer.act +(num-pend)) == :: %clear-poym @@ -226,6 +228,7 @@ [(retry-reqs block.btc-state) state] == :: +handle-provider-status: handle connectivity updates from provider +:: - retry pend-piym on any %connected event, since we're checking mempool :: - if status is %connected, retry all pending address lookups :: - only retry all if previously disconnected :: - if block is updated, retry all address reqs @@ -237,16 +240,20 @@ ?. =(host.u.provider src.bowl) `state ?- -.s %connected - :: TODO retry pend-piym every time here. :_ %= state provider `[host.u.provider %.y] btc-state [block.s fee.s now.bowl] == ?: ?!(connected.u.provider) - (weld (retry-reqs block.s) retry-txbu) - ?. (lth block.btc-state block.s) ~ + %- zing + :~ (retry-reqs block.s) + retry-txbu + retry-pend-piym + == + ?. (lth block.btc-state block.s) + retry-pend-piym ~& > "got new block, retrying {<(lent (retry-reqs block.s))>} reqs " - (retry-reqs block.s) + (weld retry-pend-piym (retry-reqs block.s)) :: %disconnected `state(provider `[host.u.provider %.n]) @@ -261,6 +268,7 @@ =/ req=(unit request:bws) (~(get by reqs) req-id.p.upd) ?~ req `state + ?> ?=([%address-info *] u.req) :_ state(reqs (~(del by reqs) req-id.p.upd)) :~ %- poke-wallet-store :* %address-info xpub.u.req chyg.u.req idx.u.req @@ -269,11 +277,17 @@ == :: %tx-info - :: TODO - :: - pass to store always - :: - check whether txid in pend-piym - :: if yes, add to wallet-store history and delete from pend-piym - `state + :: - forward tx to wallet-store + :: - delete txid from pend-piym and decrement num.pend-piym + :: - check whether payment in pend-piym matches this tx's output values + :: if yes add to wallet-store-history + =/ ti=info:tx +.body.p.upd + =/ mh=(unit [=xpub =hest:bws]) + (mk-hest ti (~(get by ps.pend-piym) txid.ti)) + :_ state(pend-piym (del-txid txid.ti)) + %+ weld ~[(poke-wallet-store [%tx-info ti])] + ?~ mh ~ + ~[(poke-wallet-store [%add-history-entry xpub.u.mh hest.u.mh])] :: %raw-tx ?~ poym `state @@ -286,16 +300,24 @@ ++ handle-wallet-store-request |= req=request:bws ^- (quip card _state) + ?~ provider `state + =/ should-send=? + ?& provider-connected + (lth last-block.req block.btc-state) + == ?- -.req %address-info =+ ri=(gen-req-id:bp eny.bowl) :_ state(reqs (~(put by reqs) ri req)) - ?~ provider ~ - ?: ?& provider-connected - (lth last-block.req block.btc-state) - == + ?: should-send ~[(get-address-info ri host.u.provider a.req)] ~ + :: + %tx-info + :: TODO: push the request out + :: put it in reqs + :: check whether last-block has passed + `state == :: ++ handle-wallet-store-update @@ -340,7 +362,43 @@ :~ %+ poke-wallet-hook payer [%ret-pay-address address.newp payer value] == +:: +del-txid: delete txid from pend-piym :: +++ del-txid + |= =txid + ^- ^pend-piym + =+ p=(~(get by ps.pend-piym) txid) + =. ps.pend-piym (~(del by ps.pend-piym) txid) + ?~ p pend-piym + =* payer payer.pay.u.p + =+ n=(~(get by num.pend-piym) payer) + ?~ n pend-piym + ?: =(0 u.n) pend-piym + pend-piym(num (~(put by num.pend-piym) payer (dec u.n))) +:: +mk-hest: make a hest to add to wallet-store's history +:: - one of the outputs' value must match the payment from pend-piym +:: +++ mk-hest + |= [=info:tx p=(unit [pay=payment vout-n=@ud])] + ^- (unit [=xpub =hest:bws]) + ?~ p ~ + ?. ?& (gth (lent outputs.info) vout-n.u.p) + =(value.pay.u.p value:(snag vout-n.u.p outputs.info)) + == + ~ + :- ~ + :- xpub.pay.u.p + :* txid.info + confs.info + recvd.info + %+ turn inputs.info + |=(i=val:tx [i `payer.pay.u.p]) + %+ turn outputs.info + |= o=val:tx + ?: =(pos.o vout-n.u.p) + [o `our.bowl] + [o `payer.pay.u.p] + == :: +fam: planet parent if s is a moon :: ++ fam @@ -376,7 +434,13 @@ %+ murn ~(tap by reqs) |= [ri=req-id:bp req=request:bws] ?: (gte last-block.req latest-block) ~ - `(get-address-info ri host.u.provider a.req) + ?- -.req + %address-info + `(get-address-info ri host.u.provider a.req) + :: + %tx-info + `(get-tx-info host.u.provider txid.req) + == :: ++ retry-txbu ^- (list card) @@ -385,6 +449,13 @@ %+ turn txis.u.poym |= =txi:bws (get-raw-tx host.u.provider txid.utxo.txi) +:: +retry-pend-piym: check whether txids in pend-piym are in mempool +:: +++ retry-pend-piym + ^- (list card) + ?~ provider ~|("provider not set" !!) + %+ turn ~(tap in ~(key by ps.pend-piym)) + |=(=txid (get-tx-info host.u.provider txid)) :: ++ get-address-info |= [ri=req-id:bp host=ship a=address] diff --git a/app/btc-wallet-store.hoon b/app/btc-wallet-store.hoon index 7355aecf7..41a8cba30 100644 --- a/app/btc-wallet-store.hoon +++ b/app/btc-wallet-store.hoon @@ -49,7 +49,7 @@ ++ on-init ^- (quip card _this) ~& > '%btc-wallet-store initialized' - `this(state [%0 *(map xpub:btc walt) *^scans max-gap:defaults 0]) + `this(state [%0 *(map xpub:btc walt) *^scans max-gap:defaults 0 *^history]) ++ on-save ^- vase !>(state) @@ -332,7 +332,7 @@ :: ++ send-request |= [pax=(list path) req=request] ^- card - ~& >> "send-request: {}, {}" +:: ~& >> "send-request: {}, {}" :* %give %fact pax %btc-wallet-store-request !>(req) == diff --git a/lib/btc-provider.hoon b/lib/btc-provider.hoon index 6480f8f29..b4c5ff503 100644 --- a/lib/btc-provider.hoon +++ b/lib/btc-provider.hoon @@ -109,8 +109,8 @@ ++ tx-vals %- ot:dejs:format :~ [%txid (cu:dejs:format to-hash256 so:dejs:format)] - [%recvd (cu:dejs:format from-epoch ni:dejs:format)] [%confs ni:dejs:format] + [%recvd (cu:dejs:format from-epoch ni:dejs:format)] [%inputs (ar:dejs:format tx-val)] [%outputs (ar:dejs:format tx-val)] == diff --git a/sur/btc-provider.hoon b/sur/btc-provider.hoon index 477a4cd1b..c02337019 100644 --- a/sur/btc-provider.hoon +++ b/sur/btc-provider.hoon @@ -16,7 +16,7 @@ +$ result [=req-id body=result-body] +$ result-body $% [%address-info utxos=(set utxo) used=? block=@ud] - [%tx-info =txid recvd=(unit @da) confs=@ud inputs=(list val:tx) outputs=(list val:tx)] + [%tx-info =info:tx] [%raw-tx =txid =rawtx] == +$ error @@ -45,7 +45,7 @@ :: +$ response $% [%get-address-info utxos=(set utxo) used=? block=@ud] - [%get-tx-vals =txid recvd=(unit @da) confs=@ud inputs=(list val:tx) outputs=(list val:tx)] + [%get-tx-vals =info:tx] [%get-raw-tx =txid =rawtx] [%get-block-count block=@ud] [%get-block-and-fee block=@ud fee=sats] diff --git a/sur/btc-wallet-hook.hoon b/sur/btc-wallet-hook.hoon index 3911b9c90..259f889e2 100644 --- a/sur/btc-wallet-hook.hoon +++ b/sur/btc-wallet-hook.hoon @@ -18,7 +18,10 @@ :: +$ payment [=xpub =address payer=ship value=sats] +$ piym [ps=(map ship payment) num-fam=(map ship @ud)] -+$ pend-piym [ps=(map txid payment) num=(map ship @ud)] ++$ pend-piym + $: ps=(map txid [pay=payment vout-n=@ud]) + num=(map ship @ud) + == +$ poym (unit txbu:bws) :: req-pay-address: request a payment address from another ship :: - target of action is local ship @@ -26,6 +29,7 @@ :: ret-pay-address: give an address to a payer who requested it :: broadcast-tx: broadcast a signed-psbt, must be current poym :: expect-payment: tell another ship that we're paying a previously requested address +:: - vout-n is the index of the output that has value :: +$ action $% [%set-provider provider=ship] @@ -34,7 +38,7 @@ [%gen-pay-address value=sats] [%ret-pay-address =address payer=ship value=sats] [%broadcast-tx signed-psbt=cord] - [%expect-payment =txid payer=ship value=sats] + [%expect-payment =txid payer=ship value=sats vout-n=@ud] [%clear-poym ~] [%force-retry ~] == diff --git a/sur/btc-wallet-store.hoon b/sur/btc-wallet-store.hoon index 4b8a874af..e7c6b9b04 100644 --- a/sur/btc-wallet-store.hoon +++ b/sur/btc-wallet-store.hoon @@ -66,9 +66,10 @@ :: +$ hest $: =txid - recvd=@da - inputs=(list [=utxo s=(unit ship)]) - outputs=(list [=output s=(unit ship)]) + confs=@ud + recvd=(unit @da) + inputs=(list [=val:tx s=(unit ship)]) + outputs=(list [=val:tx s=(unit ship)]) == +$ history (map xpub (map txid hest)) :: state/watch variables: @@ -89,6 +90,7 @@ +$ action $% [%add-wallet =xpub scan-to=(unit scon) max-gap=(unit @ud) confs=(unit @ud)] [%address-info =xpub =chyg =idx utxos=(set utxo) used=? block=@ud] + [%tx-info =info:tx] [%generate-address =xpub =chyg =peta] [%generate-txbu =xpub payee=(unit ship) feyb=sats txos=(list txo)] [%add-history-entry =xpub =hest] diff --git a/sur/btc.hoon b/sur/btc.hoon index 2a1d5d7f1..138f586f4 100644 --- a/sur/btc.hoon +++ b/sur/btc.hoon @@ -29,6 +29,13 @@ =address value=sats == + +$ info + $: =txid + confs=@ud + recvd=(unit @da) + inputs=(list val) + outputs=(list val) + == +$ unsigned $: version=@ locktime=@