Storage client doesn't know which passes the storage server considers invalid/unusable
When the storage server receives passes with a request that requires them, it validates each and then counts the valid ones. If there are not enough valid passes for the operation, it rejects it with an exception giving the number of valid passes found and the number required.
From this information, the client can't necessarily make progress. If there were some invalid passes and some valid passes, the client won't know which are which. If it wants to try the operation again with new passes, it has no simple path to replacing the invalid ones with new passes to try.
This makes it difficult for the client to recover from a double-spend situation. Such a situation can arise in any of several ways. The client may have just recovered from a backup in which the checkpoint wasn't perfectly up to date. In this case, the first small-number of passes the client tries to spend will have already been spent prior to the recovery. It needs to be able to advance past these. If this were the only case, it could just try dropping the first and adding a new one from the database to the end of the list to replace it. Eventually it would manage to skip past all the already-spent passes. However, the existence of other cases complicates this.
The client may attempt an operation - for example, a lease renewal - which succeeds. However, the network connection may be interrupted before the success response is received. The client will not know if the passes have been spent in this case or not. If it assumes they were spent and discards them, it may be throwing away unspent passes and wasting client resources. If it assumes they were not spent and keeps them, they may later result in a double-spend error from the server. If operations proceeded serially then this would also not present a problem since all potentially already-spent passes would be at the front of the database and could be skipped over as above. However, if two operations are started in parallel and one of them fails, this may produce an already-spent passes island in a sea of not-spent passes. Such passes are not so easily skipped over.
Therefore, the storage server should tell the client exactly which passes it is rejecting and it should categorize the rejection for book-keeping and reporting purposes on the client.
This will provide a first step towards #108 (closed)