Previously the PeerGroup itself would broadcast the pending transactions by simply sending an inv with them all to every peer. This is a good way to get a transaction blasted out if there are no problems with it, but it means we cannot track propagation and the numBroadcastPeers() value was correspondingly not increased. This seems to be causing issues with the Android wallet. So try out a different approach - have the wallet use broadcastTransaction as per normal on the PeerGroup when it's added. The TX will be propagated and watched as with a normal spend.
This resolves some complicated state management issues in some kinds of client (like on Android). It's also just generally a part of the work to divorce the notion of settling a channel from closing underlying protocol connections.
The client now has a new CLOSED state, which is entered once a CLOSE has been sent and the close transaction (final contract) has been broadcast onto the P2P network and entered the wallet. Once received, the hash of the close tx is stored in the wallet - the tx is itself already in the wallets spent pool because it connects to the output of the multisig tx. After seeing three confirmations of the close TX the state is deleted from the client wallet for good.
Together these changes resolve a bug/design issue in which if a channel was opened, then closed, then another channel was opened but not closed, then a third attempt to connect to the server was made, the client would try to resume the first closed channel. That would fail because the server already deleted its state object and result in new channels being created even though the second could have been resumed. By tracking the fact that the channel was closed, it can be skipped when considering what channel to resume.
Apparently this simple utility class might start to need unit tests now!
To resolve the hack, we need to resolve some circularity in construction: to add the payment channels wallet extensions requires the peerGroup and wallet object to be constructed, but to construct the peerGroup requires the chain+store and to checkpoint a fresh store requires the wallet. Catch 22! We resolve by loading a temp wallet and then throwing it away, which is inefficient for a large wallet that's being replayed but normally shouldn't matter.
Once the payment channels stuff is more mature and tested, we might want to just fold it into the core wallet format.
Long story short, I'm a shitty programmer it seems. The Wallet will at some point be modified to track just bags of outputs derived from Transaction objects, and Transactions/Blocks will become immutable. At that point there won't be any confusion between mutable data associated with the deserialised objects.
Resolves issue 453.