-
-
Save bdonlan/845271 to your computer and use it in GitHub Desktop.
Daemons: | |
* bitcoin-netd | |
Communicates with the bitcoin P2P network, and maintains a copy of the block chain and pending txns. | |
Has functions for querying the block and txn chain. | |
No private data whatsoever. | |
API: | |
* GetStatus() - Returns current latest block ID and generation number | |
* GetPendingTransactions() - Returns transactions not yet in a block [may have filter fields of some sort] | |
* GetBlock(hash, includeTxns) - Returns a specific block | |
* GetTransaction(hash) - Returns a specific transaction | |
* GetTransactionStatus(hash) - Returns txn state (pending, X confirmations, double-spent and rejected, invalid) | |
* PostTransaction(txnContents) - Posts a transaction to the bitcoin network. Returns an error on malformed or doublespent txns | |
* SearchTxns(filterTerms) - Searches for txns matching certain conditions eg: | |
AfterBlock=blockID:hash - errors if the blockID does not match the hash given (ie, when the block chain is changed after block collisions). Returns txns in blocks after that block | |
ToKey=keyHash - returns only txns redeemable with that key | |
* WatchTxns(toKey=keyHash) - returns a stream of new transactions sent to the specified key | |
* API calls for miners? | |
* bitcoin-walletd | |
Responsible for securely storing the wallet data. May interact directly with the user for permission | |
depending on configured policy. | |
API: | |
* GetBalance() | |
* ListKeys(includeHidden=boolean, createdSince=time) - returns public key:description pairs | |
* SetKeyDescription(pubKey=hash, desc=string) | |
* CreateKey(description=string) - returns public key only | |
* SetKeyHidden(pubKey=hash, hidden=boolean) | |
* GetTransactionLog(afterIndex=int, count=int) - Returns log entries from the wallet. | |
These entries correspond to both spends and receives; a single txn may produce multiple log entries. | |
Entries should reference the specific txnin or txnout they refer to. | |
* SendFunds(amount=int, dest=hash) - Send funds to the specified key. | |
May prompt the user for permission. May take a long time to do so. | |
Returns errors on insufficient funds or user refusal. | |
* ImportKey(privateKey=hash, reclaim=boolean) - Imports a key (and all its funds) into this wallet. | |
Invokes a search on the main netd to find such transactions. If reclaim=true, issues transactions | |
to move these funds onto fresh keys as well. | |
* streaming/event-based API? | |
Backup/restore is beyond the scope of this API and would use a private interface, possibly with direct | |
user intervention. |
The API should be available in 3 forms:
- as a static C library (C calling conventions only)
- as a shared (dynamic) library
- as a stand alone executable with a google protocol buffers socket api
The standalone version will require a bit more scaffolding to support authentication and encryption of the communications...it will also need to support multiple simultaneously connected clients.
In addition to the API calls outlined above, some mechanism for handling API versions should be implemented. Libraries often deal with versions utilizing filenames and filesystem links. To avoid the complexity that creates for the end user, I suggest we build a version handshake into the API. A call such as "init()" could return a struct listing the protocol versions supported. The client would choose the highest version that it also supports for use. All remaining API calls could use a version suffix (i.e. getBlock_v12() to indicate version 12 of the protocol). The library/executable should support at least 3 versions of the API to provide maximum compatibility. For static linking this is not really an issue, but for dynamic linking and the standalone executable, supporting multiple versions of the API is important and will help ensure that any given version of the libraries are widely compatible with various versions of clients.
WatchTxns may need to be able to observe transactions "fromKey" ...it's possible (though rare) that someone could use a wallet from multiple clients concurrently. Regardless of that being rare, making it work reliably is important. Startup of a wallet would first connect to a netd, then query for transactions in blocks that have been generated since it last ran (it would look for both to and from transactions for keys in the wallet), then start listening for new to/from transactions...question: how would a bad block be handled? if two blocks get generated at close to the same time, one is initially accepted, then later rejected, does this protocol need a way to tell the connected wallets to "unwind"?