WIP: random utxo selector

This commit is contained in:
timlucmiptev 2020-11-17 17:34:48 +02:00 committed by ixv
parent 0c163bbb5b
commit 7642fcdc23
6 changed files with 70 additions and 17 deletions

View File

@ -85,7 +85,8 @@ Error conditions:
## Needed Extensions ## Needed Extensions
- Invoice generator that asks for addresses on behalf of ships and tracks whether they've made payments. `wallet-hook` could probably be renamed to `wallet-manager` and extended for this purpose. - Invoice generator that asks for addresses on behalf of ships and tracks whether they've made payments. `wallet-hook` could probably be renamed to `wallet-manager` and extended for this purpose.
- `btc-provider` should push out address state in each block - `btc-provider` should push out address state in each block
- `btc-wallet-store` should watch the next ~20 addresses in each wallet account, so that it can detect BTC sent to the wallet if the wallet is also managed/generates addresses in an outside-Urbit program. - `btc-wallet-store` should watch the next ~20 addresses in each wallet account, so that it can detect BTC sent to the wallet if the wallet is also manageed/generates addresses in an outside-Urbit program.
- use Branch-and-Bound UTXO selection algo
## Possible Improvements/Changes ## Possible Improvements/Changes
- Do away with `btc-wallet-hook` altogether in its current form, and instead make `btc-provider` both a server (as it is now) and also a client. Pros: less between-agent data. Cons: complicates the otherwise simple provider module. PrA better solution might be to split just the connectivity parts of `btc-wallet-hook` into a local provider - Do away with `btc-wallet-hook` altogether in its current form, and instead make `btc-provider` both a server (as it is now) and also a client. Pros: less between-agent data. Cons: complicates the otherwise simple provider module. PrA better solution might be to split just the connectivity parts of `btc-wallet-hook` into a local provider

View File

@ -1,11 +1,7 @@
# btc-wallet-* Scratch Code # btc-wallet-* Scratch Code
## xpub ## xpub
Mnemonic xpub1 is from mnemonic from PRIVATE.scratch
```
absurd sick rose mask magnet know slide spell rent casual someone grant giant inhale toward
```
``` ```
=xpub1 'zpub6r8dKyWJ31XF6n69KKeEwLjVC5ruqAbiJ4QCqLsrV36Mvx9WEjUaiPNPGFLHNCCqgCdy6iZC8ZgHsm6a1AUTVBMVbKGemNcWFcwBGSjJKbD' =xpub1 'zpub6r8dKyWJ31XF6n69KKeEwLjVC5ruqAbiJ4QCqLsrV36Mvx9WEjUaiPNPGFLHNCCqgCdy6iZC8ZgHsm6a1AUTVBMVbKGemNcWFcwBGSjJKbD'
=xpub2 'xpub6D7yaZieZEeG617UcKXDhbsDeso6bmxSAiGWkvkASoiwcjaRtrH5HeNRnDT25s7zmxYzj6MtFe32dVqcf9YcBKKgn9THHjwn2uSjkvobK4e' =xpub2 'xpub6D7yaZieZEeG617UcKXDhbsDeso6bmxSAiGWkvkASoiwcjaRtrH5HeNRnDT25s7zmxYzj6MtFe32dVqcf9YcBKKgn9THHjwn2uSjkvobK4e'
@ -81,6 +77,8 @@ Uses `btc-wallet-hook`, with max-gap=3
## scrys ## scrys
``` ```
.^((list @t) %gx /=btc-wallet-store=/scanned/noun) .^((list @t) %gx /=btc-wallet-store=/scanned/noun)
.^(@ud %gx /=btc-wallet-store=/balance/[xpub]/noun)
``` ```
## Algos ## Algos

View File

@ -25,8 +25,8 @@
provider=(unit [host=ship connected=?]) provider=(unit [host=ship connected=?])
=btc-state =btc-state
def-wallet=(unit xpub) def-wallet=(unit xpub)
padr=pend-addr =pend-addr
ptxb=pend-txbu =pend-txbu
=piym =piym
=poym =poym
=piym-watch =piym-watch
@ -141,10 +141,13 @@
== ==
:: ::
%pay-address %pay-address
:: TODO: update poym
:: send tx request out for poym
:: TODO: ask wallet to generate tbxu for poym
`state `state
:: ::
%force-retry %force-retry
[(retry padr) state] [(retry pend-addr) state]
== ==
:: if status is %connected, retry all pending address lookups :: if status is %connected, retry all pending address lookups
:: ::
@ -156,7 +159,7 @@
?- -.s ?- -.s
%connected %connected
:: only retry if previously disconnected :: only retry if previously disconnected
:- ?:(connected.u.provider ~ (retry padr)) :- ?:(connected.u.provider ~ (retry pend-addr))
%= state %= state
provider `[host.u.provider %.y] provider `[host.u.provider %.y]
btc-state [blockcount.s fee.s now.bowl] btc-state [blockcount.s fee.s now.bowl]
@ -171,9 +174,9 @@
?. ?=(%& -.update) `state ?. ?=(%& -.update) `state
?- -.body.p.update ?- -.body.p.update
%address-info %address-info
=/ ureq (~(get by padr) req-id.p.update) =/ ureq (~(get by pend-addr) req-id.p.update)
?~ ureq `state ?~ ureq `state
:_ state(padr (~(del by padr) req-id.p.update)) :_ state(pend-addr (~(del by pend-addr) req-id.p.update))
:~ %+ poke-wallet-store / :~ %+ poke-wallet-store /
:* %address-info xpub.u.ureq chyg.u.ureq idx.u.ureq :* %address-info xpub.u.ureq chyg.u.ureq idx.u.ureq
utxos.body.p.update used.body.p.update blockcount.body.p.update utxos.body.p.update used.body.p.update blockcount.body.p.update
@ -187,7 +190,7 @@
?- -.req ?- -.req
%scan-address %scan-address
=/ ri=req-id:bp (mk-req-id (hash-xpub:bwsl +>.req)) =/ ri=req-id:bp (mk-req-id (hash-xpub:bwsl +>.req))
:_ state(padr (~(put by padr) ri req)) :_ state(pend-addr (~(put by pend-addr) ri req))
?~ provider ~ ?~ provider ~
?: provider-connected ?: provider-connected
~[(get-address-info ri host.u.provider a.req)] ~[(get-address-info ri host.u.provider a.req)]
@ -214,12 +217,13 @@
state(piym (~(add ja piym) fam [address.upd payer value])) state(piym (~(add ja piym) fam [address.upd payer value]))
:: ::
%scan-done %scan-done
:: TODO: update def-wallet if none set ?~ def-wallet
`state(def-wallet `xpub.upd)
`state `state
== ==
:: ::
++ retry ++ retry
|= p=pend-addr |= p=^pend-addr
^- (list card) ^- (list card)
?~ provider ~|("provider not set" !!) ?~ provider ~|("provider not set" !!)
%+ turn ~(tap by p) %+ turn ~(tap by p)

