@aeternity/aepp-sdk 14.1.1 → 15.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/dist/aepp-sdk.browser-script.cjs +1 -1
  2. package/dist/aepp-sdk.browser-script.cjs.map +1 -1
  3. package/dist/aepp-sdk.browser.cjs +1 -1
  4. package/dist/aepp-sdk.browser.cjs.map +1 -1
  5. package/dist/aepp-sdk.cjs +3068 -502
  6. package/dist/aepp-sdk.cjs.map +1 -1
  7. package/es/account/Base.d.ts +6 -1
  8. package/es/account/Base.js.map +1 -1
  9. package/es/account/Generalized.d.ts +1 -1
  10. package/es/account/Generalized.js +7 -1
  11. package/es/account/Generalized.js.map +1 -1
  12. package/es/apis/node/models/index.d.ts +405 -79
  13. package/es/apis/node/models/index.js.map +1 -1
  14. package/es/apis/node/models/mappers.d.ts +54 -4
  15. package/es/apis/node/models/mappers.js +1910 -500
  16. package/es/apis/node/models/mappers.js.map +1 -1
  17. package/es/apis/node/node.d.ts +28 -6
  18. package/es/apis/node/node.js +276 -5
  19. package/es/apis/node/node.js.map +1 -1
  20. package/es/channel/Contract.d.ts +5 -0
  21. package/es/channel/Contract.js +8 -2
  22. package/es/channel/Contract.js.map +1 -1
  23. package/es/channel/handlers.js +3 -3
  24. package/es/channel/handlers.js.map +1 -1
  25. package/es/contract/ga.d.ts +5 -2
  26. package/es/contract/ga.js +53 -21
  27. package/es/contract/ga.js.map +1 -1
  28. package/es/index-browser.d.ts +3 -1
  29. package/es/index-browser.js +2 -1
  30. package/es/index-browser.js.map +1 -1
  31. package/es/tx/builder/constants.d.ts +12 -2
  32. package/es/tx/builder/constants.js +11 -1
  33. package/es/tx/builder/constants.js.map +1 -1
  34. package/es/tx/builder/entry/index.js +6 -0
  35. package/es/tx/builder/entry/index.js.map +1 -1
  36. package/es/tx/builder/entry/schema.d.ts +10 -10
  37. package/es/tx/builder/field-types/ct-version.d.ts +14 -0
  38. package/es/tx/builder/field-types/ct-version.js +14 -0
  39. package/es/tx/builder/field-types/ct-version.js.map +1 -1
  40. package/es/tx/builder/field-types/fee.d.ts +9 -7
  41. package/es/tx/builder/field-types/fee.js +75 -66
  42. package/es/tx/builder/field-types/fee.js.map +1 -1
  43. package/es/tx/builder/field-types/gas-limit.d.ts +5 -3
  44. package/es/tx/builder/field-types/gas-limit.js +25 -14
  45. package/es/tx/builder/field-types/gas-limit.js.map +1 -1
  46. package/es/tx/builder/field-types/gas-price.d.ts +6 -4
  47. package/es/tx/builder/field-types/gas-price.js +87 -21
  48. package/es/tx/builder/field-types/gas-price.js.map +1 -1
  49. package/es/tx/builder/field-types/interface.d.ts +20 -0
  50. package/es/tx/builder/field-types/interface.js +17 -1
  51. package/es/tx/builder/field-types/interface.js.map +1 -1
  52. package/es/tx/builder/field-types/name-fee.d.ts +3 -2
  53. package/es/tx/builder/field-types/name-fee.js +6 -0
  54. package/es/tx/builder/field-types/name-fee.js.map +1 -1
  55. package/es/tx/builder/field-types/pointers.d.ts +2 -1
  56. package/es/tx/builder/field-types/pointers.js +6 -2
  57. package/es/tx/builder/field-types/pointers.js.map +1 -1
  58. package/es/tx/builder/field-types/transaction.d.ts +4 -1
  59. package/es/tx/builder/field-types/transaction.js +18 -3
  60. package/es/tx/builder/field-types/transaction.js.map +1 -1
  61. package/es/tx/builder/field-types/with-formatting.d.ts +1 -1
  62. package/es/tx/builder/field-types/with-formatting.js +1 -1
  63. package/es/tx/builder/field-types/with-formatting.js.map +1 -1
  64. package/es/tx/builder/index.d.ts +13 -0
  65. package/es/tx/builder/index.js +92 -5
  66. package/es/tx/builder/index.js.map +1 -1
  67. package/es/tx/builder/protocol-parameters.d.ts +123 -0
  68. package/es/tx/builder/protocol-parameters.js +519 -0
  69. package/es/tx/builder/protocol-parameters.js.map +1 -0
  70. package/es/tx/builder/schema.d.ts +156 -155
  71. package/es/tx/builder/schema.js +5 -1
  72. package/es/tx/builder/schema.js.map +1 -1
  73. package/es/tx/execution-cost.js +5 -5
  74. package/es/tx/execution-cost.js.map +1 -1
  75. package/es/tx/transaction-signer.js +2 -2
  76. package/es/tx/transaction-signer.js.map +1 -1
  77. package/es/tx/validator.js +4 -4
  78. package/es/tx/validator.js.map +1 -1
  79. package/es/utils/wrap-proxy.d.ts +10 -0
  80. package/es/utils/wrap-proxy.js +18 -0
  81. package/es/utils/wrap-proxy.js.map +1 -1
  82. package/package.json +2 -2
