|
|
@ -193,7 +193,52 @@ class PSBTTest(BitcoinTestFramework):
|
|
|
|
res = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": 0.1, "add_inputs": True})
|
|
|
|
res = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": 0.1, "add_inputs": True})
|
|
|
|
assert_approx(res["fee"], 0.055, 0.005)
|
|
|
|
assert_approx(res["fee"], 0.055, 0.005)
|
|
|
|
|
|
|
|
|
|
|
|
self.log.info("Test walletcreatefundedpsbt feeRate of 10 BTC/KB produces total fee well above -maxtxfee and raises RPC error")
|
|
|
|
self.log.info("Test walletcreatefundedpsbt explicit fee rate with conf_target and estimate_mode")
|
|
|
|
|
|
|
|
for unit, fee_rate in {"btc/kb": 0.1, "sat/b": 10000}.items():
|
|
|
|
|
|
|
|
fee = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"conf_target": fee_rate, "estimate_mode": unit, "add_inputs": True})["fee"]
|
|
|
|
|
|
|
|
self.log.info("- conf_target {}, estimate_mode {} produces fee {} at or slightly below -maxtxfee (~0.05290000)".format(fee_rate, unit, fee))
|
|
|
|
|
|
|
|
assert_approx(fee, vexp=0.055, vspan=0.005)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for field, fee_rate in {"conf_target": 0.1, "estimate_mode": "sat/b"}.items():
|
|
|
|
|
|
|
|
self.log.info("- raises RPC error if both feeRate and {} are passed".format(field))
|
|
|
|
|
|
|
|
assert_raises_rpc_error(-8, "Cannot specify both {} and feeRate".format(field),
|
|
|
|
|
|
|
|
lambda: self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": 0.1, field: fee_rate, "add_inputs": True}))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.log.info("- raises RPC error with invalid estimate_mode settings")
|
|
|
|
|
|
|
|
for k, v in {"number": 42, "object": {"foo": "bar"}}.items():
|
|
|
|
|
|
|
|
assert_raises_rpc_error(-3, "Expected type string for estimate_mode, got {}".format(k),
|
|
|
|
|
|
|
|
lambda: self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"estimate_mode": v, "conf_target": 0.1, "add_inputs": True}))
|
|
|
|
|
|
|
|
for mode in ["foo", Decimal("3.141592")]:
|
|
|
|
|
|
|
|
assert_raises_rpc_error(-8, "Invalid estimate_mode parameter",
|
|
|
|
|
|
|
|
lambda: self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"estimate_mode": mode, "conf_target": 0.1, "add_inputs": True}))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.log.info("- raises RPC error if estimate_mode is passed without a conf_target")
|
|
|
|
|
|
|
|
for unit in ["SAT/B", "BTC/KB"]:
|
|
|
|
|
|
|
|
assert_raises_rpc_error(-8, "Selected estimate_mode {} requires a fee rate to be specified in conf_target".format(unit),
|
|
|
|
|
|
|
|
lambda: self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"estimate_mode": unit}))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.log.info("- raises RPC error with invalid conf_target settings")
|
|
|
|
|
|
|
|
for mode in ["unset", "economical", "conservative", "btc/kb", "sat/b"]:
|
|
|
|
|
|
|
|
self.log.debug("{}".format(mode))
|
|
|
|
|
|
|
|
for k, v in {"string": "", "object": {"foo": "bar"}}.items():
|
|
|
|
|
|
|
|
assert_raises_rpc_error(-3, "Expected type number for conf_target, got {}".format(k),
|
|
|
|
|
|
|
|
lambda: self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"estimate_mode": mode, "conf_target": v, "add_inputs": True}))
|
|
|
|
|
|
|
|
if mode in ["btc/kb", "sat/b"]:
|
|
|
|
|
|
|
|
assert_raises_rpc_error(-3, "Amount out of range",
|
|
|
|
|
|
|
|
lambda: self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"estimate_mode": mode, "conf_target": -1, "add_inputs": True}))
|
|
|
|
|
|
|
|
assert_raises_rpc_error(-4, "Fee rate (0.00000000 BTC/kB) is lower than the minimum fee rate setting (0.00001000 BTC/kB)",
|
|
|
|
|
|
|
|
lambda: self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"estimate_mode": mode, "conf_target": 0, "add_inputs": True}))
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
for n in [-1, 0, 1009]:
|
|
|
|
|
|
|
|
assert_raises_rpc_error(-8, "Invalid conf_target, must be between 1 and 1008",
|
|
|
|
|
|
|
|
lambda: self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"estimate_mode": mode, "conf_target": n, "add_inputs": True}))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for unit, fee_rate in {"SAT/B": 0.99999999, "BTC/KB": 0.00000999}.items():
|
|
|
|
|
|
|
|
self.log.info("- raises RPC error 'fee rate too low' if conf_target {} and estimate_mode {} are passed".format(fee_rate, unit))
|
|
|
|
|
|
|
|
assert_raises_rpc_error(-4, "Fee rate (0.00000999 BTC/kB) is lower than the minimum fee rate setting (0.00001000 BTC/kB)",
|
|
|
|
|
|
|
|
lambda: self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"estimate_mode": unit, "conf_target": fee_rate, "add_inputs": True}))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.log.info("Test walletcreatefundedpsbt feeRate of 10 BTC/kB produces total fee well above -maxtxfee and raises RPC error")
|
|
|
|
# previously this was silently capped at -maxtxfee
|
|
|
|
# previously this was silently capped at -maxtxfee
|
|
|
|
for bool_add, outputs_array in {True: outputs, False: [{self.nodes[1].getnewaddress(): 1}]}.items():
|
|
|
|
for bool_add, outputs_array in {True: outputs, False: [{self.nodes[1].getnewaddress(): 1}]}.items():
|
|
|
|
assert_raises_rpc_error(-4, "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)",
|
|
|
|
assert_raises_rpc_error(-4, "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)",
|
|
|
|