Description
I have a question about tx.totalFees.coins
. I genuinely cannot understand what this value is supposed to represent. In my case, I want to write a test on how much gas is spent for a series of transactions.
I've provided an example at https://github.com/9oelM/ton-sandbox-totalfees-bug.git. The test setup is simple:
- User wallet sends tx to ContractA (msg mode is 0)
- ContractA sends tx to ContractB (msg mode is 64)
In code, it is as simple as:
it('fees test', async () => {
const increaser = await blockchain.treasury('increaser');
const contractBTONBalanceBefore = await contractB.getBalance();
const increaseResult = await contractA.sendIncrease(increaser.getSender(), {
increaseBy: 1,
value: toNano('0.05'),
});
expect(increaseResult.transactions).toHaveTransaction({
from: increaser.address,
to: contractA.address,
success: true,
});
expect(increaseResult.transactions).toHaveTransaction({
from: contractA.address,
to: contractB.address,
success: true,
});
printTransactionFees(increaseResult.transactions);
const allFees = increaseResult.transactions.reduce((acc, tx) => {
return acc + tx.totalFees.coins;
}, 0n)
const contractBTONBalanceAfter = await contractB.getBalance();
console.log('contractB TON inflow', contractBTONBalanceAfter - contractBTONBalanceBefore);
const lastTx = flattenTransaction(increaseResult.transactions[increaseResult.transactions.length - 1]);
expect(lastTx.value! - lastTx.totalFees!).toBe(
toNano('0.05') - allFees
);
});
printTransactionFees(increaseResult.transactions);
prints:
But I couldn't wrap my head around these numbers. I thought totalFees is supposed to be the sum of all total fees for a tx. In other words,
- For index = 0,
valueIn = 0.05 TON
(we started with 0.05 TON) andvalueOut = 0.0496 TON
.valueIn - valueOut = 0.0004
. ButtotalFees = 0.001613
??? - Same for index = 1.
valueIn = 0.0496 TON
andvalueOut = 0.046978 TON
.valueIn - valueOut = 0.002622
. ButtotalFees = 0.002296
???
If totalFees were correctly calculated as total gas for the tx, toNano('0.05') - allFees
would simply match the TON balance transferred to a contract, which is contractBTONBalanceAfter - contractBTONBalanceBefore
. But this is not the case. In fact, lastTx.value - lastTx.totalFees == contractBTONBalanceAfter - contractBTONBalanceBefore != toNano('0.05') - allFees
:
lastTx.value! - lastTx.totalFees!
=45904800n
contractBTONBalanceAfter - contractBTONBalanceBefore
=45904800n
toNano('0.05') - allFees
=45020139n
cc @krigga