@@ -0,0 +1,519 @@
1
+ import { AbiVersion, MAX_AUTH_FUN_GAS, MIN_GAS_PRICE, Tag } from './constants.js';
2
+ import { isKeyOfObject } from '../../utils/other.js';
3
+ import { ArgumentError, InternalError, NodeError } from '../../utils/errors.js';
4
+ import { unwrapProxy } from '../../utils/wrap-proxy.js';
5
+
6
+ /**
7
+ * Consensus parameters and node policy settings the transaction builder needs to produce a
8
+ * transaction the node would accept — see {@link getCachedProtocolParameters}.
9
+ * @category transaction builder
10
+ */
11
+
12
+ /**
13
+ * Transaction option to build a transaction against specific consensus parameters. `buildTxAsync`
14
+ * sets it to the parameters it requests from node, provide it to build a transaction offline for a
15
+ * node that doesn't run the protocol version the current SDK release was made for.
16
+ * @category transaction builder
17
+ */
18
+
19
+ const BASE_GAS = 15000;
20
+ const defaultStateGasPerBlock = {
21
+ part: 32000,
22
+ whole: Math.floor(60 * 24 * 365 / 3)
23
+ };
24
+
25
+ /**
26
+ * Protocol parameters are shared between every transaction built against them, and
27
+ * {@link defaultProtocolParameters} is shared process-wide. `readonly` guards them at compile time
28
+ * only, so freeze them to make sure a transaction can't be mispriced by an unrelated component
29
+ * mutating parameters it doesn't own.
30
+ */
31
+ function freezeParameters(parameters) {
32
+ Object.values(parameters.contractTxBaseGas).forEach(Object.freeze);
33
+ Object.values(parameters.stateGasPerBlock).forEach(Object.freeze);
34
+ Object.freeze(parameters.txBaseGas);
35
+ Object.freeze(parameters.contractTxBaseGas);
36
+ Object.freeze(parameters.stateGasPerBlock);
37
+ return Object.freeze(parameters);
38
+ }
39
+
40
+ /**
41
+ * Protocol parameters of Ceres as they were at the moment of the SDK release. Used to build
42
+ * transactions without a node connection, and on nodes that don't provide the protocol parameters
43
+ * endpoint yet.
44
+ * @category transaction builder
45
+ * @see {@link https://github.com/aeternity/protocol/blob/master/consensus/README.md#gas}
46
+ */
47
+ export const defaultProtocolParameters = freezeParameters({
48
+ minGasPrice: BigInt(MIN_GAS_PRICE),
49
+ minMinerGasPrice: BigInt(MIN_GAS_PRICE),
50
+ gasPerByte: 20,
51
+ blockGasLimit: 6e6,
52
+ maxAuthFunGas: MAX_AUTH_FUN_GAS,
53
+ txBaseGas: {
54
+ ...Object.fromEntries(Object.values(Tag).filter(tag => typeof tag === 'number')
55
+ // node reports the base gas of contract-executing types in `contract_tx_base_gas`,
56
+ // `SignedTx` is not a chargeable transaction type
57
+ .filter(tag => ![Tag.SignedTx, Tag.ContractCreateTx, Tag.ContractCallTx, Tag.GaAttachTx, Tag.GaMetaTx].includes(tag)).map(tag => [tag, BASE_GAS])),
58
+ [Tag.ChannelForceProgressTx]: 30 * BASE_GAS,
59
+ [Tag.ChannelOffChainTx]: 0,
60
+ [Tag.PayingForTx]: BASE_GAS / 5
61
+ },
62
+ contractTxBaseGas: {
63
+ [Tag.ContractCreateTx]: {
64
+ [AbiVersion.Sophia]: 5 * BASE_GAS,
65
+ [AbiVersion.Fate]: 5 * BASE_GAS
66
+ },
67
+ [Tag.ContractCallTx]: {
68
+ [AbiVersion.Sophia]: 12 * BASE_GAS,
69
+ [AbiVersion.Fate]: 12 * BASE_GAS
70
+ },
71
+ [Tag.GaAttachTx]: {
72
+ [AbiVersion.Sophia]: 5 * BASE_GAS,
73
+ [AbiVersion.Fate]: 5 * BASE_GAS
74
+ },
75
+ [Tag.GaMetaTx]: {
76
+ [AbiVersion.Sophia]: 5 * BASE_GAS,
77
+ [AbiVersion.Fate]: 5 * BASE_GAS
78
+ }
79
+ },
80
+ stateGasPerBlock: Object.fromEntries([Tag.OracleRegisterTx, Tag.OracleExtendTx, Tag.OracleQueryTx, Tag.OracleRespondTx].map(tag => [tag, {
81
+ ...defaultStateGasPerBlock
82
+ }]))
83
+ });
84
+
85
+ // node names transaction types after `aetx:type_to_swagger_name/1`, it matches `Tag` except of these
86
+ const txTypeToTag = {
87
+ GAAttachTx: Tag.GaAttachTx,
88
+ GAMetaTx: Tag.GaMetaTx
89
+ };
90
+ function getTag(txType) {
91
+ // node controls these keys, `isKeyOfObject` also accepts anything inherited from
92
+ // `Object.prototype` (`constructor`, `toString`) — a name of a transaction type is neither
93
+ const isOwnKeyOf = object => Object.prototype.hasOwnProperty.call(object, txType);
94
+ if (isOwnKeyOf(txTypeToTag) && isKeyOfObject(txType, txTypeToTag)) return txTypeToTag[txType];
95
+ if (!isOwnKeyOf(Tag) || !isKeyOfObject(txType, Tag)) return undefined;
96
+ // `Tag` is a numeric enum, so it is also indexable by a member value (`Tag['12'] === 'SpendTx'`)
97
+ const tag = Tag[txType];
98
+ return typeof tag === 'number' ? tag : undefined;
99
+ }
100
+
101
+ // Node decides these values and they multiply into the fee the user pays, so a node that is
102
+ // compromised, misconfigured, or impersonated could make the SDK build a transaction with an
103
+ // extreme fee. A hard fork may legitimately raise them, but not by orders of magnitude — refuse to
104
+ // build against a value far above the one the SDK was released with rather than silently overpay.
105
+ const maxRaiseFactor = 1000;
106
+ function excessiveError(name, value, limit) {
107
+ return new NodeError(`Node reports ${name} as ${String(value)}, which is outside of the range the SDK considers` + ` plausible (0..${limit}). Provide \`protocolParameters\` in options to build a transaction` + ' against these parameters anyway.');
108
+ }
109
+
110
+ /**
111
+ * A value that doesn't match the schema node declares for it — the api client passes `null`,
112
+ * booleans, strings, and fractions through unchanged. Not a {@link NodeError}: the parameters are
113
+ * unreadable rather than implausible, so {@link getCachedProtocolParameters} falls back to
114
+ * {@link defaultProtocolParameters}, as for a node without the endpoint (which a node can force
115
+ * with a 404 anyway).
116
+ */
117
+ function malformedError(name, value) {
118
+ return new InternalError(`Node reports ${name} as ${String(value)}, which doesn't match the schema it declares for it`);
119
+ }
120
+
121
+ /**
122
+ * Checks a value node reports against the one the SDK was released with, returns the factor it is
123
+ * raised by.
124
+ */
125
+ function checkNotExcessive(name, value, sdkValue) {
126
+ // a parameter the SDK release has at 0 can only stay at 0, it raises the fee by nothing
127
+ const raise = number => sdkValue === 0 ? 1 : number / sdkValue;
128
+ const limit = sdkValue * maxRaiseFactor;
129
+ // a bigint matches the schema whatever its magnitude, so one out of range is an implausible
130
+ // value rather than an unreadable one. Compared as a bigint: a value far enough above the limit
131
+ // can't be counted in a number, and that is what makes it implausible in the first place
132
+ if (typeof value === 'bigint') {
133
+ if (value < 0n || value > BigInt(limit)) throw excessiveError(name, value, limit);
134
+ return raise(Number(value));
135
+ }
136
+ if (!Number.isSafeInteger(value)) throw malformedError(name, value);
137
+ if (value < 0 || value > limit) throw excessiveError(name, value, limit);
138
+ return raise(value);
139
+ }
140
+
141
+ /**
142
+ * `Math.max(...array)` passes every element as an argument and overflows the stack on an array
143
+ * node can make arbitrarily long — it reports one entry per transaction type and abi version.
144
+ */
145
+ export function maxOf(numbers) {
146
+ return numbers.reduce((max, number) => number > max ? number : max, -Infinity);
147
+ }
148
+
149
+ // TODO: express the bound in aettos instead — a defaulted value may not commit the user to more
150
+ // than a fixed coin amount — rather than as a ratio against the parameters of the SDK release.
151
+ // That states the actual requirement directly and holds on any network, but it defaults a higher
152
+ // gas limit on a network that raised the block gas limit, so it is a behavior change, not a
153
+ // refactor [behavior change on networks running other parameters]
154
+ /**
155
+ * How much node's parameters raise each product a transaction costs, against the SDK release.
156
+ * Kept out of {@link ProtocolParameters} because they are not consensus parameters but a property
157
+ * of where the parameters came from — the ones a caller provides in options don't go through here.
158
+ *
159
+ * One per gas amount the SDK picks itself, and not one per parameter: each is charged to the value
160
+ * it bounds, so that a raise of one doesn't shrink a value it has nothing to do with.
161
+ */
162
+
163
+ const parameterRaises = new WeakMap();
164
+
165
+ // parameters this process built itself are checked where they are built — the ones of the SDK
166
+ // release by construction, the ones node reports by `checkParametersNotExcessive`. This remembers
167
+ // the caller-provided ones already walked, a build reads them once per field and per rebuild pass
168
+ const usableParameters = new WeakSet();
169
+ function checkUsableGas(name, value) {
170
+ if (!Number.isSafeInteger(value) || value < 0) {
171
+ throw new ArgumentError(`protocolParameters.${name}`, 'a non-negative safe integer', value);
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Checks that parameters a caller provided in options can price a transaction at all — only values
177
+ * that would produce `NaN`, `Infinity`, or a division by zero, not their magnitude: options are the
178
+ * way out of the bounds {@link convertProtocolParameters} applies, bounding them here would leave
179
+ * no way to build against a network the SDK release doesn't know. They are as trusted as `fee` and
180
+ * `gasLimit`: must not come from untrusted input, this only turns an unusable value into an error
181
+ * naming the field. See `serializeAsIsParam`.
182
+ * @param parameters - Parameters provided in options
183
+ */
184
+ export function checkParametersUsable(parameters) {
185
+ // built by this process, or already walked
186
+ if (parameterRaises.has(parameters) || usableParameters.has(parameters)) return;
187
+ if (typeof parameters.minGasPrice !== 'bigint' || parameters.minGasPrice < 1n) {
188
+ throw new ArgumentError('protocolParameters.minGasPrice', 'a positive bigint (a transaction can’t be priced against 0)', parameters.minGasPrice);
189
+ }
190
+ if (typeof parameters.minMinerGasPrice !== 'bigint' || parameters.minMinerGasPrice < 0n) {
191
+ throw new ArgumentError('protocolParameters.minMinerGasPrice', 'a non-negative bigint', parameters.minMinerGasPrice);
192
+ }
193
+ checkUsableGas('gasPerByte', parameters.gasPerByte);
194
+ checkUsableGas('blockGasLimit', parameters.blockGasLimit);
195
+ checkUsableGas('maxAuthFunGas', parameters.maxAuthFunGas);
196
+ Object.entries(parameters.txBaseGas).forEach(([tag, gas]) => {
197
+ var _Tag$tag;
198
+ return checkUsableGas(`txBaseGas.${(_Tag$tag = Tag[+tag]) !== null && _Tag$tag !== void 0 ? _Tag$tag : tag}`, gas);
199
+ });
200
+ Object.entries(parameters.contractTxBaseGas).forEach(([tag, byAbiVersion]) => Object.entries(byAbiVersion !== null && byAbiVersion !== void 0 ? byAbiVersion : {}).forEach(([abiVersion, gas]) => {
201
+ var _Tag$tag2;
202
+ return checkUsableGas(`contractTxBaseGas.${(_Tag$tag2 = Tag[+tag]) !== null && _Tag$tag2 !== void 0 ? _Tag$tag2 : tag}.${abiVersion}`, gas);
203
+ }));
204
+ Object.entries(parameters.stateGasPerBlock).forEach(([tag, fraction]) => {
205
+ var _Tag$tag3, _fraction$whole;
206
+ const name = `stateGasPerBlock.${(_Tag$tag3 = Tag[+tag]) !== null && _Tag$tag3 !== void 0 ? _Tag$tag3 : tag}`;
207
+ checkUsableGas(`${name}.part`, fraction?.part);
208
+ // a `whole` of 0 makes the state gas — and so the fee — infinite
209
+ if (!Number.isSafeInteger(fraction?.whole) || ((_fraction$whole = fraction?.whole) !== null && _fraction$whole !== void 0 ? _fraction$whole : 0) < 1) {
210
+ throw new ArgumentError(`${name}.whole`, 'a positive safe integer', fraction?.whole);
211
+ }
212
+ });
213
+ usableParameters.add(parameters);
214
+ }
215
+ function checkRatioNotExcessive(name, {
216
+ part,
217
+ whole
218
+ }, sdkRatio) {
219
+ if (!Number.isSafeInteger(part) || !Number.isSafeInteger(whole)) {
220
+ throw malformedError(name, `${String(part)}/${String(whole)}`);
221
+ }
222
+ const limit = sdkRatio * maxRaiseFactor;
223
+ // a `whole` of 0 would make the fee infinite, `0 / 0` is NaN — both fail the check below
224
+ const ratio = part >= 0 && whole > 0 ? part / whole : NaN;
225
+ if (!(ratio >= 0) || ratio > limit) throw excessiveError(name, `${part}/${whole}`, limit);
226
+ return ratio / sdkRatio;
227
+ }
228
+
229
+ /**
230
+ * The base gas the SDK release charges for a transaction type, whichever of the two tables it is
231
+ * in. `getTxBaseGas` reads `contractTxBaseGas` before `txBaseGas`, so an entry node adds to
232
+ * `contractTxBaseGas` overrides the `txBaseGas` of that very type — checking it against a
233
+ * type-independent constant would let node raise, say, a `PayingForTx` (3000) to 15000000 and
234
+ * still be counted as a raise of 1000.
235
+ */
236
+ function defaultBaseGasOf(tag) {
237
+ var _d$contractTxBaseGas$;
238
+ const d = defaultProtocolParameters;
239
+ const values = [d.txBaseGas[tag], ...Object.values((_d$contractTxBaseGas$ = d.contractTxBaseGas[tag]) !== null && _d$contractTxBaseGas$ !== void 0 ? _d$contractTxBaseGas$ : {})].filter(value => value != null);
240
+ const max = values.length !== 0 ? maxOf(values) : BASE_GAS;
241
+ // a type charged 0 (`ChannelOffChainTx`) would get a budget of 0, and node reporting any gas for
242
+ // it would refuse the whole response. Give it an ordinary type's budget instead — a node charging
243
+ // more than `maxRaiseFactor` base gas units for it is still refused
244
+ return max !== 0 ? max : BASE_GAS;
245
+ }
246
+ function checkRaiseNotExcessive(what, raise) {
247
+ if (raise <= maxRaiseFactor) return;
248
+ throw new NodeError(`Node reports parameters raising ${what} ${Math.round(raise)} times above the one of the SDK` + ` release, more than the ${maxRaiseFactor} times the SDK considers plausible. Provide` + ' `protocolParameters` in options to build a transaction against these parameters anyway.');
249
+ }
250
+
251
+ /**
252
+ * Refuses the parameters if node reports values far above the ones of the SDK release, and returns
253
+ * the factors the two products a transaction costs may be raised by — see {@link ParameterRaises}.
254
+ */
255
+ function checkParametersNotExcessive(parameters) {
256
+ const d = defaultProtocolParameters;
257
+ const defaultMinGasPrice = Number(d.minGasPrice);
258
+ // a gas price of 0 makes every fee 0 — the network would reject the transaction, and the
259
+ // `minFee / minGasPrice` of the demand-based fee is a division by zero
260
+ if (parameters.minGasPrice < 1n) {
261
+ throw new NodeError(`Node reports the minimum gas price as ${parameters.minGasPrice}, a transaction can't be` + ' priced against it. Provide `protocolParameters` in options to build a transaction' + ' against these parameters anyway.');
262
+ }
263
+ // both raise the gas price the fee is counted from: the consensus minimum directly, the miner
264
+ // minimum as the floor `getCachedIncreasedGasPrice` lifts the gas price to. Bounding the miner
265
+ // minimum on its own — as this used to — leaves node the product of the two to raise the fee by.
266
+ const gasPriceRaise = maxOf([checkNotExcessive('the minimum gas price', parameters.minGasPrice, defaultMinGasPrice), checkNotExcessive('the miner minimum gas price', parameters.minMinerGasPrice, defaultMinGasPrice)]);
267
+
268
+ // every one of these is a gas amount the fee is counted from, the biggest raise among them is
269
+ // the most a transaction's gas can grow by
270
+ const gasRaises = [checkNotExcessive('the gas per byte', parameters.gasPerByte, d.gasPerByte)];
271
+ Object.entries(parameters.txBaseGas).forEach(([tag, gas]) => {
272
+ // against the default of this very type and not against the biggest default of all types: a
273
+ // `ChannelForceProgressTx` costs 30 times a `SpendTx`, that is not a budget for a `SpendTx`
274
+ gasRaises.push(checkNotExcessive(`the base gas of ${Tag[+tag]}`, gas, defaultBaseGasOf(+tag)));
275
+ });
276
+ Object.entries(parameters.contractTxBaseGas).forEach(([tag, byAbiVersion]) => {
277
+ const sdkValue = defaultBaseGasOf(+tag);
278
+ Object.entries(byAbiVersion).forEach(([abiVersion, gas]) => {
279
+ const name = `the base gas of ${Tag[+tag]} at abi version ${abiVersion}`;
280
+ gasRaises.push(checkNotExcessive(name, gas, sdkValue));
281
+ });
282
+ });
283
+ const defaultStateGasRatio = defaultStateGasPerBlock.part / defaultStateGasPerBlock.whole;
284
+ Object.entries(parameters.stateGasPerBlock).forEach(([tag, fraction]) => {
285
+ const name = `the state gas per block of ${Tag[+tag]}`;
286
+ gasRaises.push(checkRatioNotExcessive(name, fraction, defaultStateGasRatio));
287
+ });
288
+
289
+ // the minimum fee is `gasPrice * (baseGas + size * gasPerByte + stateGas)`, so each product is
290
+ // bounded rather than each parameter — otherwise node could combine them into a fee
291
+ // `maxRaiseFactor` squared above the one of the SDK release
292
+ const feeGasRaise = maxOf(gasRaises);
293
+ checkRaiseNotExcessive('the minimum transaction fee', gasPriceRaise * feeGasRaise);
294
+
295
+ // the two bound different transaction types, but both are a gas limit multiplied by the same
296
+ // gas price — the bigger of them is what the worst case costs
297
+ const blockGasLimitRaise = checkNotExcessive('the block gas limit', parameters.blockGasLimit, d.blockGasLimit);
298
+ const maxAuthFunGasRaise = checkNotExcessive('the max auth fun gas', parameters.maxAuthFunGas, d.maxAuthFunGas);
299
+ const gasLimitRaise = maxOf([blockGasLimitRaise, maxAuthFunGasRaise]);
300
+ checkRaiseNotExcessive('the cost of a contract transaction', gasPriceRaise * gasLimitRaise);
301
+
302
+ // the gas above is multiplied by a gas price that doesn't come from these parameters, and that
303
+ // is bounded on its own — so the raises are reported to lower those bounds by the same factors,
304
+ // see `getGasPriceDivisor` and `getGasLimitDivisor`
305
+ return {
306
+ fee: maxOf([1, feeGasRaise]),
307
+ blockGasLimit: maxOf([1, blockGasLimitRaise]),
308
+ maxAuthFunGas: maxOf([1, maxAuthFunGasRaise])
309
+ };
310
+ }
311
+
312
+ /**
313
+ * Factor the gas price ceiling of `gas-price.ts` is lowered by, so that the worst case fee doesn't
314
+ * become the product of that ceiling and the fee gas bound of {@link convertProtocolParameters}.
315
+ * The gas limit raise is charged to the gas limit default instead ({@link getGasLimitDivisor}).
316
+ * It is 1 unless the parameters came from node.
317
+ *
318
+ * The biggest raise among all transaction types, not the one of the type being built — so a node
319
+ * repricing one type lowers the ceiling for every type. The ceiling is 100000 times the minimum
320
+ * gas price, far above the demand-based price this bounds in practice.
321
+ * @param parameters - Parameters a transaction is built against
322
+ */
323
+ export function getGasPriceDivisor(parameters) {
324
+ var _parameterRaises$get$;
325
+ return (_parameterRaises$get$ = parameterRaises.get(parameters)?.fee) !== null && _parameterRaises$get$ !== void 0 ? _parameterRaises$get$ : 1;
326
+ }
327
+
328
+ /**
329
+ * The cost of a contract transaction is `gasPrice * gasLimit`, and the gas limit the SDK defaults
330
+ * to comes from `blockGasLimit` — from `maxAuthFunGas` on a `GaMetaTx`. This is the factor node
331
+ * raises the one `tag` reads by, so that lowering the default by it keeps the product within the
332
+ * one of the SDK release. It is 1 unless the parameters came from node.
333
+ *
334
+ * Only the limit `tag` reads: charging the other one would shrink a gas limit because node raised
335
+ * something that transaction never reads. The fee gas raise is charged to the gas price ceiling
336
+ * ({@link getGasPriceDivisor}) instead.
337
+ * @param parameters - Parameters a transaction is built against
338
+ * @param tag - Type of the transaction the gas limit is defaulted for
339
+ */
340
+ export function getGasLimitDivisor(parameters, tag) {
341
+ const raises = parameterRaises.get(parameters);
342
+ if (raises == null) return 1;
343
+ return tag === Tag.GaMetaTx ? raises.maxAuthFunGas : raises.blockGasLimit;
344
+ }
345
+ function mapByTxType(entries, map) {
346
+ return Object.fromEntries(entries.map(([txType, value]) => [getTag(txType), map(value)])
347
+ // a transaction type the SDK doesn't implement, or won't ever build (`ChannelClientReconnectTx`)
348
+ .filter(entry => entry[0] != null));
349
+ }
350
+
351
+ /**
352
+ * Converts the node responses to the shape the transaction builder uses, rejecting values far
353
+ * above the ones the SDK was released with. Not a part of the public api, it is exported for
354
+ * tests — use {@link getCachedProtocolParameters}.
355
+ * @param response - Response of the `/v3/protocol-parameters` endpoint
356
+ * @param nodeSettings - Response of the `/v3/node-settings` endpoint
357
+ */
358
+ export function convertProtocolParameters(response, nodeSettings) {
359
+ const {
360
+ currentProtocolVersion,
361
+ protocols
362
+ } = response;
363
+ const protocol = protocols.find(({
364
+ version
365
+ }) => version === currentProtocolVersion);
366
+ if (protocol == null) {
367
+ throw new InternalError(`Node doesn't provide parameters of the current protocol ${currentProtocolVersion}`);
368
+ }
369
+
370
+ // starts from the values of the SDK release so that a type or an abi version node doesn't report
371
+ // keeps building against them, as the SDK did before this endpoint existed, instead of failing
372
+ const contractTxBaseGas = Object.fromEntries(Object.entries(defaultProtocolParameters.contractTxBaseGas).map(([tag, byAbiVersion]) => [tag, {
373
+ ...byAbiVersion
374
+ }]));
375
+ protocol.contractTxBaseGas.forEach(({
376
+ txType,
377
+ abiVersion,
378
+ txBaseGas
379
+ }) => {
380
+ var _contractTxBaseGas$ta;
381
+ const tag = getTag(txType);
382
+ // node controls `abiVersion` and the api client passes a value that doesn't match the schema
383
+ // node declares for it through unchanged. A `__proto__` key would be written into the
384
+ // prototype: invisible to the `Object.values` of the check below, and still returned by the
385
+ // `byAbiVersion[abiVersion]` lookup the fee is calculated from
386
+ if (tag == null || !Number.isInteger(abiVersion)) return;
387
+ const byAbiVersion = (_contractTxBaseGas$ta = contractTxBaseGas[tag]) !== null && _contractTxBaseGas$ta !== void 0 ? _contractTxBaseGas$ta : contractTxBaseGas[tag] = {};
388
+ byAbiVersion[abiVersion] = txBaseGas;
389
+ });
390
+ const reportedTxBaseGas = mapByTxType(Object.entries(protocol.txBaseGas), gas => gas);
391
+ const parameters = freezeParameters({
392
+ minGasPrice: protocol.minimumGasPrice,
393
+ minMinerGasPrice: nodeSettings.minMinerGasPrice,
394
+ gasPerByte: protocol.gasPerByte,
395
+ blockGasLimit: nodeSettings.blockGasLimit,
396
+ maxAuthFunGas: nodeSettings.maxAuthFunGas,
397
+ txBaseGas: {
398
+ // see the note on `contractTxBaseGas` above
399
+ ...defaultProtocolParameters.txBaseGas,
400
+ ...reportedTxBaseGas
401
+ },
402
+ contractTxBaseGas,
403
+ stateGasPerBlock: {
404
+ // see the note on `contractTxBaseGas` above
405
+ ...defaultProtocolParameters.stateGasPerBlock,
406
+ ...mapByTxType(Object.entries(protocol.stateGasPerBlock), fraction => ({
407
+ part: fraction.part,
408
+ whole: fraction.whole
409
+ }))
410
+ }
411
+ });
412
+ parameterRaises.set(parameters, checkParametersNotExcessive(parameters));
413
+ return parameters;
414
+ }
415
+ const cache = new WeakMap();
416
+ // protocol parameters change on a hard fork, or when the node operator edits the node config,
417
+ // neither happens often enough to justify a request per transaction built
418
+ const cacheTtl = 10 * 60 * 1000;
419
+ // a node that can't be reached, or that reports parameters the SDK refuses to build against, may
420
+ // be reachable or reconfigured in a moment — don't keep the whole `cacheTtl` worth of transactions
421
+ // building against the parameters of the SDK release, or failing, because of one bad response.
422
+ // Still cached rather than retried per transaction: both outcomes cost a round trip to reproduce.
423
+ const transientCacheTtl = 30 * 1000;
424
+
425
+ /**
426
+ * Requests protocol parameters from node, the result is cached per node instance.
427
+ *
428
+ * Falls back to {@link defaultProtocolParameters} for a node that doesn't provide the endpoints,
429
+ * can't be reached, or answers something this SDK release can't read. Rejects only when node
430
+ * reports parameters that would price a transaction far above the SDK release — see
431
+ * {@link ProtocolParametersOption} for the way out of that.
432
+ *
433
+ * The cache is keyed by the `Node` object, so code that constructs a `Node` per request (a
434
+ * serverless handler, an edge worker) requests the parameters again for each one. Keep one `Node`
435
+ * instance per endpoint to get the benefit of the cache.
436
+ * @category transaction builder
437
+ * @param nodeOrProxy - Node to request the parameters from
438
+ */
439
+ export async function getCachedProtocolParameters(nodeOrProxy) {
440
+ const node = unwrapProxy(nodeOrProxy);
441
+ const entry = cache.get(node);
442
+ if (entry != null && entry.expiresAt > Date.now()) return entry.parameters;
443
+
444
+ // node is expected to respond with 404 until it gets the endpoints, and a node whose operator
445
+ // disabled the `node_info`/`node_settings` endpoint groups with 403 — neither changes within
446
+ // `cacheTtl`, while anything else is worth asking again about sooner
447
+ let ttl = cacheTtl;
448
+ // the request and the conversion both run in here so that only a deliberate refusal — a
449
+ // `NodeError` on implausible parameters — comes out as a rejection; anything unreadable falls
450
+ // back to the parameters of the SDK release instead of making every transaction unbuildable
451
+ const parameters = (async () => {
452
+ const fallBack = reason => {
453
+ ttl = transientCacheTtl;
454
+ console.warn("Can't get protocol parameters from node, using the ones of the SDK release instead." + ' A transaction may be rejected if this node runs other parameters.' + ` Reason: ${reason instanceof Error ? reason.message : String(reason)}`);
455
+ return defaultProtocolParameters;
456
+ };
457
+
458
+ // a node object without the methods (a test double, another SDK copy's `Node`) won't grow
459
+ // them within `transientCacheTtl` — treat like the 404 of an old node: full-interval cache,
460
+ // and no warning per 30 seconds for the life of the process
461
+ if (typeof node.getProtocolParameters !== 'function' || typeof node.getNodeSettings !== 'function') {
462
+ return defaultProtocolParameters;
463
+ }
464
+
465
+ // retrying the 404 on every transaction built would only add latency
466
+ const noRetry = {
467
+ requestOptions: {
468
+ customHeaders: {
469
+ '__no-retry': 'true'
470
+ }
471
+ }
472
+ };
473
+ let response;
474
+ let nodeSettings;
475
+ try {
476
+ // consensus parameters and this node's own policy are two endpoints, and a transaction is
477
+ // priced by both — requested together so that a build waits for one round trip and not two,
478
+ // and taken as a set: parameters half from node and half from the SDK release would be
479
+ // neither ones node accepts nor ones the SDK was tested against
480
+ [response, nodeSettings] = await Promise.all([node.getProtocolParameters(noRetry), node.getNodeSettings(noRetry)]);
481
+ } catch (error) {
482
+ // the 404/403 of the note above — neither is worth a warning, or an earlier retry.
483
+ // Read off the error rather than through `instanceof RestError`: that would import
484
+ // `@azure/core-rest-pipeline` as a value into the transaction builder, which is otherwise
485
+ // free of it, and pull the http stack into the bundle of an application that only packs
486
+ // transactions. The api client is the only thing that rejects here, and it sets this
487
+ const {
488
+ statusCode
489
+ } = error;
490
+ if (statusCode === 404 || statusCode === 403) return defaultProtocolParameters;
491
+ // node is syncing (503), a proxy in between is down, the request timed out
492
+ return fallBack(error);
493
+ }
494
+ try {
495
+ return convertProtocolParameters(response, nodeSettings);
496
+ } catch (error) {
497
+ // node reports parameters that would price a transaction far above the SDK release — falling
498
+ // back would build a transaction this node rejects, so the caller is told to decide instead
499
+ if (error instanceof NodeError) throw error;
500
+ return fallBack(error);
501
+ }
502
+ })();
503
+
504
+ // until it settles the entry keeps concurrent builds on this one request
505
+ const cacheEntry = {
506
+ expiresAt: Date.now() + cacheTtl,
507
+ parameters
508
+ };
509
+ parameters.then(() => {
510
+ cacheEntry.expiresAt = Date.now() + ttl;
511
+ },
512
+ // see `transientCacheTtl`
513
+ () => {
514
+ cacheEntry.expiresAt = Date.now() + transientCacheTtl;
515
+ });
516
+ cache.set(node, cacheEntry);
517
+ return parameters;
518
+ }
519
+ //# sourceMappingURL=protocol-parameters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol-parameters.js","names":["AbiVersion","MAX_AUTH_FUN_GAS","MIN_GAS_PRICE","Tag","isKeyOfObject","ArgumentError","InternalError","NodeError","unwrapProxy","BASE_GAS","defaultStateGasPerBlock","part","whole","Math","floor","freezeParameters","parameters","Object","values","contractTxBaseGas","forEach","freeze","stateGasPerBlock","txBaseGas","defaultProtocolParameters","minGasPrice","BigInt","minMinerGasPrice","gasPerByte","blockGasLimit","maxAuthFunGas","fromEntries","filter","tag","SignedTx","ContractCreateTx","ContractCallTx","GaAttachTx","GaMetaTx","includes","map","ChannelForceProgressTx","ChannelOffChainTx","PayingForTx","Sophia","Fate","OracleRegisterTx","OracleExtendTx","OracleQueryTx","OracleRespondTx","txTypeToTag","GAAttachTx","GAMetaTx","getTag","txType","isOwnKeyOf","object","prototype","hasOwnProperty","call","undefined","maxRaiseFactor","excessiveError","name","value","limit","String","malformedError","checkNotExcessive","sdkValue","raise","number","Number","isSafeInteger","maxOf","numbers","reduce","max","Infinity","parameterRaises","WeakMap","usableParameters","WeakSet","checkUsableGas","checkParametersUsable","has","entries","gas","_Tag$tag","byAbiVersion","abiVersion","_Tag$tag2","fraction","_Tag$tag3","_fraction$whole","add","checkRatioNotExcessive","sdkRatio","ratio","NaN","defaultBaseGasOf","_d$contractTxBaseGas$","d","length","checkRaiseNotExcessive","what","round","checkParametersNotExcessive","defaultMinGasPrice","gasPriceRaise","gasRaises","push","defaultStateGasRatio","feeGasRaise","blockGasLimitRaise","maxAuthFunGasRaise","gasLimitRaise","fee","getGasPriceDivisor","_parameterRaises$get$","get","getGasLimitDivisor","raises","mapByTxType","entry","convertProtocolParameters","response","nodeSettings","currentProtocolVersion","protocols","protocol","find","version","_contractTxBaseGas$ta","isInteger","reportedTxBaseGas","minimumGasPrice","set","cache","cacheTtl","transientCacheTtl","getCachedProtocolParameters","nodeOrProxy","node","expiresAt","Date","now","ttl","fallBack","reason","console","warn","Error","message","getProtocolParameters","getNodeSettings","noRetry","requestOptions","customHeaders","Promise","all","error","statusCode","cacheEntry","then"],"sources":["../../../src/tx/builder/protocol-parameters.ts"],"sourcesContent":["import { AbiVersion, MAX_AUTH_FUN_GAS, MIN_GAS_PRICE, Tag } from './constants.js';\nimport { isKeyOfObject } from '../../utils/other.js';\nimport { ArgumentError, InternalError, NodeError } from '../../utils/errors.js';\nimport { unwrapProxy } from '../../utils/wrap-proxy.js';\nimport type Node from '../../Node.js';\n\n/**\n * Consensus parameters and node policy settings the transaction builder needs to produce a\n * transaction the node would accept — see {@link getCachedProtocolParameters}.\n * @category transaction builder\n */\nexport interface ProtocolParameters {\n /**\n * Consensus minimum gas price in aettos, the minimum transaction fee is the transaction's fee\n * gas multiplied by this value\n */\n readonly minGasPrice: bigint;\n /**\n * Minimum gas price accepted by the miner of the node the SDK is connected to. A transaction\n * below it is still valid, but this node won't mine it.\n */\n readonly minMinerGasPrice: bigint;\n /** Gas per serialized transaction byte counted into the minimum fee */\n readonly gasPerByte: number;\n /**\n * Maximum total gas the node the SDK is connected to accepts in a single micro block. Node\n * policy rather than a consensus parameter, it may differ between nodes.\n */\n readonly blockGasLimit: number;\n /**\n * Maximum gas accepted for a generalized account authentication function by the node the SDK is\n * connected to. Node policy rather than a consensus parameter, it may differ between nodes.\n */\n readonly maxAuthFunGas: number;\n /** Base fee gas by transaction type, transactions not executing contract code */\n readonly txBaseGas: Readonly<Partial<Record<Tag, number>>>;\n /** Base fee gas of contract-executing transaction types, by ABI version */\n readonly contractTxBaseGas: Readonly<\n Partial<Record<Tag, Readonly<Partial<Record<AbiVersion, number>>>>>\n >;\n /**\n * State rent gas fraction per key block by transaction type,\n * state gas is `ceil(relativeTtl * part / whole)`\n */\n readonly stateGasPerBlock: Readonly<\n Partial<Record<Tag, Readonly<{ part: number; whole: number }>>>\n >;\n}\n\n/**\n * Transaction option to build a transaction against specific consensus parameters. `buildTxAsync`\n * sets it to the parameters it requests from node, provide it to build a transaction offline for a\n * node that doesn't run the protocol version the current SDK release was made for.\n * @category transaction builder\n */\nexport interface ProtocolParametersOption {\n protocolParameters?: ProtocolParameters;\n}\n\nconst BASE_GAS = 15000;\nconst defaultStateGasPerBlock = { part: 32000, whole: Math.floor((60 * 24 * 365) / 3) };\n\n/**\n * Protocol parameters are shared between every transaction built against them, and\n * {@link defaultProtocolParameters} is shared process-wide. `readonly` guards them at compile time\n * only, so freeze them to make sure a transaction can't be mispriced by an unrelated component\n * mutating parameters it doesn't own.\n */\nfunction freezeParameters(parameters: ProtocolParameters): ProtocolParameters {\n Object.values(parameters.contractTxBaseGas).forEach(Object.freeze);\n Object.values(parameters.stateGasPerBlock).forEach(Object.freeze);\n Object.freeze(parameters.txBaseGas);\n Object.freeze(parameters.contractTxBaseGas);\n Object.freeze(parameters.stateGasPerBlock);\n return Object.freeze(parameters);\n}\n\n/**\n * Protocol parameters of Ceres as they were at the moment of the SDK release. Used to build\n * transactions without a node connection, and on nodes that don't provide the protocol parameters\n * endpoint yet.\n * @category transaction builder\n * @see {@link https://github.com/aeternity/protocol/blob/master/consensus/README.md#gas}\n */\nexport const defaultProtocolParameters: ProtocolParameters = freezeParameters({\n minGasPrice: BigInt(MIN_GAS_PRICE),\n minMinerGasPrice: BigInt(MIN_GAS_PRICE),\n gasPerByte: 20,\n blockGasLimit: 6e6,\n maxAuthFunGas: MAX_AUTH_FUN_GAS,\n txBaseGas: {\n ...Object.fromEntries(\n Object.values(Tag)\n .filter((tag): tag is Tag => typeof tag === 'number')\n // node reports the base gas of contract-executing types in `contract_tx_base_gas`,\n // `SignedTx` is not a chargeable transaction type\n .filter(\n (tag) =>\n ![\n Tag.SignedTx,\n Tag.ContractCreateTx,\n Tag.ContractCallTx,\n Tag.GaAttachTx,\n Tag.GaMetaTx,\n ].includes(tag),\n )\n .map((tag) => [tag, BASE_GAS]),\n ),\n [Tag.ChannelForceProgressTx]: 30 * BASE_GAS,\n [Tag.ChannelOffChainTx]: 0,\n [Tag.PayingForTx]: BASE_GAS / 5,\n },\n contractTxBaseGas: {\n [Tag.ContractCreateTx]: { [AbiVersion.Sophia]: 5 * BASE_GAS, [AbiVersion.Fate]: 5 * BASE_GAS },\n [Tag.ContractCallTx]: { [AbiVersion.Sophia]: 12 * BASE_GAS, [AbiVersion.Fate]: 12 * BASE_GAS },\n [Tag.GaAttachTx]: { [AbiVersion.Sophia]: 5 * BASE_GAS, [AbiVersion.Fate]: 5 * BASE_GAS },\n [Tag.GaMetaTx]: { [AbiVersion.Sophia]: 5 * BASE_GAS, [AbiVersion.Fate]: 5 * BASE_GAS },\n },\n stateGasPerBlock: Object.fromEntries(\n [Tag.OracleRegisterTx, Tag.OracleExtendTx, Tag.OracleQueryTx, Tag.OracleRespondTx].map(\n (tag) => [tag, { ...defaultStateGasPerBlock }],\n ),\n ),\n});\n\n// node names transaction types after `aetx:type_to_swagger_name/1`, it matches `Tag` except of these\nconst txTypeToTag = {\n GAAttachTx: Tag.GaAttachTx,\n GAMetaTx: Tag.GaMetaTx,\n} as const;\n\nfunction getTag(txType: string): Tag | undefined {\n // node controls these keys, `isKeyOfObject` also accepts anything inherited from\n // `Object.prototype` (`constructor`, `toString`) — a name of a transaction type is neither\n const isOwnKeyOf = (object: object): boolean =>\n Object.prototype.hasOwnProperty.call(object, txType);\n if (isOwnKeyOf(txTypeToTag) && isKeyOfObject(txType, txTypeToTag)) return txTypeToTag[txType];\n if (!isOwnKeyOf(Tag) || !isKeyOfObject(txType, Tag)) return undefined;\n // `Tag` is a numeric enum, so it is also indexable by a member value (`Tag['12'] === 'SpendTx'`)\n const tag = Tag[txType];\n return typeof tag === 'number' ? tag : undefined;\n}\n\n// Node decides these values and they multiply into the fee the user pays, so a node that is\n// compromised, misconfigured, or impersonated could make the SDK build a transaction with an\n// extreme fee. A hard fork may legitimately raise them, but not by orders of magnitude — refuse to\n// build against a value far above the one the SDK was released with rather than silently overpay.\nconst maxRaiseFactor = 1000;\n\nfunction excessiveError(name: string, value: unknown, limit: number): NodeError {\n return new NodeError(\n `Node reports ${name} as ${String(value)}, which is outside of the range the SDK considers` +\n ` plausible (0..${limit}). Provide \\`protocolParameters\\` in options to build a transaction` +\n ' against these parameters anyway.',\n );\n}\n\n/**\n * A value that doesn't match the schema node declares for it — the api client passes `null`,\n * booleans, strings, and fractions through unchanged. Not a {@link NodeError}: the parameters are\n * unreadable rather than implausible, so {@link getCachedProtocolParameters} falls back to\n * {@link defaultProtocolParameters}, as for a node without the endpoint (which a node can force\n * with a 404 anyway).\n */\nfunction malformedError(name: string, value: unknown): InternalError {\n return new InternalError(\n `Node reports ${name} as ${String(value)}, which doesn't match the schema it declares for it`,\n );\n}\n\n/**\n * Checks a value node reports against the one the SDK was released with, returns the factor it is\n * raised by.\n */\nfunction checkNotExcessive(name: string, value: number | bigint, sdkValue: number): number {\n // a parameter the SDK release has at 0 can only stay at 0, it raises the fee by nothing\n const raise = (number: number): number => (sdkValue === 0 ? 1 : number / sdkValue);\n const limit = sdkValue * maxRaiseFactor;\n // a bigint matches the schema whatever its magnitude, so one out of range is an implausible\n // value rather than an unreadable one. Compared as a bigint: a value far enough above the limit\n // can't be counted in a number, and that is what makes it implausible in the first place\n if (typeof value === 'bigint') {\n if (value < 0n || value > BigInt(limit)) throw excessiveError(name, value, limit);\n return raise(Number(value));\n }\n if (!Number.isSafeInteger(value)) throw malformedError(name, value);\n if (value < 0 || value > limit) throw excessiveError(name, value, limit);\n return raise(value);\n}\n\n/**\n * `Math.max(...array)` passes every element as an argument and overflows the stack on an array\n * node can make arbitrarily long — it reports one entry per transaction type and abi version.\n */\nexport function maxOf(numbers: number[]): number {\n return numbers.reduce((max, number) => (number > max ? number : max), -Infinity);\n}\n\n// TODO: express the bound in aettos instead — a defaulted value may not commit the user to more\n// than a fixed coin amount — rather than as a ratio against the parameters of the SDK release.\n// That states the actual requirement directly and holds on any network, but it defaults a higher\n// gas limit on a network that raised the block gas limit, so it is a behavior change, not a\n// refactor [behavior change on networks running other parameters]\n/**\n * How much node's parameters raise each product a transaction costs, against the SDK release.\n * Kept out of {@link ProtocolParameters} because they are not consensus parameters but a property\n * of where the parameters came from — the ones a caller provides in options don't go through here.\n *\n * One per gas amount the SDK picks itself, and not one per parameter: each is charged to the value\n * it bounds, so that a raise of one doesn't shrink a value it has nothing to do with.\n */\ninterface ParameterRaises {\n /** Of the gas the minimum fee is counted from: `gasPerByte`, the base gas, the state gas */\n readonly fee: number;\n /** Of the gas limit a contract transaction defaults to */\n readonly blockGasLimit: number;\n /** Of the gas limit a `GaMetaTx` defaults to */\n readonly maxAuthFunGas: number;\n}\nconst parameterRaises: WeakMap<ProtocolParameters, ParameterRaises> = new WeakMap();\n\n// parameters this process built itself are checked where they are built — the ones of the SDK\n// release by construction, the ones node reports by `checkParametersNotExcessive`. This remembers\n// the caller-provided ones already walked, a build reads them once per field and per rebuild pass\nconst usableParameters: WeakSet<ProtocolParameters> = new WeakSet();\n\nfunction checkUsableGas(name: string, value: unknown): void {\n if (!Number.isSafeInteger(value) || (value as number) < 0) {\n throw new ArgumentError(`protocolParameters.${name}`, 'a non-negative safe integer', value);\n }\n}\n\n/**\n * Checks that parameters a caller provided in options can price a transaction at all — only values\n * that would produce `NaN`, `Infinity`, or a division by zero, not their magnitude: options are the\n * way out of the bounds {@link convertProtocolParameters} applies, bounding them here would leave\n * no way to build against a network the SDK release doesn't know. They are as trusted as `fee` and\n * `gasLimit`: must not come from untrusted input, this only turns an unusable value into an error\n * naming the field. See `serializeAsIsParam`.\n * @param parameters - Parameters provided in options\n */\nexport function checkParametersUsable(parameters: ProtocolParameters): void {\n // built by this process, or already walked\n if (parameterRaises.has(parameters) || usableParameters.has(parameters)) return;\n\n if (typeof parameters.minGasPrice !== 'bigint' || parameters.minGasPrice < 1n) {\n throw new ArgumentError(\n 'protocolParameters.minGasPrice',\n 'a positive bigint (a transaction can’t be priced against 0)',\n parameters.minGasPrice,\n );\n }\n if (typeof parameters.minMinerGasPrice !== 'bigint' || parameters.minMinerGasPrice < 0n) {\n throw new ArgumentError(\n 'protocolParameters.minMinerGasPrice',\n 'a non-negative bigint',\n parameters.minMinerGasPrice,\n );\n }\n checkUsableGas('gasPerByte', parameters.gasPerByte);\n checkUsableGas('blockGasLimit', parameters.blockGasLimit);\n checkUsableGas('maxAuthFunGas', parameters.maxAuthFunGas);\n Object.entries(parameters.txBaseGas).forEach(([tag, gas]) =>\n checkUsableGas(`txBaseGas.${Tag[+tag] ?? tag}`, gas),\n );\n Object.entries(parameters.contractTxBaseGas).forEach(([tag, byAbiVersion]) =>\n Object.entries(byAbiVersion ?? {}).forEach(([abiVersion, gas]) =>\n checkUsableGas(`contractTxBaseGas.${Tag[+tag] ?? tag}.${abiVersion}`, gas),\n ),\n );\n Object.entries(parameters.stateGasPerBlock).forEach(([tag, fraction]) => {\n const name = `stateGasPerBlock.${Tag[+tag] ?? tag}`;\n checkUsableGas(`${name}.part`, fraction?.part);\n // a `whole` of 0 makes the state gas — and so the fee — infinite\n if (!Number.isSafeInteger(fraction?.whole) || (fraction?.whole ?? 0) < 1) {\n throw new ArgumentError(`${name}.whole`, 'a positive safe integer', fraction?.whole);\n }\n });\n\n usableParameters.add(parameters);\n}\n\nfunction checkRatioNotExcessive(\n name: string,\n { part, whole }: { part: number; whole: number },\n sdkRatio: number,\n): number {\n if (!Number.isSafeInteger(part) || !Number.isSafeInteger(whole)) {\n throw malformedError(name, `${String(part)}/${String(whole)}`);\n }\n const limit = sdkRatio * maxRaiseFactor;\n // a `whole` of 0 would make the fee infinite, `0 / 0` is NaN — both fail the check below\n const ratio = part >= 0 && whole > 0 ? part / whole : NaN;\n if (!(ratio >= 0) || ratio > limit) throw excessiveError(name, `${part}/${whole}`, limit);\n return ratio / sdkRatio;\n}\n\n/**\n * The base gas the SDK release charges for a transaction type, whichever of the two tables it is\n * in. `getTxBaseGas` reads `contractTxBaseGas` before `txBaseGas`, so an entry node adds to\n * `contractTxBaseGas` overrides the `txBaseGas` of that very type — checking it against a\n * type-independent constant would let node raise, say, a `PayingForTx` (3000) to 15000000 and\n * still be counted as a raise of 1000.\n */\nfunction defaultBaseGasOf(tag: Tag): number {\n const d = defaultProtocolParameters;\n const values = [d.txBaseGas[tag], ...Object.values(d.contractTxBaseGas[tag] ?? {})].filter(\n (value): value is number => value != null,\n );\n const max = values.length !== 0 ? maxOf(values) : BASE_GAS;\n // a type charged 0 (`ChannelOffChainTx`) would get a budget of 0, and node reporting any gas for\n // it would refuse the whole response. Give it an ordinary type's budget instead — a node charging\n // more than `maxRaiseFactor` base gas units for it is still refused\n return max !== 0 ? max : BASE_GAS;\n}\n\nfunction checkRaiseNotExcessive(what: string, raise: number): void {\n if (raise <= maxRaiseFactor) return;\n throw new NodeError(\n `Node reports parameters raising ${what} ${Math.round(raise)} times above the one of the SDK` +\n ` release, more than the ${maxRaiseFactor} times the SDK considers plausible. Provide` +\n ' `protocolParameters` in options to build a transaction against these parameters anyway.',\n );\n}\n\n/**\n * Refuses the parameters if node reports values far above the ones of the SDK release, and returns\n * the factors the two products a transaction costs may be raised by — see {@link ParameterRaises}.\n */\nfunction checkParametersNotExcessive(parameters: ProtocolParameters): ParameterRaises {\n const d = defaultProtocolParameters;\n const defaultMinGasPrice = Number(d.minGasPrice);\n // a gas price of 0 makes every fee 0 — the network would reject the transaction, and the\n // `minFee / minGasPrice` of the demand-based fee is a division by zero\n if (parameters.minGasPrice < 1n) {\n throw new NodeError(\n `Node reports the minimum gas price as ${parameters.minGasPrice}, a transaction can't be` +\n ' priced against it. Provide `protocolParameters` in options to build a transaction' +\n ' against these parameters anyway.',\n );\n }\n // both raise the gas price the fee is counted from: the consensus minimum directly, the miner\n // minimum as the floor `getCachedIncreasedGasPrice` lifts the gas price to. Bounding the miner\n // minimum on its own — as this used to — leaves node the product of the two to raise the fee by.\n const gasPriceRaise = maxOf([\n checkNotExcessive('the minimum gas price', parameters.minGasPrice, defaultMinGasPrice),\n checkNotExcessive(\n 'the miner minimum gas price',\n parameters.minMinerGasPrice,\n defaultMinGasPrice,\n ),\n ]);\n\n // every one of these is a gas amount the fee is counted from, the biggest raise among them is\n // the most a transaction's gas can grow by\n const gasRaises = [checkNotExcessive('the gas per byte', parameters.gasPerByte, d.gasPerByte)];\n Object.entries(parameters.txBaseGas).forEach(([tag, gas]) => {\n // against the default of this very type and not against the biggest default of all types: a\n // `ChannelForceProgressTx` costs 30 times a `SpendTx`, that is not a budget for a `SpendTx`\n gasRaises.push(checkNotExcessive(`the base gas of ${Tag[+tag]}`, gas, defaultBaseGasOf(+tag)));\n });\n Object.entries(parameters.contractTxBaseGas).forEach(([tag, byAbiVersion]) => {\n const sdkValue = defaultBaseGasOf(+tag);\n Object.entries(byAbiVersion).forEach(([abiVersion, gas]) => {\n const name = `the base gas of ${Tag[+tag]} at abi version ${abiVersion}`;\n gasRaises.push(checkNotExcessive(name, gas, sdkValue));\n });\n });\n const defaultStateGasRatio = defaultStateGasPerBlock.part / defaultStateGasPerBlock.whole;\n Object.entries(parameters.stateGasPerBlock).forEach(([tag, fraction]) => {\n const name = `the state gas per block of ${Tag[+tag]}`;\n gasRaises.push(checkRatioNotExcessive(name, fraction, defaultStateGasRatio));\n });\n\n // the minimum fee is `gasPrice * (baseGas + size * gasPerByte + stateGas)`, so each product is\n // bounded rather than each parameter — otherwise node could combine them into a fee\n // `maxRaiseFactor` squared above the one of the SDK release\n const feeGasRaise = maxOf(gasRaises);\n checkRaiseNotExcessive('the minimum transaction fee', gasPriceRaise * feeGasRaise);\n\n // the two bound different transaction types, but both are a gas limit multiplied by the same\n // gas price — the bigger of them is what the worst case costs\n const blockGasLimitRaise = checkNotExcessive(\n 'the block gas limit',\n parameters.blockGasLimit,\n d.blockGasLimit,\n );\n const maxAuthFunGasRaise = checkNotExcessive(\n 'the max auth fun gas',\n parameters.maxAuthFunGas,\n d.maxAuthFunGas,\n );\n const gasLimitRaise = maxOf([blockGasLimitRaise, maxAuthFunGasRaise]);\n checkRaiseNotExcessive('the cost of a contract transaction', gasPriceRaise * gasLimitRaise);\n\n // the gas above is multiplied by a gas price that doesn't come from these parameters, and that\n // is bounded on its own — so the raises are reported to lower those bounds by the same factors,\n // see `getGasPriceDivisor` and `getGasLimitDivisor`\n return {\n fee: maxOf([1, feeGasRaise]),\n blockGasLimit: maxOf([1, blockGasLimitRaise]),\n maxAuthFunGas: maxOf([1, maxAuthFunGasRaise]),\n };\n}\n\n/**\n * Factor the gas price ceiling of `gas-price.ts` is lowered by, so that the worst case fee doesn't\n * become the product of that ceiling and the fee gas bound of {@link convertProtocolParameters}.\n * The gas limit raise is charged to the gas limit default instead ({@link getGasLimitDivisor}).\n * It is 1 unless the parameters came from node.\n *\n * The biggest raise among all transaction types, not the one of the type being built — so a node\n * repricing one type lowers the ceiling for every type. The ceiling is 100000 times the minimum\n * gas price, far above the demand-based price this bounds in practice.\n * @param parameters - Parameters a transaction is built against\n */\nexport function getGasPriceDivisor(parameters: ProtocolParameters): number {\n return parameterRaises.get(parameters)?.fee ?? 1;\n}\n\n/**\n * The cost of a contract transaction is `gasPrice * gasLimit`, and the gas limit the SDK defaults\n * to comes from `blockGasLimit` — from `maxAuthFunGas` on a `GaMetaTx`. This is the factor node\n * raises the one `tag` reads by, so that lowering the default by it keeps the product within the\n * one of the SDK release. It is 1 unless the parameters came from node.\n *\n * Only the limit `tag` reads: charging the other one would shrink a gas limit because node raised\n * something that transaction never reads. The fee gas raise is charged to the gas price ceiling\n * ({@link getGasPriceDivisor}) instead.\n * @param parameters - Parameters a transaction is built against\n * @param tag - Type of the transaction the gas limit is defaulted for\n */\nexport function getGasLimitDivisor(parameters: ProtocolParameters, tag: Tag): number {\n const raises = parameterRaises.get(parameters);\n if (raises == null) return 1;\n return tag === Tag.GaMetaTx ? raises.maxAuthFunGas : raises.blockGasLimit;\n}\n\nfunction mapByTxType<Value, Result>(\n entries: Array<[string, Value]>,\n map: (value: Value) => Result,\n): Partial<Record<Tag, Result>> {\n return Object.fromEntries(\n entries\n .map(([txType, value]): [Tag | undefined, Result] => [getTag(txType), map(value)])\n // a transaction type the SDK doesn't implement, or won't ever build (`ChannelClientReconnectTx`)\n .filter((entry): entry is [Tag, Result] => entry[0] != null),\n );\n}\n\n/**\n * Converts the node responses to the shape the transaction builder uses, rejecting values far\n * above the ones the SDK was released with. Not a part of the public api, it is exported for\n * tests — use {@link getCachedProtocolParameters}.\n * @param response - Response of the `/v3/protocol-parameters` endpoint\n * @param nodeSettings - Response of the `/v3/node-settings` endpoint\n */\nexport function convertProtocolParameters(\n response: Awaited<ReturnType<Node['getProtocolParameters']>>,\n nodeSettings: Awaited<ReturnType<Node['getNodeSettings']>>,\n): ProtocolParameters {\n const { currentProtocolVersion, protocols } = response;\n const protocol = protocols.find(({ version }) => version === currentProtocolVersion);\n if (protocol == null) {\n throw new InternalError(\n `Node doesn't provide parameters of the current protocol ${currentProtocolVersion}`,\n );\n }\n\n // starts from the values of the SDK release so that a type or an abi version node doesn't report\n // keeps building against them, as the SDK did before this endpoint existed, instead of failing\n const contractTxBaseGas: Partial<Record<Tag, Partial<Record<AbiVersion, number>>>> =\n Object.fromEntries(\n Object.entries(defaultProtocolParameters.contractTxBaseGas).map(([tag, byAbiVersion]) => [\n tag,\n { ...byAbiVersion },\n ]),\n );\n protocol.contractTxBaseGas.forEach(({ txType, abiVersion, txBaseGas }) => {\n const tag = getTag(txType);\n // node controls `abiVersion` and the api client passes a value that doesn't match the schema\n // node declares for it through unchanged. A `__proto__` key would be written into the\n // prototype: invisible to the `Object.values` of the check below, and still returned by the\n // `byAbiVersion[abiVersion]` lookup the fee is calculated from\n if (tag == null || !Number.isInteger(abiVersion)) return;\n const byAbiVersion = (contractTxBaseGas[tag] ??= {});\n byAbiVersion[abiVersion as AbiVersion] = txBaseGas;\n });\n\n const reportedTxBaseGas = mapByTxType(Object.entries(protocol.txBaseGas), (gas) => gas);\n const parameters = freezeParameters({\n minGasPrice: protocol.minimumGasPrice,\n minMinerGasPrice: nodeSettings.minMinerGasPrice,\n gasPerByte: protocol.gasPerByte,\n blockGasLimit: nodeSettings.blockGasLimit,\n maxAuthFunGas: nodeSettings.maxAuthFunGas,\n txBaseGas: {\n // see the note on `contractTxBaseGas` above\n ...defaultProtocolParameters.txBaseGas,\n ...reportedTxBaseGas,\n },\n contractTxBaseGas,\n stateGasPerBlock: {\n // see the note on `contractTxBaseGas` above\n ...defaultProtocolParameters.stateGasPerBlock,\n ...mapByTxType(Object.entries(protocol.stateGasPerBlock), (fraction) => ({\n part: fraction.part,\n whole: fraction.whole,\n })),\n },\n });\n parameterRaises.set(parameters, checkParametersNotExcessive(parameters));\n return parameters;\n}\n\ninterface CacheEntry {\n expiresAt: number;\n parameters: Promise<ProtocolParameters>;\n}\nconst cache: WeakMap<Node, CacheEntry> = new WeakMap();\n// protocol parameters change on a hard fork, or when the node operator edits the node config,\n// neither happens often enough to justify a request per transaction built\nconst cacheTtl = 10 * 60 * 1000;\n// a node that can't be reached, or that reports parameters the SDK refuses to build against, may\n// be reachable or reconfigured in a moment — don't keep the whole `cacheTtl` worth of transactions\n// building against the parameters of the SDK release, or failing, because of one bad response.\n// Still cached rather than retried per transaction: both outcomes cost a round trip to reproduce.\nconst transientCacheTtl = 30 * 1000;\n\n/**\n * Requests protocol parameters from node, the result is cached per node instance.\n *\n * Falls back to {@link defaultProtocolParameters} for a node that doesn't provide the endpoints,\n * can't be reached, or answers something this SDK release can't read. Rejects only when node\n * reports parameters that would price a transaction far above the SDK release — see\n * {@link ProtocolParametersOption} for the way out of that.\n *\n * The cache is keyed by the `Node` object, so code that constructs a `Node` per request (a\n * serverless handler, an edge worker) requests the parameters again for each one. Keep one `Node`\n * instance per endpoint to get the benefit of the cache.\n * @category transaction builder\n * @param nodeOrProxy - Node to request the parameters from\n */\nexport async function getCachedProtocolParameters(nodeOrProxy: Node): Promise<ProtocolParameters> {\n const node = unwrapProxy(nodeOrProxy);\n const entry = cache.get(node);\n if (entry != null && entry.expiresAt > Date.now()) return entry.parameters;\n\n // node is expected to respond with 404 until it gets the endpoints, and a node whose operator\n // disabled the `node_info`/`node_settings` endpoint groups with 403 — neither changes within\n // `cacheTtl`, while anything else is worth asking again about sooner\n let ttl = cacheTtl;\n // the request and the conversion both run in here so that only a deliberate refusal — a\n // `NodeError` on implausible parameters — comes out as a rejection; anything unreadable falls\n // back to the parameters of the SDK release instead of making every transaction unbuildable\n const parameters = (async (): Promise<ProtocolParameters> => {\n const fallBack = (reason: unknown): ProtocolParameters => {\n ttl = transientCacheTtl;\n console.warn(\n \"Can't get protocol parameters from node, using the ones of the SDK release instead.\" +\n ' A transaction may be rejected if this node runs other parameters.' +\n ` Reason: ${reason instanceof Error ? reason.message : String(reason)}`,\n );\n return defaultProtocolParameters;\n };\n\n // a node object without the methods (a test double, another SDK copy's `Node`) won't grow\n // them within `transientCacheTtl` — treat like the 404 of an old node: full-interval cache,\n // and no warning per 30 seconds for the life of the process\n if (\n typeof node.getProtocolParameters !== 'function' ||\n typeof node.getNodeSettings !== 'function'\n ) {\n return defaultProtocolParameters;\n }\n\n // retrying the 404 on every transaction built would only add latency\n const noRetry = { requestOptions: { customHeaders: { '__no-retry': 'true' } } };\n let response;\n let nodeSettings;\n try {\n // consensus parameters and this node's own policy are two endpoints, and a transaction is\n // priced by both — requested together so that a build waits for one round trip and not two,\n // and taken as a set: parameters half from node and half from the SDK release would be\n // neither ones node accepts nor ones the SDK was tested against\n [response, nodeSettings] = await Promise.all([\n node.getProtocolParameters(noRetry),\n node.getNodeSettings(noRetry),\n ]);\n } catch (error) {\n // the 404/403 of the note above — neither is worth a warning, or an earlier retry.\n // Read off the error rather than through `instanceof RestError`: that would import\n // `@azure/core-rest-pipeline` as a value into the transaction builder, which is otherwise\n // free of it, and pull the http stack into the bundle of an application that only packs\n // transactions. The api client is the only thing that rejects here, and it sets this\n const { statusCode } = error as { statusCode?: number };\n if (statusCode === 404 || statusCode === 403) return defaultProtocolParameters;\n // node is syncing (503), a proxy in between is down, the request timed out\n return fallBack(error);\n }\n\n try {\n return convertProtocolParameters(response, nodeSettings);\n } catch (error) {\n // node reports parameters that would price a transaction far above the SDK release — falling\n // back would build a transaction this node rejects, so the caller is told to decide instead\n if (error instanceof NodeError) throw error;\n return fallBack(error);\n }\n })();\n\n // until it settles the entry keeps concurrent builds on this one request\n const cacheEntry: CacheEntry = { expiresAt: Date.now() + cacheTtl, parameters };\n parameters.then(\n () => {\n cacheEntry.expiresAt = Date.now() + ttl;\n },\n // see `transientCacheTtl`\n () => {\n cacheEntry.expiresAt = Date.now() + transientCacheTtl;\n },\n );\n cache.set(node, cacheEntry);\n return parameters;\n}\n"],"mappings":"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","ignoreList":[]}