Skip to content

Commit 47f216e

Browse files
authored
feat: add platform.getFeeState and update etna builder (#879)
1 parent b5db93b commit 47f216e

File tree

23 files changed

+224
-153
lines changed

23 files changed

+224
-153
lines changed

examples/p-chain/etna/base.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,16 @@ const SEND_AVAX_AMOUNT: number = 0.001;
1010
const main = async () => {
1111
const { AVAX_PUBLIC_URL, P_CHAIN_ADDRESS, PRIVATE_KEY } = getEnvVars();
1212

13-
const pvmApi = new pvm.PVMApi(AVAX_PUBLIC_URL);
14-
1513
const context = await getEtnaContextFromURI(AVAX_PUBLIC_URL);
1614

15+
const pvmApi = new pvm.PVMApi(AVAX_PUBLIC_URL);
16+
const feeState = await pvmApi.getFeeState();
17+
1718
const { utxos } = await pvmApi.getUTXOs({ addresses: [P_CHAIN_ADDRESS] });
1819

1920
const tx = pvm.e.newBaseTx(
2021
{
22+
feeState,
2123
fromAddressesBytes: [utils.bech32ToBytes(P_CHAIN_ADDRESS)],
2224
outputs: [
2325
TransferableOutput.fromNative(

examples/p-chain/etna/delegate.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ const DAYS_TO_DELEGATE: number = 14;
88
const main = async () => {
99
const { AVAX_PUBLIC_URL, P_CHAIN_ADDRESS, PRIVATE_KEY } = getEnvVars();
1010

11-
const pvmApi = new pvm.PVMApi(AVAX_PUBLIC_URL);
12-
1311
const context = await getEtnaContextFromURI(AVAX_PUBLIC_URL);
1412

13+
const pvmApi = new pvm.PVMApi(AVAX_PUBLIC_URL);
14+
const feeState = await pvmApi.getFeeState();
15+
1516
const { utxos } = await pvmApi.getUTXOs({ addresses: [P_CHAIN_ADDRESS] });
1617

1718
const startTime = await pvmApi.getTimestamp();
@@ -28,6 +29,7 @@ const main = async () => {
2829
const tx = pvm.e.newAddPermissionlessDelegatorTx(
2930
{
3031
end,
32+
feeState,
3133
fromAddressesBytes: [utils.bech32ToBytes(P_CHAIN_ADDRESS)],
3234
nodeId,
3335
rewardAddresses: [utils.bech32ToBytes(P_CHAIN_ADDRESS)],

examples/p-chain/etna/export.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const main = async () => {
1111
const context = await getEtnaContextFromURI(AVAX_PUBLIC_URL);
1212

1313
const pvmApi = new pvm.PVMApi(AVAX_PUBLIC_URL);
14+
const feeState = await pvmApi.getFeeState();
1415

1516
const { utxos } = await pvmApi.getUTXOs({
1617
addresses: [P_CHAIN_ADDRESS],
@@ -19,6 +20,7 @@ const main = async () => {
1920
const exportTx = pvm.e.newExportTx(
2021
{
2122
destinationChainId: context.xBlockchainID,
23+
feeState,
2224
fromAddressesBytes: [utils.bech32ToBytes(P_CHAIN_ADDRESS)],
2325
outputs: [
2426
TransferableOutput.fromNative(

examples/p-chain/etna/import.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const main = async () => {
99
const context = await getEtnaContextFromURI(AVAX_PUBLIC_URL);
1010

1111
const pvmApi = new pvm.PVMApi(AVAX_PUBLIC_URL);
12+
const feeState = await pvmApi.getFeeState();
1213

1314
const { utxos } = await pvmApi.getUTXOs({
1415
sourceChain: 'X',
@@ -17,6 +18,7 @@ const main = async () => {
1718

1819
const importTx = pvm.e.newImportTx(
1920
{
21+
feeState,
2022
fromAddressesBytes: [utils.bech32ToBytes(X_CHAIN_ADDRESS)],
2123
sourceChainId: context.xBlockchainID,
2224
toAddresses: [utils.bech32ToBytes(P_CHAIN_ADDRESS)],
Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { Context } from '../../../../src';
2-
1+
import { Context, Info } from '../../../../src';
32
/**
43
* Gets the context from URI and then modifies the context
54
* to be used for testing example Etna transactions until Etna is enabled.
@@ -9,5 +8,24 @@ export const getEtnaContextFromURI = async (
98
): Promise<Context.Context> => {
109
const context = await Context.getContextFromURI(uri);
1110

12-
return context;
11+
const info = new Info(uri);
12+
13+
const { etnaTime } = await info.getUpgradesInfo();
14+
15+
const etnaDateTime = new Date(etnaTime);
16+
const now = new Date();
17+
18+
if (etnaDateTime < now) {
19+
return context;
20+
}
21+
22+
// If Etna is not enabled, we need to override the minPrice of 1n that is returned.
23+
// This is because the minPrice of 1n is not enough to calculate a fee that exceeds the current static fees.
24+
return {
25+
...context,
26+
platformFeeConfig: {
27+
...context.platformFeeConfig,
28+
minPrice: 10_000n,
29+
},
30+
};
1331
};

examples/p-chain/etna/validate.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ const nodeId = getRandomNodeId();
1111
const main = async () => {
1212
const { AVAX_PUBLIC_URL, P_CHAIN_ADDRESS, PRIVATE_KEY } = getEnvVars();
1313

14-
const pvmApi = new pvm.PVMApi(AVAX_PUBLIC_URL);
15-
1614
const context = await getEtnaContextFromURI(AVAX_PUBLIC_URL);
1715

16+
const pvmApi = new pvm.PVMApi(AVAX_PUBLIC_URL);
17+
const feeState = await pvmApi.getFeeState();
18+
1819
const { utxos } = await pvmApi.getUTXOs({ addresses: [P_CHAIN_ADDRESS] });
1920

2021
const startTime = await pvmApi.getTimestamp();
@@ -37,6 +38,7 @@ const main = async () => {
3738
{
3839
end,
3940
delegatorRewardsOwner: [utils.bech32ToBytes(P_CHAIN_ADDRESS)],
41+
feeState,
4042
fromAddressesBytes: [utils.bech32ToBytes(P_CHAIN_ADDRESS)],
4143
nodeId,
4244
publicKey,

src/fixtures/context.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { createDimensions } from '../vms/common/fees/dimensions';
12
import type { Context } from '../vms/context';
23

34
export const testContext: Context = {
@@ -16,4 +17,17 @@ export const testContext: Context = {
1617
addSubnetDelegatorFee: 1000000n,
1718
networkID: 1,
1819
hrp: 'avax',
20+
platformFeeConfig: {
21+
weights: createDimensions({
22+
bandwidth: 1,
23+
dbRead: 1,
24+
dbWrite: 1,
25+
compute: 1,
26+
}),
27+
maxCapacity: 1_000_000n,
28+
maxPerSecond: 1_000n,
29+
targetPerSecond: 500n,
30+
minPrice: 1n,
31+
excessConversionConstant: 5_000n,
32+
},
1933
};

src/fixtures/feeConfig.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/fixtures/pvm.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import {
5555
} from './secp256k1';
5656
import { bytesForInt } from './utils/bytesFor';
5757
import { makeList, makeListBytes } from './utils/makeList';
58+
import type { FeeState } from '../vms/pvm';
5859

5960
export const validator = () =>
6061
new Validator(nodeId(), bigIntPr(), bigIntPr(), bigIntPr());
@@ -290,3 +291,10 @@ export const transformSubnetTxBytes = () =>
290291
bytesForInt(10),
291292
inputBytes(),
292293
);
294+
295+
export const feeState = (): FeeState => ({
296+
capacity: 1n,
297+
excess: 1n,
298+
price: 1n,
299+
timestamp: new Date().toISOString(),
300+
});

src/vms/context/context.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { getHRP } from '../../constants/networkIDs';
22
import { Info } from '../../info/info';
33
import { AVMApi } from '../avm/api';
4+
import { PVMApi } from '../pvm';
45
import type { Context } from './model';
56

67
/*
@@ -10,6 +11,7 @@ export const getContextFromURI = async (
1011
baseURL?: string,
1112
assetDescription = 'AVAX',
1213
): Promise<Context> => {
14+
const pChainApi = new PVMApi(baseURL);
1315
const xChainApi = new AVMApi(baseURL);
1416
const { assetID: avaxAssetID } = await xChainApi.getAssetDescription(
1517
assetDescription,
@@ -33,6 +35,8 @@ export const getContextFromURI = async (
3335
const { networkID: networkIDstring } = await info.getNetworkId();
3436
const networkID = Number(networkIDstring);
3537

38+
const platformFeeConfig = await pChainApi.getFeeConfig();
39+
3640
return Object.freeze({
3741
xBlockchainID,
3842
pBlockchainID,
@@ -49,5 +53,6 @@ export const getContextFromURI = async (
4953
addSubnetDelegatorFee,
5054
networkID,
5155
hrp: getHRP(networkID),
56+
platformFeeConfig,
5257
});
5358
};

src/vms/context/model.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import type { FeeConfig } from '../pvm';
2+
13
export type Context = {
24
readonly networkID: number;
35
readonly hrp: string;
@@ -14,4 +16,7 @@ export type Context = {
1416
readonly addPrimaryNetworkDelegatorFee: bigint;
1517
readonly addSubnetValidatorFee: bigint;
1618
readonly addSubnetDelegatorFee: bigint;
19+
20+
// Post Etna
21+
readonly platformFeeConfig: FeeConfig;
1722
};

src/vms/pvm/api.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import { createDimensions } from '../common/fees/dimensions';
88
import type {
99
FeeConfig,
1010
FeeConfigResponse,
11+
FeeState,
12+
FeeStateResponse,
1113
GetBalanceParams,
1214
GetBalanceResponse,
1315
GetBlockchainsResponse,
@@ -247,4 +249,15 @@ export class PVMApi extends AvaxApi {
247249
excessConversionConstant: BigInt(excessConversionConstant),
248250
};
249251
}
252+
253+
async getFeeState(): Promise<FeeState> {
254+
const resp = await this.callRpc<FeeStateResponse>('getFeeState');
255+
256+
return {
257+
capacity: BigInt(resp.capacity),
258+
excess: BigInt(resp.excess),
259+
price: BigInt(resp.price),
260+
timestamp: resp.timestamp,
261+
};
262+
}
250263
}

0 commit comments

Comments
 (0)