diff --git a/chia/rpc/full_node_rpc_api.py b/chia/rpc/full_node_rpc_api.py index 8e1b29e0c986..5effbfd70368 100644 --- a/chia/rpc/full_node_rpc_api.py +++ b/chia/rpc/full_node_rpc_api.py @@ -1,6 +1,5 @@ from __future__ import annotations -import math from datetime import datetime, timezone from typing import Any, Dict, List, Optional @@ -760,26 +759,24 @@ class FullNodeRpcApi: return {"mempool_item": item} - def _get_spendbundle_type_cost(self, name: str): + def _get_spendbundle_type_cost(self, name: str) -> uint64: """ This is a stopgap until we modify the wallet RPCs to get exact costs for created SpendBundles - before we send the mto the Mempool. + before we send them to the Mempool. """ - maxBlockCostCLVM = 11_000_000_000 - txCostEstimates = { - "walletSendXCH": math.floor(maxBlockCostCLVM / 1170), - "spendCATtx": 36_382_111, - "acceptOffer": 721_393_265, - "cancelOffer": 212_443_993, - "burnNFT": 74_385_541, - "assignDIDToNFT": 115_540_006, - "transferNFT": 74_385_541, - "createPlotNFT": 18_055_407, - "claimPoolingReward": 82_668_466, - "createDID": 57_360_396, + tx_cost_estimates = { + "send_xch_transaction": 9_401_710, + "cat_spend": 36_382_111, + "take_offer": 721_393_265, + "cancel_offer": 212_443_993, + "nft_set_nft_did": 115_540_006, + "nft_transfer_nft": 74_385_541, # burn or transfer + "create_new_pool_wallet": 18_055_407, + "pw_absorb_rewards": 82_668_466, + "create_new_did_wallet": 57_360_396, } - return txCostEstimates[name] + return uint64(tx_cost_estimates[name]) async def _validate_fee_estimate_cost(self, request: Dict) -> uint64: c = 0 @@ -803,6 +800,7 @@ class FullNodeRpcApi: cost = request["cost"] else: cost = self._get_spendbundle_type_cost(request["spend_type"]) + cost *= request.get("spend_count", 1) return uint64(cost) def _validate_target_times(self, request: Dict) -> None: diff --git a/tests/fee_estimation/test_fee_estimation_rpc.py b/tests/fee_estimation/test_fee_estimation_rpc.py index 12edbb63ecbc..692fe670cad1 100644 --- a/tests/fee_estimation/test_fee_estimation_rpc.py +++ b/tests/fee_estimation/test_fee_estimation_rpc.py @@ -222,9 +222,9 @@ async def test_validate_fee_estimate_cost_err( bad_arglist: List[List[Any]] = [ [["foo", "bar"]], [["spend_bundle", spend_bundle.to_json_dict()], ["cost", 1]], - [["spend_bundle", spend_bundle.to_json_dict()], ["spend_type", "walletSendXCH"]], - [["cost", 1], ["spend_type", "walletSendXCH"]], - [["spend_bundle", spend_bundle.to_json_dict()], ["cost", 1], ["spend_type", "walletSendXCH"]], + [["spend_bundle", spend_bundle.to_json_dict()], ["spend_type", "send_xch_transaction"]], + [["cost", 1], ["spend_type", "send_xch_transaction"]], + [["spend_bundle", spend_bundle.to_json_dict()], ["cost", 1], ["spend_type", "send_xch_transaction"]], ] for args in bad_arglist: print(args) @@ -248,9 +248,41 @@ async def test_validate_fee_estimate_cost_ok( good_arglist: List[List[Any]] = [ ["spend_bundle", spend_bundle.to_json_dict()], ["cost", 1], - ["spend_type", "walletSendXCH"], + ["spend_type", "send_xch_transaction"], ] for var, val in good_arglist: request = {"target_times": [1]} request[var] = val _ = await full_node_rpc_api.get_fee_estimate(request) + + +@pytest.mark.asyncio +async def test_get_spendbundle_type_cost_missing( + setup_node_and_rpc: Tuple[FullNodeRpcClient, FullNodeRpcApi], bt: BlockTools +) -> None: + client, full_node_rpc_api = setup_node_and_rpc + with pytest.raises(KeyError, match=re.escape("INVALID")): + request = {"target_times": [1], "spend_type": "INVALID"} + _ = await full_node_rpc_api.get_fee_estimate(request) + + +@pytest.mark.asyncio +async def test_get_spendbundle_type_cost_spend_count_ok( + setup_node_and_rpc: Tuple[FullNodeRpcClient, FullNodeRpcApi], bt: BlockTools +) -> None: + client, full_node_rpc_api = setup_node_and_rpc + spend_counts = [0, 1, 2] + for spend_count in spend_counts: + request = {"target_times": [1], "spend_type": "send_xch_transaction", "spend_count": spend_count} + ret = await full_node_rpc_api.get_fee_estimate(request) + print(spend_count, ret) + + +@pytest.mark.asyncio +async def test_get_spendbundle_type_cost_spend_count_bad( + setup_node_and_rpc: Tuple[FullNodeRpcClient, FullNodeRpcApi], bt: BlockTools +) -> None: + client, full_node_rpc_api = setup_node_and_rpc + with pytest.raises(ValueError): + request = {"target_times": [1], "spend_type": "send_xch_transaction", "spend_count": -1} + _ = await full_node_rpc_api.get_fee_estimate(request)