How to calculate the cost of a transaction? Is my program correct?

Why

There’s a duststorm out there, and it’s never gonna end.

According to the document: [6.1 Mempool | Chia Documentation]

Fees that are very close to zero are considered equivalent to zero. The threshold is set at 5 mojo per cost, but this can vary by implementation, version, and settings, so it’s not guaranteed by the protocol.

To get my transaction included in the mempool, I’ll need to add a fee.

But how do I know what’s the threshold of a valid fee if I don’t know the fee per cost of my transaction?

Research

I failed to find an existing api for calculating the cost of a transaction after a few hours search the source code. So I had to write my own.

Is the following program correct?

from chia.types.blockchain_format.program import INFINITE_COST
from chia.types.condition_opcodes import ConditionOpcode
from chia.types.spend_bundle import SpendBundle

def get_transaction_cost(spend_bundle: SpendBundle, cost_per_byte: int):
    total_cost = 0

    for spend in spend_bundle.coin_spends:
        len_puz = len(bytes(spend.puzzle_reveal))
        len_sol = len(bytes(spend.solution))
        total_cost += (len_puz + len_sol) * cost_per_byte

        cost, result = spend.puzzle_reveal.run_with_cost(INFINITE_COST, spend.solution)
        total_cost += cost

        for cond in result.as_python():
            opcode = cond[0]
            if opcode in [ConditionOpcode.AGG_SIG_UNSAFE, ConditionOpcode.AGG_SIG_ME]:
                total_cost += ConditionCost.AGG_SIG.value
            elif opcode == ConditionOpcode.CREATE_COIN:
                total_cost += ConditionCost.CREATE_COIN.value

    return total_cost
1 Like
from chia.full_node.bundle_tools import simple_solution_generator
from chia.full_node.mempool_check_conditions import get_name_puzzle_conditions

program = simple_solution_generator(bundle)
npc_result = get_name_puzzle_conditions(
    program,
    constants.MAX_BLOCK_COST_CLVM,
    cost_per_byte=constants.COST_PER_BYTE,
     mempool_mode=True,
)
print(npc_result.cost)

I think your program is probably mostly correct. I would recommend using get_name_puzzle_conditions like in @william 's answer but his answer doesn’t take into account puzzle reveal and solution reveal cost like yours does.

It is also worth noting that the cost documentation has recently been significantly enhanced:

4 Likes