the `zapwallettxes.py` qa test is currently broken due to a syntax error:

```python
     assert_raises(JSONRPCException, self.nodes[0].gettransaction, [txid3])
     #there must be a expection because the unconfirmed wallettx0 must be gone by now
```

This doesn't actually test that the transaction is not in the wallet, because `gettransaction()` is being called incorrectly (with an array instead of a string).

Changing the test to `assert_raises(JSONRPCException, self.nodes[0].gettransaction, txid3)` causes the rpc to succeed and the test script to fail because `txid3` is still in the wallet.

This is because the mempool is now persistent and is saved to disk when bitcoind shuts down. zapwallettxes removes the unconfirmed transaction from the wallet but bitcoind will rescan the mempool.dat file on startup and add the unconfirmed transaction back into the wallet.

I've 'fixed' zapwallettxes.py in https://github.com/jnewbery/bitcoin/tree/zapwallettxes , but the question remains: how *should* -zapwallettxes interact with persistent mempool? The use case for zapwallettxes is explained here: https://github.com/bitcoin/bitcoin/pull/3659#issuecomment-34878999 . My view is that even with zapwallettxes, bitcoind should rescan the mempool, but there should be better documentation or a warning that unconfirmed transaction in your mempool will be re-added to the wallet even if zapwallettxes is used. If you really want to remove all unconfirmed transactions from your wallet, you can delete your mempool.dat file and then restart with zapwallettxes.
extern uint256 hashAssumeValid;
extern CBlockIndex *pindexBestHeader;
static const uint64_t nMinDiskSpace = 52428800;
extern bool fHavePruned;
extern bool fPruneMode;
extern uint64_t nPruneTarget;
static const unsigned int MIN_BLOCKS_TO_KEEP = 288;
static const signed int DEFAULT_CHECKBLOCKS = 6;
static const unsigned int DEFAULT_CHECKLEVEL = 3;
static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024;
/** 
 * Process an incoming block. This only returns after the best known valid
 * block is made active. Note that it does not, however, guarantee that the
 * specific block passed to it has been checked for validity!
 *
 * If you want to *possibly* get feedback on whether pblock is valid, you must
 * install a CValidationInterface (see validationinterface.h) - this will have
 * its BlockChecked method called whenever *any* block completes validation.
 *
 * Note that we guarantee that either the proof-of-work is valid on pblock, or
 * (and possibly also) BlockChecked will have been called.
 * 
 * Call without cs_main held.
 *
 * @param[in]   pblock  The block we want to process.
 * @param[in]   fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers.
 * @param[out]  fNewBlock A boolean which is set to indicate if the block was first received via this call
 * @return True if state.IsValid()
 */
bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, bool* fNewBlock);