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

View File

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

View File

@ -7,6 +7,10 @@
:: - /requests: to request data about 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
/+ dbug, default-agent, *btc-wallet-store, btc, bip32
|%
@ -85,6 +89,9 @@
?+ pax (on-peek:def pax)
[%x %scanned ~]
``noun+!>(scanned-wallets)
::
[%x %balance @ ~]
``noun+!>((balance:hc (xpub:btc +>-.pax)))
==
++ on-leave on-leave:def
++ on-agent on-agent:def
@ -154,7 +161,8 @@
[(sy (gulf 0 endpoint)) endpoint %.n]
:- (weld (req-scan ~[/requests] b xpub %0) (req-scan ~[/requests] b xpub %1))
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
|= [=xpub =chyg]
@ -236,4 +244,43 @@
|= [=xpub:btc w=walt]
^- (unit xpub:btc)
?: 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
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
:: start: index this batch started scanning from
::