View File

@ -7,6 +7,10 @@
:: - /requests: to request data about addresses :: - /requests: to request data about addresses
:: - /updates: new data about one of our addresses :: - /updates: new data about one of our addresses
:: ::
:: Scrys
:: x/scanned: (list xpub) of all scanned wallets
:: x/balance/xpub: balance (in sats) of wallet
::
/- *btc-wallet-store /- *btc-wallet-store
/+ dbug, default-agent, *btc-wallet-store, btc, bip32 /+ dbug, default-agent, *btc-wallet-store, btc, bip32
|% |%
@ -85,6 +89,9 @@
?+ pax (on-peek:def pax) ?+ pax (on-peek:def pax)
[%x %scanned ~] [%x %scanned ~]
``noun+!>(scanned-wallets) ``noun+!>(scanned-wallets)
::
[%x %balance @ ~]
``noun+!>((balance:hc (xpub:btc +>-.pax)))
== ==
++ on-leave on-leave:def ++ on-leave on-leave:def
++ on-agent on-agent:def ++ on-agent on-agent:def
@ -154,7 +161,8 @@
[(sy (gulf 0 endpoint)) endpoint %.n] [(sy (gulf 0 endpoint)) endpoint %.n]
:- (weld (req-scan ~[/requests] b xpub %0) (req-scan ~[/requests] b xpub %1)) :- (weld (req-scan ~[/requests] b xpub %0) (req-scan ~[/requests] b xpub %1))
state(scans (insert-batches xpub b b)) state(scans (insert-batches xpub b b))
:: if the batch is done but the wallet isn't done scanning, returns new address requests and updated batch :: if the batch is done but the wallet isn't done scanning,
:: returns new address requests and updated batch
:: ::
++ bump-batch ++ bump-batch
|= [=xpub =chyg] |= [=xpub =chyg]
@ -236,4 +244,43 @@
|= [=xpub:btc w=walt] |= [=xpub:btc w=walt]
^- (unit xpub:btc) ^- (unit xpub:btc)
?: scanned.w `xpub ~ ?: scanned.w `xpub ~
::
++ balance
|= =xpub:btc
^- sats:btc
=/ w (~(get by walts) xpub)
?~ w ~|("btc-wallet-store: non-existent xpub" !!)
=/ values=(list sats:btc)
%+ turn ~(val by wach.u.w)
|= =addi ^- sats:btc
%+ roll
%+ turn ~(tap by utxos.addi)
|=(=utxo:btc value.utxo)
add
(roll values add)
:: Uses naive random selection. Should switch to branch-and-bound later
::
++ select-utxos
|= [target=sats w=walt]
^- (unit (list input))
=/ is=(list input)
%- zing
%+ turn ~(val by wach.w)
|= =addi
%+ turn ~(tap in utxos.addi)
|=(=utxo:btc [utxo chyg.addi idx.addi])
(single-random-draw target is)
::
++ single-random-draw
|= [target=sats is=(list input)]
^- (unit (list input))
=| [selected=(list input) total=sats:btc]
=/ rng ~(. og eny.bowl)
|- ?~ is ~
=^ n rng (rads:rng (lent is))
=/ i (snag n ((list input) is))
=/ new-total (add total value.utxo.i)
?: (gth new-total target)
`[i selected]
$(is t.is, total new-total, selected [i selected])
-- --

View File

@ -39,6 +39,9 @@
max-gap=@ud max-gap=@ud
confs=@ud confs=@ud
== ==
:: input: utxo for a transaction
::
+$ input [=utxo =chyg =idx]
:: todo: Set of indices; empty it out until none are left--means scanning of that batch is done :: todo: Set of indices; empty it out until none are left--means scanning of that batch is done
:: start: index this batch started scanning from :: start: index this batch started scanning from
:: ::