A bunch of little errors, including a fix to the balancehash computation
[Trubanc.git] / todo.txt
blobfa535c6c8e8626aef5e7e0062dbc5d58377d880d
1 If we can't redeem a coupon spend, or cancel a regular spend from the outbox,
2 there should be some way to remove that item from the outbox. It's a bug
3 that this happens at all, but there needs to be a way to clean up.
5 ======================================================================
7 If inbox has bank fees, the balance could go negative. Don't allow processinbox.
8 This happens if the user rejects the initial spend of usage tokens.
10 ======================================================================
12 Test for existence of cURL, bcmath, and OpenSSL libraries.
14 ======================================================================
16 safeidx($array, $idx) doesn't warn if $idx is not in array. Sprinkle liberally.
17 Or just put @ before suspect accessors.
19 Ship with clientdb and serverdb directories inside of dbs.
21 Backup mechanism. Real-time logging and replication.
23 Client command to change passphrase. Server request to change name
24 associated with account.
26 The current, not original, asset issuer should be allowed to change the storage fee.
28 ======================================================================
30 $t->BATCHFEES command, to iterate over accounts, collecting storage fees.
32   (<id>,batchfees,<assetid>,<start>,<timelimit>,<frequency>)
34 Returns:
36   (<bankid>,@batchfees,<amount>,<start2>,
37     (<id>,batchfees,<assetid>,<start>,<timelimit>,<frequency>))
39 <assetid>     asset for which to collect fees.
40 <start>       user ID at which to start processing
41 <timelimit>   maximum seconds to process. Prevents web form timeout.
42 <frequency>   how often the issuer runs this process. Balances newer than
43               (now - <frequency>) won't be processed.
44 <start2>      user ID at which to continue processing
46 This exposes that fsdb->contents() doesn't scale. If there are
47 millions of accounts, the /account directory has millions of
48 first-level subdirs. That's a lot of RAM to list. Need to split up
49 abcdefgh... into ab/cd/efgh.... That turns 2**20 accounts into 2**16
50 dirs of 2**4 accounts each. Use new fsdb->iterator() function to
51 return an iterator:
52   iterator->next() - returns next item
53   iterator->init(start) - next next() will return start
54   iterator->peek() - returns next item, but doesn't advance
56 Fees get credited to the issuer's $t->STORAGEFEE accumulators. We need
57 a $t->BANKFEE accumulator for each account that accumulates the
58 charges, per assetid. These look like part of the inbox for the
59 getinbox and processinbox operations, but are separate so we don't
60 need to find them while batching fees. They have non-integer amounts,
61 which will require some tweaking to work properly.
63 The server must remember, for each issuer and asset, when the last
64 batchfees was run, so that we don't double-charge. This is a bigger
65 problem for inbox items. Since they can sit there for a long time, and
66 accepting one charges the recipient, we somehow have to know that
67 batchfees has charged (the sender) for one of them. This needs to be a
68 special negative bank spend, that debits the recipient if he accepts,
69 or the spender if rejected.
71 ======================================================================
73 Sync command in user interface. Click link. Sync balances, outbox, and inbox with server.
74   It would be better to do this automagically when something appears
75   wrong, and I'm doing it in some places, but the user needs to be
76   able to do it explicitly.
78 Real sync command that doesn't just overwrite the client, but notifies
79 the server when the client has a more recent message for a balance or
80 outbox item.  Tools for the bank to rectify outstanding notifications
82 Accept only the [url,number] form for coupons. Give a reasonable error
83 message if the user misses copying part of the coupon (e.g. the
84 opening or closing square bracket).
86 Transaction fees. Fixed as amount and asset. Or charge rent on space,
87 e.g. 10% / year, in usage tokens, of your total file count.
89 ======================================================================
91 Enable Bank to take a cut of storage fees. Configured in settings.php. 
93   // The cut of storage fees taken by the bank, in percent. Default: 0.
94   // And the ID of the account to pay. Default: the bank itself.
95   $storagefeecut = 10;
96   $storagefeeid = "18864f9f1e8df66c15f76513df0fde9064ceeb2c";
98 ======================================================================
100 Lisp wrapper around the OpenSSL command line.
101   If this works, do a whole server in Lisp.
103 Currently, transaction fees go only to bank. Could give asset issuer a cut.
104 Currently, storage fees go only to asset issuer. Could give bank a cut.
105 Currently, transaction fees are paid by spender. Could charge recipient, instead or as well.
107 Time zone preference for client.
109 History features:
110     Additional notes
111     Sort
112     Filter
113     Export/Import
114     "Show raw history" link
115     Show source and target acct on transfer spends.
117 URLs for adding a contact and for filling the spend page with info for a sale.
119 Nicknames for asset types.
121 Show/Hide checkboxes on sub-account names. Move hidden sub-account
122 names to bottom of list, one line apiece.
124 If you paste an old inbox entry into somebody's inbox, it will look
125 real, and give them those assets when processed. Bank needs to protect
126 against inbox tampering in its file system by storing a message that
127 encodes the real inbox entries.
129 If the customer can prove he has a higher balance than the bank in an asset, add a balance-disagreement record to that balance entry. The customer's usable balance will be what the bank agrees with, and he can continue to make transactions, but the amount in disagreement will remain in disagreement until the bank officers and the asset issuer decide whether they're going to honor the customer's balance. If they do, they'll add a balance-disagreement-resolution to the user's inbox.
131 A way to transfer contacts between client DBs, likely as a big URL.
133 Encrypt message contents with recipients public key, so bank can't read them.
135 Allow adding non-registered IDs to contact list in web client.
137 Use titles on asset names in the UI to distinguish different assets with the same name. Need to print ID and owner. Probably need to mark certain assets as known in the "Assets" screen.
139 Optimize server traffic.
141 Stand-alone non-HTTP server:
142   http://www.van-steenbeek.net/?q=php_pcntl_fork
144 Canonicalize the bank URL at the bank. That way you don't get the spelling of the first user to use it in a client.
146 Email notification. Info must be encrypted in the server database. And it's obviously optional. User specifies message to send and options about transaction details, e.g. amount, asset, spender, bank url.
148 Wrap functions around code shared by do_spend, do_processinbox, and do_asset
150 Finish two-phase commit for spend and inboxhash.
152 To cancel a spend, do a negative spend of the same amount with a note of the outbox timestamp of the original spend. There are locking issues with removing the recipient's inbox entry. May have to do it with another inbox entry that cancels the first one. Then both will be quietly removed by the next getinbox.
154 A real transaction system for disk writes, like Patrick has done for Loom. The locking works, if all goes well in disk writes. But it doesn't if there's an unexpected error, e.g. the problems I had with creating subdirs in a SAFE-MODE environment. We get in an inconsistent state. This should be just a layer on top of fsdb.php.
156 -----
158 Remember the last successful spend or processinbox message and its result, and resend the result if the message is resent. This can heal responses that are lost in transit.
160 Credit the bank for usage tokens paid for files. Some of this may be already done, but that code needs reviewing.
162 -----
164 Encrypt the client<->server messages. SSL could do this, but why bother, when we can easily do it ourselves? Why pay for an SSL certificate and the SSL connection overhead, when you don't have to?
166   sent: (<id>,getsessionkey,<bankid>,<reqid>)
167   rcvd: (<bankid>,sessionkey,<id>,<pubkey encrypted: [<sessionid>,<sessionkey>]>)
169   sent: [<sessionid>,<sessionkey encrypted: message>]
170   rcvd: [<sessionid>,<sessionkey encrypted: response>]
171            or
172         [<sessionid>,unknown]
174   sent: [<sessionid>,
175          <sessionkey encrypted: (<id>,closesession,<bankid>,<sessionid>)>]
176   rcvd: [<sessionid>,
177          <sessionkey encrypted:
178            (<bankid>,@closesession,(<id>,closesession,<bankid>,<sessionid>))>]
180 Unfortunately, the PHP OpenSSL library doesn't give sufficient access to OpenSSL's encryption functions, so we'll have to rely on mcrypt:
182 http://us3.php.net/manual/en/function.mcrypt-module-open.php
184 http://www.ietf.org/rfc/rfc4344.txt recommends aes256-ctr.
186 Unfortunately, PHP's mcrypt library doesn't provide CTR. CBC or CFB will have to do. The openssl on my machine supports aes-256-cbc and aes-256-cfb, so either will do.
188 rfc4344 also recommends periodic rekeying. Can do that by closing the session and starting a new one. Client needs to keep track of the number of messages or number of bytes sent, per session, and have a rekey period.
190 -----
192 Bank Counterfeiting
194 As it is now, the bank can counterfeit assets. This will put the bank out of balance, but who's to know, unless they hire an auditing firm to audit the database? This means that issuers have to trust the banks they issue for, or they could end up with more liabilities than they promised. One way around this is to have the issuer approve every transaction. Actually, approve it twice, once when the spend happens, and again when the spend|accept or spend|reject happens.
196 The issuer would sign an approval of the new balance, or spend, without the customer <id>, just the <time#>. Otherwise, the issuer would know identities of all the holders of his currency, which many customers are not likely to want. Letting the bank have that information is bad enough, if what you really want is totally anonymous digital cash.
198 The bank would supply the issuer with:
200   (<bankid>,debit|request,<issuerid>,<time#>,<assetid>,<amount>).
201   (<bankid>,debit,<issuerid>,<time2#>,<assetid>,<amount2>).
202   (<bankid>,credit,<issuerid>,<time#>,<assetid>,<amount3>)
204 This means that we're spending from the previously approved <time2#> balance, and asking for approval of the spend and the new <time#> balance. <amount2> - <amount> = <amount3>, basically breaking up the <time2#> balance entry into a spend and the <time#> balance entry.
206 The issuer removes the <time2#> balance|approved item from his database, adds the <tim#> balance|approved and debit|approved entries, and sends back:
208   (<issuerid>,debit|approved,<bankid>,<time#>,<assetid>,<amount>).
209   (<issuerid>,balance|approved,<bankid>,<time#>,<assetid>,<amount3>)
211 Or, if the issuer doesn't find the <time2#> balance in his database:
213   (<issuerid>,debit|rejected,(<bankid>,debit|request,<issuerid>,<time#>,<assetid>,<amount>))
215 If the recipient accepts this spend, the bank sends to the issuer:
217   (<bankid>,debit|accepted,(<issuerid>,debit|approved,<bankid>,<time#>,<assetid>,<amount>)).
218   (<bankid>,debit,<issuerid>,<time4#>,<assetid>,<amount4>).
219   (<bankid>,credit,<issuerid>,<time3#>,<assetid>,<amount5>)
221 Here <amount> + <amount4> = <amount5>, joining the <time4#> balance with the <time#> debit approval to create the <time3#> balance.
223 The issuer removes the <time#> debit|approved item and the <time4#> balance|approved item from his database, adds the <time3#> balance|approved item, and sends back:
225   (<issuerid>,balance|approved,<bankid>,<time3#>,<assetid>,<amount5>)
227 Or, if the issuer doesn't find the <time#> debit|approved item or the <time4#> balance|approved item in his database:
229   (<issuerid>,credit|rejected,(<bankid>,credit|request,<issuerid>,<time3#>,<assetid>,<amount>))
231 If the recipient rejects the spend, and the spender acknowledges the rejection, the bank sends to the issuer:
233   (<bankid>,debit|rejected,(<issuerid>,debit|approved,<bankid>,<time#>,<assetid>,<amount>)).
234   (<bankid>,debit,<issuerid>,<time#>,<assetid>,<amount3>)
235   (<bankid>,credit,<issuerid>,<time5#>,<assetid>,<amount2>)
237 <amount> + <amount3> = <amount2>.
239 The issuer removes the <time#> debit|approved item and the <time#> balance|approved item from his database, adds the <time5#> balance|approved item, and sends back:
241   (<issuerid>,@debit|rejected,(<bankid>,debit|rejected,(<issuerid>,debit|approved,<bankid>,<time#>,<assetid>,<amount>))).
242   (<issuerid>,balance|approved,<bankid>,<time5#>,<assetid>,<amount2>)
244 The bank sends the issuer's balance|approved items back to the customer with successful response to a spend or processinbox request:
246   (<bankid>,@balance,(<id>,balance,<bankid>,<time#>,<assetid>,<amount3>)).
247     (<bankid>,@balance|approved,(<issuerid>,balance|approved,<bankid>,<time#>,<assetid>,<amount3>))
249 Or maybe the customer doesn't need to care about that, leaving the issuer approval between the bank and the issuer. The customer's balances are guaranteed, but if the bank counterfeits, the currency will inflate, making his balances worth less than the backing commodity that the issuer promised.
251 Now we've tranformed the bank counterfeiting problem into an issuer reliability problem. We're depending on the issuer to approve balance changes. If he doesn't, the customer is stuck with a bunch of worthless assets. Many issuers won't be in the position to create a reliable server to approve all balance transformations. They'll have to trust that the bank won't counterfeit their assets.
253 If the issuer trusts the bank, his assets can have value beyond his disappearance. If he doesn't, then if his server disappears, none of his assets can ever be traded again. So I don't know if I'll ever implement this. We'll just have to trust banks not to counterfeit, encourage them to get audited by independent auditing firms, and let the market put out of business banks that aren't honest or don't get properly audited.
255 -----
257 Remove zero-balance files and credit a usage token. This requires a new message that captures all the files for, e.g., an account, so the customer can't claim a non-zero balance later on for the now missing file.
259 spend|cancel to take back a spend before the other guy has accepted or rejected it.
261 Support fees other than usage tokens.
263 Error codes on $this->failmsg()
265 $t->SPEND
266 ---------
268 Right now, spends to the bank are rejected right away.
270 Alternatives:
272 1) Accept spends to the bank right away, with no inbox or
273 outbox. Credit the bank's accounts.
275 2) Reject spends to the bank, but keep the proferred tokens. This might anger some, but possibly no more than losing tokens when another customer rejects your spend.
278 Checks and Certificates
279 -----------------------
281 Have to keep external spend receipt until expiration date. Check or certificate costs a usage token, which is refunded on expiration. Thank you, Patrick!