shrub/ARCH.md

96 lines
5.2 KiB
Markdown
Raw Normal View History

2020-11-10 15:49:03 +03:00
# Urbit Bitcoin Architecture
## Intro
This architecture is, by Urbit standards, awkward. The awkwardness arises mainly from the asymmetry of full nodes: only a few nodes are providers/full nodes, and they have to keep remote clients updated as to the state of the blockchain. The system also requires providers to run a node side-by-side with their Urbit, although this can mostly be abstracted away as HTTP calls out.
2020-11-11 11:00:32 +03:00
My goal in designing this was to isolate the architecture's awkwardness as much as possible to specific chokepoints, and to keep the non-provider portions as clean state machine primitives.
2020-11-10 15:49:03 +03:00
2020-11-13 13:23:16 +03:00
## System Components
### Outside Dependencies (for `btc-provider`)
These dependencies only apply to a provider running a full node with the `btc-provider` agent.
- Fully sync'd Bitcoin full node with running RPC. Be sure to have settings:
```
server=1
rpcallowip=127.0.0.1
rpcport=8332
```
- Fully sync'd ElectRS
- Custom HTTP API proxy. This is what `btc-provider` calls. It is necessary because ElectRS does not accept HTTP calls, and its API endpoints chain several RPC calls into one for convenience. It also abstracts out the multiple Bitcoin/ElectRS RPCs.
### Gall Agents
2020-11-10 15:49:03 +03:00
- `btc-wallet-store`: holds wallets and watches their addresses
* tracks whether a wallet has been scanned
* generates receiving addresses and change addresses
2020-11-11 11:00:32 +03:00
* can take address state input from any agent on its own ship
2020-11-10 15:49:03 +03:00
- `btc-wallet-hook`: requests BTC state from provider and forwards it
* subscribes to wallet-store for any address requests.
* pokes wallet-store with new address info
- `btc-provider`:
- helper BTC libraries for address and transaction generation.
## btc-wallet-store
2020-11-11 11:00:32 +03:00
Intentionally very limited in function. It's a primitive for tracking wallet state, including available addresses an existing/watched addresses.
2020-11-10 15:49:03 +03:00
2020-11-11 11:00:32 +03:00
Addresses are put in a watchlist if they have UTXOs *or* have been previously used. "Used" means either existing in transactions already, or having been generated by the store's `gen-address` gate, which generates and watches a new address, and increments the next "free" address.
2020-11-10 15:49:03 +03:00
2020-11-11 11:00:32 +03:00
You add a wallet to the store by adding that wallet's xpub. The store scans that xpub's change and non-change addresses in batches, by sending the address batches to its subscribers and taking pokes back with info for each address. The scan is done when store sees `max-gap` consecutive unused addresses.
Any source on the ship can poke the store with address info. This allows the possibility of creating import programs for pre-existing wallet data, or large amounts of wallet data. Currently, the only program that interacts with it is `btc-wallet-hook`.
Incoming data:
2020-11-11 11:00:32 +03:00
- requested address info
- unsolicited address updates (checked against watch list)
- requests to generate and watch new addresses
Outgoing data:
2020-11-11 12:41:13 +03:00
- requests for address info on unscanned address batches (sends to each new subscriber on /requests)
2020-11-11 11:00:32 +03:00
- newly generated/watched addresses
2020-11-10 15:49:03 +03:00
## btc-wallet-hook
2020-11-11 11:00:32 +03:00
I don't like the name "hook" here, but can't think of anything better atm. It's closer to a non-wallet-state manager on top of the wallet-store; potentially just one of many.
2020-11-11 12:41:13 +03:00
Incoming data:
- responses from `btc-provider`
- connectivity status from `btc-provider`
- address lookup requests from `btc-wallet-store`
2020-11-11 15:30:22 +03:00
- newly generated/watched addresses from `btc-wallet-store`
2020-11-10 15:49:03 +03:00
Outgoing data:
2020-11-11 12:41:13 +03:00
- pokes `btc-wallet-store` with address updates
- pokes `btc-wallet-store` with address generation requests
- pokes `btc-provider` with address lookup requests
Error conditions:
2020-11-11 11:00:32 +03:00
Disconnected provider: when it receives a message that this is the case, it stops sending outgoing address info requests until the provider says it's back up. Once we receive a connected message, all pending requests are retried.
## btc-provider
2020-11-11 11:00:32 +03:00
Layers on top of both BTC and ElectRS *TODO explain why the latter*
Incoming data:
2020-11-11 11:00:32 +03:00
Outgoing data:
Error conditions:
2020-11-11 11:00:32 +03:00
## Resource Usage
### Provider
- machine: requires hard drive and processing to run a BTC full node and ElectRS indexer.
- network: sends out *all* addresses in each new block to *all* clients
### Wallet
- machine: processes all addresses for each block to see whether they are being watched.
- network: receives all addresses for each block
2020-11-10 15:49:03 +03:00
## 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.
2020-11-11 11:00:32 +03:00
- `btc-provider` should push out address state in each block
2020-11-17 18:34:48 +03:00
- `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
2020-11-10 15:49:03 +03:00
2020-11-11 11:00:32 +03:00
## Possible Improvements/Changes
2020-11-11 12:41:13 +03:00
- 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
2020-11-10 15:49:03 +03:00
- Multiple Providers
2020-11-11 11:00:32 +03:00
- Gossip network for both pulling and pushing address updates to lower network usage on the providers.
2020-11-10 15:49:03 +03:00