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.
/**
 * Process incoming block headers.
 *
 * Call without cs_main held.
 *
 * @param[in]  block The block headers themselves
 * @param[out] state This may be set to an Error state if any error occurred processing them
 * @param[in]  chainparams The params for the chain we want to connect to
 * @param[out] ppindex If set, the pointer will be set to point to the last new block index object for the given headers
 */
bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, CValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex=NULL);
bool CheckDiskSpace(uint64_t nAdditionalBytes = 0);
FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly = false);
FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly = false);
boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix);
bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskBlockPos *dbp = NULL);
bool InitBlockIndex(const CChainParams& chainparams);
bool LoadBlockIndex(const CChainParams& chainparams);
void UnloadBlockIndex();
void ThreadScriptCheck();
bool IsInitialBlockDownload();
/** Format a string that describes several potential problems detected by the core.
 * strFor can have three values:
 * - "rpc": get critical warnings, which should put the client in safe mode if non-empty
 * - "statusbar": get all warnings
 * - "gui": get all warnings, translated (where possible) for GUI
 * This function only returns the highest priority warning of the set selected by strFor.
 */
std::string GetWarnings(const std::string& strFor);
bool GetTransaction(const uint256 &hash, CTransactionRef &tx, const Consensus::Params& params, uint256 &hashBlock, bool fAllowSlow = false);