Repository: bitcoin/bitcoin
File: test/functional/wallet_fundrawtransaction.py (Python)

Code before:
        vout2 = next(utxo["vout"] for utxo in wallet.listunspent() if utxo["txid"] == txid2)
        amount_with_fee_err_msg = "The total exceeds your balance when the {} transaction fee is included."

        self.log.info("Test without preselected inputs")
        self.log.info("Attempt to send 0.45 BTC without SFFO")
        rawtx = wallet.createrawtransaction(inputs=[], outputs=[{default_wallet.getnewaddress(): 0.45}])
        assert_raises_rpc_error(-4, amount_with_fee_err_msg.format("0.00000042"), wallet.fundrawtransaction, rawtx, options={"fee_rate":1})

        self.log.info("Send 0.45 BTC with SFFO")
        wallet.fundrawtransaction(rawtx, options={"subtractFeeFromOutputs":[0]})

        self.log.info("Attempt to send 0.45 BTC by restricting coin selection with minconf=6")
        assert_raises_rpc_error(-4, "Insufficient funds", wallet.fundrawtransaction, rawtx, options={"minconf":6})

        self.log.info("Test with preselected inputs")
        self.log.info("Attempt to send 0.45 BTC preselecting 0.15 BTC utxo")
        rawtx = wallet.createrawtransaction(inputs=[{"txid": txid2, "vout": vout2}], outputs=[{default_wallet.getnewaddress(): 0.45}])
        assert_raises_rpc_error(-4, amount_with_fee_err_msg.format("0.00000042"), wallet.fundrawtransaction, rawtx, options={"fee_rate":1})

        self.log.info("Send 0.45 BTC preselecting 0.15 BTC utxo with SFFO")
        wallet.fundrawtransaction(hexstring=rawtx, options={"subtractFeeFromOutputs":[0]})

        self.log.info("Attempt to send 0.15 BTC using only the 0.15 BTC preselected utxo")
        rawtx = wallet.createrawtransaction(inputs=[{"txid": txid2, "vout": vout2}], outputs=[{default_wallet.getnewaddress(): 0.15}])
        assert_raises_rpc_error(-4, "The preselected coins total amount does not cover the transaction target. "
                                             "Please allow other inputs to be automatically selected or include more coins manually",
                                              wallet.fundrawtransaction, rawtx, options={"fee_rate":1, "add_inputs":False})
        self.log.info("Send 0.15 BTC using only the 0.15 BTC preselected utxo with SFFO")
        wallet.fundrawtransaction(hexstring=rawtx, options={"subtractFeeFromOutputs":[0], "add_inputs":False})


if __name__ == '__main__':
    RawTransactionsTest(__file__).main()


Review comment (suggestion):
In 2be0279a2ad1dd372b9df9500cd4b50ec8d27a04 "wallet: introduce "tx amount exceeds balance when fees are included" error"

Can use `ERR_NOT_ENOUGH_PRESET_INPUTS` for the error message rather than retyping the very long string.

Code after:
        vout2 = next(utxo["vout"] for utxo in wallet.listunspent() if utxo["txid"] == txid2)
        amount_with_fee_err_msg = "The total exceeds your balance when the {} transaction fee is included."

        self.log.info("Test without preselected inputs")
        self.log.info("Attempt to send 0.45 BTC without SFFO")
        rawtx = wallet.createrawtransaction(inputs=[], outputs=[{default_wallet.getnewaddress(): 0.45}])
        assert_raises_rpc_error(-4, amount_with_fee_err_msg.format("0.00000042"), wallet.fundrawtransaction, rawtx, options={"fee_rate":1})

        self.log.info("Send 0.45 BTC with SFFO")
        wallet.fundrawtransaction(rawtx, options={"subtractFeeFromOutputs":[0]})

        self.log.info("Attempt to send 0.45 BTC by restricting coin selection with minconf=6")
        assert_raises_rpc_error(-4, "Insufficient funds", wallet.fundrawtransaction, rawtx, options={"minconf":6})

        self.log.info("Test with preselected inputs")
        self.log.info("Attempt to send 0.45 BTC preselecting 0.15 BTC utxo")
        rawtx = wallet.createrawtransaction(inputs=[{"txid": txid2, "vout": vout2}], outputs=[{default_wallet.getnewaddress(): 0.45}])
        assert_raises_rpc_error(-4, amount_with_fee_err_msg.format("0.00000042"), wallet.fundrawtransaction, rawtx, options={"fee_rate":1})

        self.log.info("Send 0.45 BTC preselecting 0.15 BTC utxo with SFFO")
        wallet.fundrawtransaction(hexstring=rawtx, options={"subtractFeeFromOutputs":[0]})

        self.log.info("Attempt to send 0.15 BTC using only the 0.15 BTC preselected utxo")
        rawtx = wallet.createrawtransaction(inputs=[{"txid": txid2, "vout": vout2}], outputs=[{default_wallet.getnewaddress(): 0.15}])
        assert_raises_rpc_error(-4, ERR_NOT_ENOUGH_PRESET_INPUTS, wallet.fundrawtransaction, rawtx, options={"fee_rate":1, "add_inputs":False})
        self.log.info("Send 0.15 BTC using only the 0.15 BTC preselected utxo with SFFO")
        wallet.fundrawtransaction(hexstring=rawtx, options={"subtractFeeFromOutputs":[0], "add_inputs":False})


if __name__ == '__main__':
    RawTransactionsTest(__file__).main()