Skip to content

Commit 2651bf5

Browse files
committed
feat: add fee calculator
1 parent 3977b68 commit 2651bf5

File tree

5 files changed

+373
-237
lines changed

5 files changed

+373
-237
lines changed

src/vms/common/fees/dimensions.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,15 @@ export const addDimensions = (...dimensions: Dimensions[]): Dimensions => {
4848
}
4949
return result;
5050
};
51+
52+
export const dimensionsToGas = (
53+
dimensions: Dimensions,
54+
weights: Dimensions,
55+
): bigint => {
56+
return BigInt(
57+
dimensions[FeeDimensions.Bandwidth] * weights[FeeDimensions.Bandwidth] +
58+
dimensions[FeeDimensions.DBRead] * weights[FeeDimensions.DBRead] +
59+
dimensions[FeeDimensions.DBWrite] * weights[FeeDimensions.DBWrite] +
60+
dimensions[FeeDimensions.Compute] * weights[FeeDimensions.Compute],
61+
);
62+
};
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { hexToBuffer, unpackWithManager } from '../../../../utils';
2+
import { calculateFee } from './calculator';
3+
import {
4+
TEST_DYNAMIC_PRICE,
5+
TEST_DYNAMIC_WEIGHTS,
6+
TEST_TRANSACTIONS,
7+
TEST_UNSUPPORTED_TRANSACTIONS,
8+
} from './fixtures/transactions';
9+
10+
const txHexToPVMTransaction = (txHex: string) => {
11+
const txBytes = hexToBuffer(txHex);
12+
13+
// console.log('txBytes length:', txBytes.length, '=== expected bandwidth');
14+
15+
return unpackWithManager('PVM', txBytes);
16+
};
17+
18+
describe('Calculator', () => {
19+
describe('calculateFee', () => {
20+
test.each(TEST_TRANSACTIONS)(
21+
'calculates the fee for $name',
22+
({ txHex, expectedDynamicFee }) => {
23+
const result = calculateFee(
24+
txHexToPVMTransaction(txHex),
25+
TEST_DYNAMIC_WEIGHTS,
26+
TEST_DYNAMIC_PRICE,
27+
);
28+
29+
expect(result).toBe(expectedDynamicFee);
30+
},
31+
);
32+
33+
test.each(TEST_UNSUPPORTED_TRANSACTIONS)(
34+
'unsupported tx - $name',
35+
({ txHex }) => {
36+
const tx = txHexToPVMTransaction(txHex);
37+
38+
expect(() => {
39+
calculateFee(tx, TEST_DYNAMIC_WEIGHTS, TEST_DYNAMIC_PRICE);
40+
}).toThrow('Unsupported transaction type.');
41+
},
42+
);
43+
});
44+
});

src/vms/pvm/txs/fee/calculator.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import type { Transaction } from '../../../common';
2+
import {
3+
dimensionsToGas,
4+
type Dimensions,
5+
} from '../../../common/fees/dimensions';
6+
import { txComplexity } from './complexity';
7+
8+
/**
9+
* Calculates the minimum required fee, in nAVAX, that an unsigned
10+
* transaction must pay for valid inclusion into a block.
11+
*/
12+
export const calculateFee = (
13+
// TODO: Do we need this to be UnsignedTx?
14+
// If so, we can use .getTx() to get the Transaction.
15+
tx: Transaction,
16+
weights: Dimensions,
17+
price: bigint,
18+
): bigint => {
19+
const complexity = txComplexity(tx);
20+
21+
const gas = dimensionsToGas(complexity, weights);
22+
23+
return gas * price;
24+
};

0 commit comments

Comments
 (0)