@xyo-network/xl1-protocol 5.6.2 → 5.7.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.
- package/dist/neutral/modules/protocol-lib/viewers/WindowedBlock.d.ts +17 -0
- package/dist/neutral/modules/protocol-lib/viewers/WindowedBlock.d.ts.map +1 -1
- package/dist/neutral/modules/protocol-model/index.d.ts +1 -0
- package/dist/neutral/modules/protocol-model/index.d.ts.map +1 -1
- package/dist/neutral/modules/protocol-model/signature/canonicalSignature.d.ts +39 -0
- package/dist/neutral/modules/protocol-model/signature/canonicalSignature.d.ts.map +1 -0
- package/dist/neutral/modules/protocol-model/signature/index.d.ts +2 -0
- package/dist/neutral/modules/protocol-model/signature/index.d.ts.map +1 -0
- package/dist/neutral/modules/validation/block/validators/BlockTransactionUniquenessValidator.d.ts +23 -0
- package/dist/neutral/modules/validation/block/validators/BlockTransactionUniquenessValidator.d.ts.map +1 -0
- package/dist/neutral/modules/validation/block/validators/index.d.ts +1 -0
- package/dist/neutral/modules/validation/block/validators/index.d.ts.map +1 -1
- package/dist/neutral/modules/validation/transaction/validateTransaction.d.ts.map +1 -1
- package/dist/neutral/modules/validation/transaction/validators/TransactionSignatureCanonicalityValidator.d.ts +22 -0
- package/dist/neutral/modules/validation/transaction/validators/TransactionSignatureCanonicalityValidator.d.ts.map +1 -0
- package/dist/neutral/modules/validation/transaction/validators/index.d.ts +1 -0
- package/dist/neutral/modules/validation/transaction/validators/index.d.ts.map +1 -1
- package/dist/neutral/protocol-lib.mjs.map +2 -2
- package/dist/neutral/protocol-model.mjs +32 -0
- package/dist/neutral/protocol-model.mjs.map +3 -3
- package/dist/neutral/validation.mjs +109 -38
- package/dist/neutral/validation.mjs.map +4 -4
- package/package.json +1 -1
|
@@ -92,8 +92,53 @@ function BlockCumulativeBalanceValidatorFactory() {
|
|
|
92
92
|
};
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
// src/modules/validation/
|
|
95
|
+
// src/modules/validation/block/validators/BlockTransactionUniquenessValidator.ts
|
|
96
96
|
import { ZERO_HASH as ZERO_HASH2 } from "@ariestools/sdk";
|
|
97
|
+
import {
|
|
98
|
+
HydratedBlockStateValidationError as HydratedBlockStateValidationError2,
|
|
99
|
+
isCanonicalSignature,
|
|
100
|
+
isTransactionBoundWitnessWithHashMeta as isTransactionBoundWitnessWithHashMeta2
|
|
101
|
+
} from "#protocol-lib";
|
|
102
|
+
function BlockTransactionUniquenessValidatorFactory() {
|
|
103
|
+
return async (context, hydratedBlock) => {
|
|
104
|
+
const [blockBw, payloads] = hydratedBlock;
|
|
105
|
+
try {
|
|
106
|
+
const transactions = payloads.filter(isTransactionBoundWitnessWithHashMeta2);
|
|
107
|
+
if (transactions.length === 0) return [];
|
|
108
|
+
const chainId = await context.chainIdAtBlockNumber(blockBw.block);
|
|
109
|
+
const errors = [];
|
|
110
|
+
const error3 = (message) => new HydratedBlockStateValidationError2(blockBw._hash, chainId, hydratedBlock, message);
|
|
111
|
+
const seen = /* @__PURE__ */ new Set();
|
|
112
|
+
for (const tx of transactions) {
|
|
113
|
+
if (seen.has(tx._dataHash)) {
|
|
114
|
+
errors.push(error3(
|
|
115
|
+
`Block contains more than one transaction with data hash ${tx._dataHash} (duplicate at ${tx._hash}); a signed authorization may execute only once`
|
|
116
|
+
));
|
|
117
|
+
}
|
|
118
|
+
seen.add(tx._dataHash);
|
|
119
|
+
for (const [index, signature] of (tx.$signatures ?? []).entries()) {
|
|
120
|
+
if (!isCanonicalSignature(signature)) {
|
|
121
|
+
errors.push(error3(
|
|
122
|
+
`Transaction ${tx._hash} carries a non-canonical (high-S) signature at index ${index}; that is a malleated twin of a valid signature and is not accepted`
|
|
123
|
+
));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return errors;
|
|
128
|
+
} catch (ex) {
|
|
129
|
+
return [new HydratedBlockStateValidationError2(
|
|
130
|
+
blockBw?._hash ?? ZERO_HASH2,
|
|
131
|
+
blockBw?.chain,
|
|
132
|
+
hydratedBlock,
|
|
133
|
+
`BlockTransactionUniquenessValidator excepted: ${ex.message}`,
|
|
134
|
+
ex
|
|
135
|
+
)];
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// src/modules/validation/boundwitness/validators/BoundWitnessReferences.ts
|
|
141
|
+
import { ZERO_HASH as ZERO_HASH3 } from "@ariestools/sdk";
|
|
97
142
|
import { isAnyPayload } from "@xyo-network/sdk";
|
|
98
143
|
import { HydratedBoundWitnessValidationError } from "#protocol-lib";
|
|
99
144
|
function getPayloadsFromPayloadArray(payloads, hashes) {
|
|
@@ -102,21 +147,21 @@ function getPayloadsFromPayloadArray(payloads, hashes) {
|
|
|
102
147
|
function payloadReferenceErrors(bw, payloadSet, payload, allowedSchemas) {
|
|
103
148
|
const errors = [];
|
|
104
149
|
if (!isAnyPayload(payload)) {
|
|
105
|
-
errors.push(new HydratedBoundWitnessValidationError(bw?._hash ??
|
|
150
|
+
errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH3, [bw, payloadSet], "invalid payload"));
|
|
106
151
|
return errors;
|
|
107
152
|
}
|
|
108
153
|
const payloadHashIndex = bw.payload_hashes.indexOf(payload._hash);
|
|
109
154
|
const payloadDataHashIndex = bw.payload_hashes.indexOf(payload._dataHash);
|
|
110
155
|
const payloadIndex = Math.max(payloadHashIndex, payloadDataHashIndex);
|
|
111
156
|
if (payloadIndex === -1) {
|
|
112
|
-
errors.push(new HydratedBoundWitnessValidationError(bw?._hash ??
|
|
157
|
+
errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH3, [bw, payloadSet], "payload hash not found"));
|
|
113
158
|
}
|
|
114
159
|
const declaredSchema = bw.payload_schemas[payloadIndex];
|
|
115
160
|
if (declaredSchema !== payload.schema) {
|
|
116
|
-
errors.push(new HydratedBoundWitnessValidationError(bw?._hash ??
|
|
161
|
+
errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH3, [bw, payloadSet], "mismatched schema"));
|
|
117
162
|
}
|
|
118
163
|
if (allowedSchemas && !allowedSchemas.includes(payload.schema)) {
|
|
119
|
-
errors.push(new HydratedBoundWitnessValidationError(bw?._hash ??
|
|
164
|
+
errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH3, [bw, payloadSet], `disallowed schema [${payload.schema}]`));
|
|
120
165
|
}
|
|
121
166
|
return errors;
|
|
122
167
|
}
|
|
@@ -125,20 +170,20 @@ var BoundWitnessReferencesValidator = (allowedSchemas) => ([bw, payloadSet]) =>
|
|
|
125
170
|
try {
|
|
126
171
|
const payloads = getPayloadsFromPayloadArray(payloadSet, bw.payload_hashes);
|
|
127
172
|
if (payloads.length !== bw.payload_hashes.length) {
|
|
128
|
-
errors.push(new HydratedBoundWitnessValidationError(bw?._hash ??
|
|
173
|
+
errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH3, [bw, payloadSet], "unable to locate payloads"));
|
|
129
174
|
}
|
|
130
175
|
for (const payload of payloads) {
|
|
131
176
|
errors.push(...payloadReferenceErrors(bw, payloadSet, payload, allowedSchemas));
|
|
132
177
|
}
|
|
133
178
|
} catch (ex) {
|
|
134
|
-
const
|
|
135
|
-
errors.push(
|
|
179
|
+
const error3 = new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH3, [bw, payloadSet], `validation excepted: ${String(ex)}`, ex);
|
|
180
|
+
errors.push(error3);
|
|
136
181
|
}
|
|
137
182
|
return errors;
|
|
138
183
|
};
|
|
139
184
|
|
|
140
185
|
// src/modules/validation/boundwitness/validators/BoundWitnessSignatures.ts
|
|
141
|
-
import { toArrayBuffer, ZERO_HASH as
|
|
186
|
+
import { toArrayBuffer, ZERO_HASH as ZERO_HASH4 } from "@ariestools/sdk";
|
|
142
187
|
import { BoundWitnessBuilder, BoundWitnessValidator } from "@xyo-network/sdk";
|
|
143
188
|
import { BoundWitnessValidationError } from "#protocol-lib";
|
|
144
189
|
var BoundWitnessSignaturesValidator = async (bw) => {
|
|
@@ -154,19 +199,19 @@ var BoundWitnessSignaturesValidator = async (bw) => {
|
|
|
154
199
|
}));
|
|
155
200
|
for (const [, bwErrors] of results) {
|
|
156
201
|
for (const bwError of bwErrors) {
|
|
157
|
-
errors.push(new BoundWitnessValidationError(bw?._hash ??
|
|
202
|
+
errors.push(new BoundWitnessValidationError(bw?._hash ?? ZERO_HASH4, bw, "validation errors", bwError));
|
|
158
203
|
}
|
|
159
204
|
}
|
|
160
205
|
} catch (ex) {
|
|
161
|
-
errors.push(new BoundWitnessValidationError(bw?._hash ??
|
|
206
|
+
errors.push(new BoundWitnessValidationError(bw?._hash ?? ZERO_HASH4, bw, "validation excepted", ex));
|
|
162
207
|
}
|
|
163
208
|
return errors;
|
|
164
209
|
};
|
|
165
210
|
|
|
166
211
|
// src/modules/validation/transaction/validateTransaction.ts
|
|
167
|
-
import { ZERO_HASH as
|
|
212
|
+
import { ZERO_HASH as ZERO_HASH13 } from "@ariestools/sdk";
|
|
168
213
|
import { asHashMeta } from "@xyo-network/sdk";
|
|
169
|
-
import { HydratedTransactionValidationError as
|
|
214
|
+
import { HydratedTransactionValidationError as HydratedTransactionValidationError10, isTransactionBoundWitness } from "#protocol-lib";
|
|
170
215
|
|
|
171
216
|
// src/modules/validation/transaction/validators/SignerAuthorization.ts
|
|
172
217
|
import { XyoAddressZod } from "@xyo-network/sdk";
|
|
@@ -253,11 +298,11 @@ function signerValidatorsFromAuthorizations(authorizations = []) {
|
|
|
253
298
|
}
|
|
254
299
|
|
|
255
300
|
// src/modules/validation/transaction/validators/TransactionBoundWitnessValidator.ts
|
|
256
|
-
import { ZERO_HASH as
|
|
301
|
+
import { ZERO_HASH as ZERO_HASH5 } from "@ariestools/sdk";
|
|
257
302
|
import { BoundWitnessValidator as BoundWitnessValidator2 } from "@xyo-network/sdk";
|
|
258
303
|
import { HydratedTransactionValidationError as HydratedTransactionValidationError2 } from "#protocol-lib";
|
|
259
304
|
import { isXl1PayloadVersionSupported } from "#protocol-model";
|
|
260
|
-
var error = (tx, message) => new HydratedTransactionValidationError2(tx?.[0]?._hash ??
|
|
305
|
+
var error = (tx, message) => new HydratedTransactionValidationError2(tx?.[0]?._hash ?? ZERO_HASH5, tx, message);
|
|
261
306
|
var checkSignaturesShape = (tx) => {
|
|
262
307
|
const bw = tx[0];
|
|
263
308
|
if (bw.$signatures === void 0) {
|
|
@@ -281,11 +326,11 @@ var TransactionBoundWitnessValidator = async (context, tx) => {
|
|
|
281
326
|
};
|
|
282
327
|
|
|
283
328
|
// src/modules/validation/transaction/validators/TransactionDurationValidator.ts
|
|
284
|
-
import { ZERO_HASH as
|
|
329
|
+
import { ZERO_HASH as ZERO_HASH6 } from "@ariestools/sdk";
|
|
285
330
|
import { HydratedTransactionValidationError as HydratedTransactionValidationError3 } from "#protocol-lib";
|
|
286
331
|
var TransactionDurationValidator = (context, tx) => {
|
|
287
332
|
const errors = [];
|
|
288
|
-
const hash = tx?.[0]?._hash ??
|
|
333
|
+
const hash = tx?.[0]?._hash ?? ZERO_HASH6;
|
|
289
334
|
try {
|
|
290
335
|
const { exp, nbf } = tx[0];
|
|
291
336
|
if (nbf < 0) errors.push(new HydratedTransactionValidationError3(hash, tx, "Transaction nbf must be positive"));
|
|
@@ -308,7 +353,7 @@ var TransactionDurationValidator = (context, tx) => {
|
|
|
308
353
|
};
|
|
309
354
|
|
|
310
355
|
// src/modules/validation/transaction/validators/TransactionElevationValidator.ts
|
|
311
|
-
import { ZERO_HASH as
|
|
356
|
+
import { ZERO_HASH as ZERO_HASH7 } from "@ariestools/sdk";
|
|
312
357
|
import { extractElevatedHashes, HydratedTransactionValidationError as HydratedTransactionValidationError4 } from "#protocol-lib";
|
|
313
358
|
var TransactionElevationValidator = (context, tx) => {
|
|
314
359
|
const errors = [];
|
|
@@ -316,11 +361,11 @@ var TransactionElevationValidator = (context, tx) => {
|
|
|
316
361
|
try {
|
|
317
362
|
extractElevatedHashes(tx);
|
|
318
363
|
} catch {
|
|
319
|
-
errors.push(new HydratedTransactionValidationError4(tx?.[0]?._hash ??
|
|
364
|
+
errors.push(new HydratedTransactionValidationError4(tx?.[0]?._hash ?? ZERO_HASH7, tx, "Hydrated transaction does not include all script hashes"));
|
|
320
365
|
}
|
|
321
366
|
} catch (ex) {
|
|
322
367
|
errors.push(new HydratedTransactionValidationError4(
|
|
323
|
-
tx?.[0]?._hash ??
|
|
368
|
+
tx?.[0]?._hash ?? ZERO_HASH7,
|
|
324
369
|
tx,
|
|
325
370
|
`Failed TransactionElevationValidator: ${String(ex)}`,
|
|
326
371
|
ex
|
|
@@ -330,7 +375,7 @@ var TransactionElevationValidator = (context, tx) => {
|
|
|
330
375
|
};
|
|
331
376
|
|
|
332
377
|
// src/modules/validation/transaction/validators/TransactionFromValidator.ts
|
|
333
|
-
import { ZERO_HASH as
|
|
378
|
+
import { ZERO_HASH as ZERO_HASH8 } from "@ariestools/sdk";
|
|
334
379
|
import { addressesContains, asXyoAddress } from "@xyo-network/sdk";
|
|
335
380
|
import { HydratedTransactionValidationError as HydratedTransactionValidationError5 } from "#protocol-lib";
|
|
336
381
|
var TransactionFromValidator = (context, tx) => {
|
|
@@ -338,18 +383,18 @@ var TransactionFromValidator = (context, tx) => {
|
|
|
338
383
|
try {
|
|
339
384
|
const from = asXyoAddress(tx[0].from);
|
|
340
385
|
if (from === void 0) errors.push(new HydratedTransactionValidationError5(
|
|
341
|
-
tx?.[0]?._hash ??
|
|
386
|
+
tx?.[0]?._hash ?? ZERO_HASH8,
|
|
342
387
|
tx,
|
|
343
388
|
"Transaction from is not a valid address"
|
|
344
389
|
));
|
|
345
390
|
else if (!addressesContains(tx[0], from)) errors.push(new HydratedTransactionValidationError5(
|
|
346
|
-
tx?.[0]?._hash ??
|
|
391
|
+
tx?.[0]?._hash ?? ZERO_HASH8,
|
|
347
392
|
tx,
|
|
348
393
|
"Transaction from address must be listed in addresses"
|
|
349
394
|
));
|
|
350
395
|
} catch (ex) {
|
|
351
396
|
errors.push(new HydratedTransactionValidationError5(
|
|
352
|
-
tx?.[0]?._hash ??
|
|
397
|
+
tx?.[0]?._hash ?? ZERO_HASH8,
|
|
353
398
|
tx,
|
|
354
399
|
`Failed TransactionFromValidator: ${String(ex)}`,
|
|
355
400
|
ex
|
|
@@ -359,7 +404,7 @@ var TransactionFromValidator = (context, tx) => {
|
|
|
359
404
|
};
|
|
360
405
|
|
|
361
406
|
// src/modules/validation/transaction/validators/TransactionGasValidator.ts
|
|
362
|
-
import { hexToBigInt as hexToBigInt2, ZERO_HASH as
|
|
407
|
+
import { hexToBigInt as hexToBigInt2, ZERO_HASH as ZERO_HASH9 } from "@ariestools/sdk";
|
|
363
408
|
import {
|
|
364
409
|
AttoXL1,
|
|
365
410
|
HydratedTransactionValidationError as HydratedTransactionValidationError6,
|
|
@@ -367,7 +412,7 @@ import {
|
|
|
367
412
|
} from "#protocol-lib";
|
|
368
413
|
var TransactionGasValidator = (context, tx) => {
|
|
369
414
|
const errors = [];
|
|
370
|
-
const hash = tx?.[0]?._hash ??
|
|
415
|
+
const hash = tx?.[0]?._hash ?? ZERO_HASH9;
|
|
371
416
|
try {
|
|
372
417
|
if (tx?.[0].fees === void 0) {
|
|
373
418
|
errors.push(new HydratedTransactionValidationError6(
|
|
@@ -451,7 +496,7 @@ var parseFees = (fees) => {
|
|
|
451
496
|
};
|
|
452
497
|
|
|
453
498
|
// src/modules/validation/transaction/validators/TransactionJsonSchemaValidator.ts
|
|
454
|
-
import { ZERO_HASH as
|
|
499
|
+
import { ZERO_HASH as ZERO_HASH10 } from "@ariestools/sdk";
|
|
455
500
|
import { PayloadBuilder } from "@xyo-network/sdk";
|
|
456
501
|
import { Ajv } from "ajv";
|
|
457
502
|
import { HydratedTransactionValidationError as HydratedTransactionValidationError7 } from "#protocol-lib";
|
|
@@ -463,42 +508,65 @@ var TransactionJsonSchemaValidator = (context, tx) => {
|
|
|
463
508
|
try {
|
|
464
509
|
validate ??= ajv.compile(TransactionBoundWitnessJsonSchema);
|
|
465
510
|
if (!validate(PayloadBuilder.omitStorageMeta(tx[0]))) {
|
|
466
|
-
const
|
|
467
|
-
tx?.[0]?._hash ??
|
|
511
|
+
const error3 = new HydratedTransactionValidationError7(
|
|
512
|
+
tx?.[0]?._hash ?? ZERO_HASH10,
|
|
468
513
|
tx,
|
|
469
514
|
`failed JSON schema validation: ${ajv.errorsText(validate.errors, { separator: "\n" })}`,
|
|
470
515
|
validate.errors
|
|
471
516
|
);
|
|
472
|
-
errors.push(
|
|
517
|
+
errors.push(error3);
|
|
473
518
|
}
|
|
474
519
|
} catch (ex) {
|
|
475
|
-
errors.push(new HydratedTransactionValidationError7(tx?.[0]?._hash ??
|
|
520
|
+
errors.push(new HydratedTransactionValidationError7(tx?.[0]?._hash ?? ZERO_HASH10, tx, "validation excepted", ex));
|
|
476
521
|
}
|
|
477
522
|
return errors;
|
|
478
523
|
};
|
|
479
524
|
|
|
480
525
|
// src/modules/validation/transaction/validators/TransactionProtocolValidator.ts
|
|
481
|
-
import { ZERO_HASH as
|
|
526
|
+
import { ZERO_HASH as ZERO_HASH11 } from "@ariestools/sdk";
|
|
482
527
|
import { HydratedTransactionValidationError as HydratedTransactionValidationError8 } from "#protocol-lib";
|
|
483
528
|
var TransactionProtocolValidator = async (context, tx) => {
|
|
484
529
|
const errors = [];
|
|
485
530
|
try {
|
|
486
531
|
if (context?.chainId !== void 0 && tx[0].chain !== context.chainId) {
|
|
487
|
-
errors.push(new HydratedTransactionValidationError8(tx?.[0]?._hash ??
|
|
532
|
+
errors.push(new HydratedTransactionValidationError8(tx?.[0]?._hash ?? ZERO_HASH11, tx, `invalid chain id [${context.chainId}, ${tx[0].chain}]`));
|
|
488
533
|
}
|
|
489
534
|
} catch (ex) {
|
|
490
|
-
errors.push(new HydratedTransactionValidationError8(tx?.[0]?._hash ??
|
|
535
|
+
errors.push(new HydratedTransactionValidationError8(tx?.[0]?._hash ?? ZERO_HASH11, tx, "validation excepted", ex));
|
|
491
536
|
}
|
|
492
537
|
return errors;
|
|
493
538
|
};
|
|
494
539
|
|
|
540
|
+
// src/modules/validation/transaction/validators/TransactionSignatureCanonicalityValidator.ts
|
|
541
|
+
import { ZERO_HASH as ZERO_HASH12 } from "@ariestools/sdk";
|
|
542
|
+
import { HydratedTransactionValidationError as HydratedTransactionValidationError9, isCanonicalSignature as isCanonicalSignature2 } from "#protocol-lib";
|
|
543
|
+
var error2 = (tx, message) => new HydratedTransactionValidationError9(tx?.[0]?._hash ?? ZERO_HASH12, tx, message);
|
|
544
|
+
var TransactionSignatureCanonicalityValidator = async (_context, tx) => {
|
|
545
|
+
try {
|
|
546
|
+
const signatures = tx[0]?.$signatures;
|
|
547
|
+
if (!Array.isArray(signatures)) return [];
|
|
548
|
+
const errors = [];
|
|
549
|
+
for (const [index, signature] of signatures.entries()) {
|
|
550
|
+
if (!isCanonicalSignature2(signature)) {
|
|
551
|
+
errors.push(error2(
|
|
552
|
+
tx,
|
|
553
|
+
`Non-canonical signature at index ${index}: s must be in the lower half of the secp256k1 order (low-S). A high-S signature is a malleated twin of a valid signature and is not accepted.`
|
|
554
|
+
));
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return errors;
|
|
558
|
+
} catch (ex) {
|
|
559
|
+
return [error2(tx, `Failed TransactionSignatureCanonicalityValidator: ${String(ex)}`)];
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
|
|
495
563
|
// src/modules/validation/transaction/validateTransaction.ts
|
|
496
564
|
var validateTransaction = async (context, tx, additionalValidators) => {
|
|
497
565
|
try {
|
|
498
566
|
if (!isTransactionBoundWitness(tx[0])) {
|
|
499
567
|
const castTx = tx.at(0);
|
|
500
|
-
return [new
|
|
501
|
-
asHashMeta(castTx)?._hash ??
|
|
568
|
+
return [new HydratedTransactionValidationError10(
|
|
569
|
+
asHashMeta(castTx)?._hash ?? ZERO_HASH13,
|
|
502
570
|
tx,
|
|
503
571
|
"failed isTransactionBoundWitness identity check"
|
|
504
572
|
)];
|
|
@@ -509,6 +577,7 @@ var validateTransaction = async (context, tx, additionalValidators) => {
|
|
|
509
577
|
TransactionFromValidator,
|
|
510
578
|
TransactionGasValidator,
|
|
511
579
|
TransactionElevationValidator,
|
|
580
|
+
TransactionSignatureCanonicalityValidator,
|
|
512
581
|
TransactionBoundWitnessValidator,
|
|
513
582
|
...additionalValidators ?? []
|
|
514
583
|
];
|
|
@@ -516,8 +585,8 @@ var validateTransaction = async (context, tx, additionalValidators) => {
|
|
|
516
585
|
return validationResults.flat();
|
|
517
586
|
} catch (ex) {
|
|
518
587
|
const castTx = tx?.[0];
|
|
519
|
-
return [new
|
|
520
|
-
castTx?._hash ??
|
|
588
|
+
return [new HydratedTransactionValidationError10(
|
|
589
|
+
castTx?._hash ?? ZERO_HASH13,
|
|
521
590
|
tx,
|
|
522
591
|
"Failed TransactionGasValidator: " + ex.message,
|
|
523
592
|
ex
|
|
@@ -526,6 +595,7 @@ var validateTransaction = async (context, tx, additionalValidators) => {
|
|
|
526
595
|
};
|
|
527
596
|
export {
|
|
528
597
|
BlockCumulativeBalanceValidatorFactory,
|
|
598
|
+
BlockTransactionUniquenessValidatorFactory,
|
|
529
599
|
BoundWitnessReferencesValidator,
|
|
530
600
|
BoundWitnessSignaturesValidator,
|
|
531
601
|
CompletedStepRewardAddressValidatorFactory,
|
|
@@ -541,6 +611,7 @@ export {
|
|
|
541
611
|
TransactionGasValidator,
|
|
542
612
|
TransactionJsonSchemaValidator,
|
|
543
613
|
TransactionProtocolValidator,
|
|
614
|
+
TransactionSignatureCanonicalityValidator,
|
|
544
615
|
TransactionTransfersValidatorFactory,
|
|
545
616
|
accumulateOutflows,
|
|
546
617
|
findMalformedTransfers,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../src/modules/validation/block/validators/BlockCumulativeBalanceValidator.ts", "../../src/modules/validation/boundwitness/validators/BoundWitnessReferences.ts", "../../src/modules/validation/boundwitness/validators/BoundWitnessSignatures.ts", "../../src/modules/validation/transaction/validateTransaction.ts", "../../src/modules/validation/transaction/validators/SignerAuthorization.ts", "../../src/modules/validation/transaction/validators/TransactionTransfersValidator.ts", "../../src/modules/validation/transaction/validators/TransactionBoundWitnessValidator.ts", "../../src/modules/validation/transaction/validators/TransactionDurationValidator.ts", "../../src/modules/validation/transaction/validators/TransactionElevationValidator.ts", "../../src/modules/validation/transaction/validators/TransactionFromValidator.ts", "../../src/modules/validation/transaction/validators/TransactionGasValidator.ts", "../../src/modules/validation/transaction/validators/TransactionJsonSchemaValidator.ts", "../../src/modules/validation/transaction/validators/TransactionProtocolValidator.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type Hex, hexToBigInt, ZERO_HASH,\n} from '@ariestools/sdk'\nimport type { XyoAddress } from '@xyo-network/sdk'\n\nimport type {\n HydratedBlockStateValidationFunction,\n HydratedBlockWithHashMeta,\n TransactionBoundWitnessWithHashMeta,\n} from '#protocol-lib'\nimport {\n HydratedBlockStateValidationError,\n isTransactionBoundWitnessWithHashMeta,\n isTransferPayload,\n TransferSchema,\n XYO_ZERO_ADDRESS,\n} from '#protocol-lib'\n\n/** Compute the maximum fee commitment for a transaction (base + priority + gasLimit). */\nfunction maxTransactionFeeCost(tx: TransactionBoundWitnessWithHashMeta): bigint {\n const {\n base, gasLimit, priority,\n } = tx.fees\n return hexToBigInt(base) + hexToBigInt(priority) + hexToBigInt(gasLimit)\n}\n\nfunction accumulateTransferOutflows(\n payload: HydratedBlockWithHashMeta[1][number],\n txPayloadHashes: Set<string>,\n outflows: Record<XyoAddress, bigint>,\n): void {\n // Transfers are matched by _hash only. Producer-synthesized system transfers (fee burn,\n // gas payment, block reward) are intentionally unreferenced by any transaction and thus\n // excluded \u2014 the sender's fee commitment is already charged via maxTransactionFeeCost.\n // Note: _dataHash references, though accepted by BoundWitnessReferencesValidator, do not\n // count here and are therefore never balance-checked.\n if (!txPayloadHashes.has(payload._hash) || !isTransferPayload(payload)) return\n const { from } = payload\n for (const [to, amount] of Object.entries(payload.transfers) as [XyoAddress, Hex][]) {\n if (to !== from) {\n outflows[from] = (outflows[from] ?? 0n) + hexToBigInt(amount)\n }\n }\n}\n\n/** Accumulate outflows per address from fees and transfers in the given transactions. */\nexport function accumulateOutflows(\n transactions: TransactionBoundWitnessWithHashMeta[],\n payloads: HydratedBlockWithHashMeta[1],\n): Record<XyoAddress, bigint> {\n const outflows: Record<XyoAddress, bigint> = {}\n\n for (const tx of transactions) {\n // Fee cost charged to the transaction sender\n const feeCost = maxTransactionFeeCost(tx)\n const feePayer = tx.from\n outflows[feePayer] = (outflows[feePayer] ?? 0n) + feeCost\n\n // Find transfer payloads belonging to this transaction\n const txPayloadHashes = new Set(tx.payload_hashes)\n for (const payload of payloads) {\n accumulateTransferOutflows(payload, txPayloadHashes, outflows)\n }\n }\n\n return outflows\n}\n\n/**\n * Find transaction-referenced payloads that claim the Transfer schema but fail full Transfer\n * validation. These must be surfaced as errors rather than skipped: the balance applier treats\n * every payload with the Transfer schema as a transfer, so a malformed one that validation\n * ignores would still be applied (or crash the applier).\n */\nexport function findMalformedTransfers(\n transactions: TransactionBoundWitnessWithHashMeta[],\n payloads: HydratedBlockWithHashMeta[1],\n): HydratedBlockWithHashMeta[1] {\n const referenced = new Set(transactions.flatMap(tx => tx.payload_hashes))\n return payloads.filter(payload =>\n referenced.has(payload._hash)\n && payload.schema === TransferSchema\n && !isTransferPayload(payload))\n}\n\n/** Creates a block state validator that checks cumulative outflows per address do not exceed pre-block balances. */\nexport function BlockCumulativeBalanceValidatorFactory(): HydratedBlockStateValidationFunction {\n return async (context, hydratedBlock) => {\n const [blockBw, payloads] = hydratedBlock\n try {\n // Find all transactions in the block\n const transactions = payloads.filter(isTransactionBoundWitnessWithHashMeta)\n\n if (transactions.length === 0) return []\n\n const chainId = await context.chainIdAtBlockNumber(blockBw.block)\n const errors: HydratedBlockStateValidationError[] = []\n\n const malformedErrors = Array.from(\n findMalformedTransfers(transactions, payloads),\n malformed => new HydratedBlockStateValidationError(\n blockBw._hash,\n chainId,\n hydratedBlock,\n `Transaction-referenced payload ${malformed._hash} claims the Transfer schema but is not a valid Transfer`,\n ),\n )\n errors.push(...malformedErrors)\n\n const outflows = accumulateOutflows(transactions, payloads)\n\n // Query pre-block balances for all addresses with outflows\n const addresses = Object.keys(outflows) as XyoAddress[]\n if (addresses.length === 0) return errors\n\n const balances = await context.accountBalance.accountBalances(addresses)\n\n // Check each address\n for (const address of addresses) {\n if (address === XYO_ZERO_ADDRESS) continue // Skip zero address as it's used for burn transactions and doesn't have a balance\n // TODO: Add specific validation for block reward transfer\n const balance = balances[address] ?? 0n\n const totalOutflow = outflows[address]\n if (totalOutflow > balance) {\n errors.push(new HydratedBlockStateValidationError(\n blockBw._hash,\n chainId,\n hydratedBlock,\n `Cumulative outflow for address ${address} exceeds available balance: outflow ${totalOutflow} > balance ${balance}`,\n ))\n }\n }\n\n return errors\n } catch (ex) {\n return [new HydratedBlockStateValidationError(\n blockBw?._hash ?? ZERO_HASH,\n blockBw?.chain,\n hydratedBlock,\n `BlockCumulativeBalanceValidator excepted: ${(ex as Error).message}`,\n ex,\n )]\n }\n }\n}\n", "import type { Hash, Promisable } from '@ariestools/sdk'\nimport { ZERO_HASH } from '@ariestools/sdk'\nimport type {\n BoundWitness,\n Payload,\n Schema,\n WithHashMeta,\n} from '@xyo-network/sdk'\nimport { isAnyPayload } from '@xyo-network/sdk'\n\nimport type { HydratedBoundWitnessValidationFunction, HydratedBoundWitnessWithHashMeta } from '#protocol-lib'\nimport { HydratedBoundWitnessValidationError } from '#protocol-lib'\n\nfunction getPayloadsFromPayloadArray(payloads: WithHashMeta<Payload>[], hashes: Hash[]): (WithHashMeta<Payload> | undefined)[] {\n return hashes.map(hash => payloads.find(payload => payload._hash === hash || payload._dataHash === hash))\n}\n\n/** Checks one resolved payload reference for presence, index, schema, and allow-list conformance. */\nfunction payloadReferenceErrors<T extends BoundWitness>(\n bw: WithHashMeta<T>,\n payloadSet: WithHashMeta<Payload>[],\n payload: WithHashMeta<Payload> | undefined,\n allowedSchemas: Schema[] | undefined,\n): HydratedBoundWitnessValidationError[] {\n const errors: HydratedBoundWitnessValidationError[] = []\n if (!isAnyPayload(payload)) {\n errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], 'invalid payload'))\n return errors\n }\n const payloadHashIndex = bw.payload_hashes.indexOf(payload._hash)\n const payloadDataHashIndex = bw.payload_hashes.indexOf(payload._dataHash)\n const payloadIndex = Math.max(payloadHashIndex, payloadDataHashIndex)\n if (payloadIndex === -1) {\n errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], 'payload hash not found'))\n }\n\n const declaredSchema = bw.payload_schemas[payloadIndex]\n if (declaredSchema !== payload.schema) {\n errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], 'mismatched schema'))\n }\n\n if (allowedSchemas && !allowedSchemas.includes(payload.schema)) {\n errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], `disallowed schema [${payload.schema}]`))\n }\n return errors\n}\n\n/** Creates a validator that checks all payload references in a BoundWitness are present, have matching schemas, and optionally conform to an allowed schema list. */\nexport const BoundWitnessReferencesValidator\n\n = <T extends BoundWitness = BoundWitness>(allowedSchemas?: Schema[]): HydratedBoundWitnessValidationFunction<T> => (\n [bw, payloadSet]: HydratedBoundWitnessWithHashMeta<T>,\n ): Promisable<HydratedBoundWitnessValidationError[]> => {\n const errors: HydratedBoundWitnessValidationError[] = []\n try {\n const payloads = getPayloadsFromPayloadArray(payloadSet, bw.payload_hashes)\n if (payloads.length !== bw.payload_hashes.length) {\n errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], 'unable to locate payloads'))\n }\n\n // check if payloads are valid and if their schemas match the declared schemas\n for (const payload of payloads) {\n errors.push(...payloadReferenceErrors(bw, payloadSet, payload, allowedSchemas))\n }\n } catch (ex) {\n const error = new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], `validation excepted: ${String(ex)}`, ex)\n errors.push(error)\n }\n return errors\n }\n", "import { toArrayBuffer, ZERO_HASH } from '@ariestools/sdk'\nimport type {\n BoundWitness, WithStorageMeta, XyoAddress,\n} from '@xyo-network/sdk'\nimport { BoundWitnessBuilder, BoundWitnessValidator } from '@xyo-network/sdk'\n\nimport type { BoundWitnessValidationFunction } from '#protocol-lib'\nimport { BoundWitnessValidationError } from '#protocol-lib'\n\n/** Validates that all signatures on a BoundWitness are cryptographically valid for their corresponding addresses. */\nexport const BoundWitnessSignaturesValidator: BoundWitnessValidationFunction = async (\n bw: BoundWitness,\n) => {\n const errors: BoundWitnessValidationError[] = []\n try {\n const dataHash = await BoundWitnessBuilder.dataHash(bw)\n const results: [XyoAddress, Error[]][] = await Promise.all(bw.addresses.map(async (address, index) => {\n return [address, await BoundWitnessValidator.validateSignature(\n toArrayBuffer(dataHash),\n address,\n toArrayBuffer(bw.$signatures[index] ?? undefined),\n )]\n }))\n for (const [, bwErrors] of results) {\n for (const bwError of bwErrors) {\n errors.push(new BoundWitnessValidationError((bw as WithStorageMeta<BoundWitness>)?._hash ?? ZERO_HASH, bw, 'validation errors', bwError))\n }\n }\n } catch (ex) {\n errors.push(new BoundWitnessValidationError((bw as WithStorageMeta<BoundWitness>)?._hash ?? ZERO_HASH, bw, 'validation excepted', ex))\n }\n return errors\n}\n", "import { ZERO_HASH } from '@ariestools/sdk'\nimport { asHashMeta } from '@xyo-network/sdk'\n\nimport type {\n HydratedTransactionValidationFunction,\n HydratedTransactionValidationFunctionContext,\n HydratedTransactionWithHashMeta,\n} from '#protocol-lib'\nimport { HydratedTransactionValidationError, isTransactionBoundWitness } from '#protocol-lib'\n\nimport {\n TransactionBoundWitnessValidator,\n TransactionDurationValidator,\n TransactionElevationValidator, TransactionFromValidator, TransactionGasValidator, TransactionProtocolValidator,\n} from './validators/index.ts'\n\n/**\n * Validates a hydrated transaction using built-in validators plus any additional validators provided.\n *\n * Transfer authorization (`TransactionTransfersValidatorFactory`) is intentionally NOT part of the\n * built-in list: it requires deployment configuration (the node's `SignerAuthorization[]`), which is\n * not available at this layer. Chain engines MUST inject it via `additionalValidators` \u2014 otherwise\n * nothing verifies that a transfer's `from` is authorized by the transaction signer. See\n * xyo-chain `buildValidators()`, which injects it at both mempool admission and block validation.\n */\nexport const validateTransaction: HydratedTransactionValidationFunction = async (\n context: HydratedTransactionValidationFunctionContext,\n tx: HydratedTransactionWithHashMeta,\n additionalValidators?: HydratedTransactionValidationFunction[],\n): Promise<HydratedTransactionValidationError[]> => {\n try {\n if (!isTransactionBoundWitness(tx[0])) {\n const castTx = tx.at(0)\n return [new HydratedTransactionValidationError(\n asHashMeta(castTx)?._hash ?? ZERO_HASH,\n tx,\n 'failed isTransactionBoundWitness identity check',\n )]\n }\n\n const validators: HydratedTransactionValidationFunction<HydratedTransactionValidationFunctionContext>[] = [\n TransactionProtocolValidator,\n TransactionDurationValidator,\n TransactionFromValidator,\n TransactionGasValidator,\n TransactionElevationValidator,\n TransactionBoundWitnessValidator,\n ...(additionalValidators ?? []),\n ]\n const validationResults = await Promise.all(validators.map(async v => v(context, tx)))\n return validationResults.flat()\n } catch (ex) {\n const castTx = tx?.[0]\n return [new HydratedTransactionValidationError(\n castTx?._hash ?? ZERO_HASH,\n tx,\n 'Failed TransactionGasValidator: ' + (ex as Error).message,\n ex,\n )]\n }\n}\n", "import { XyoAddressZod } from '@xyo-network/sdk'\nimport { z } from 'zod'\n\nimport type { SignerValidator } from './TransactionTransfersValidator.ts'\nimport {\n CompletedStepRewardAddressValidatorFactory, DerivedReceiveAddressValidatorFactory, SelfSignerValidator,\n} from './TransactionTransfersValidator.ts'\n\n/** Authorizes the listed signers to sign for completed-step-reward addresses. */\nexport const CompletedStepRewardAuthorizationZod = z.object({\n type: z.literal('completedStepReward'),\n signers: z.array(XyoAddressZod),\n}).describe('Authorizes signers for completed-step-reward addresses')\n\n/** Authorizes the listed signers to sign for derived-receive addresses within a scope. */\nexport const DerivedReceiveAuthorizationZod = z.object({\n type: z.literal('derivedReceive'),\n scope: z.string(),\n signers: z.array(XyoAddressZod),\n}).describe('Authorizes signers for derived-receive addresses within a scope')\n\n/** A single signer authorization, discriminated by `type` (the deriving-function selector). */\nexport const SignerAuthorizationZod = z.discriminatedUnion('type', [\n CompletedStepRewardAuthorizationZod,\n DerivedReceiveAuthorizationZod,\n])\n\n/** Type-level representation of Completed Step Reward Authorization. */\nexport type CompletedStepRewardAuthorization = z.infer<typeof CompletedStepRewardAuthorizationZod>\n/** Type-level representation of Derived Receive Authorization. */\nexport type DerivedReceiveAuthorization = z.infer<typeof DerivedReceiveAuthorizationZod>\n/** Type-level representation of Signer Authorization. */\nexport type SignerAuthorization = z.infer<typeof SignerAuthorizationZod>\n\n/**\n * Registry mapping an authorization `type` to the SignerValidator factory that enforces it.\n * The exhaustive switch keeps each variant's params type-safe; add a new address family by\n * adding a union variant above and a case here.\n */\nfunction signerValidatorFromAuthorization(authorization: SignerAuthorization): SignerValidator {\n switch (authorization.type) {\n case 'completedStepReward': {\n return CompletedStepRewardAddressValidatorFactory(authorization.signers)\n }\n case 'derivedReceive': {\n return DerivedReceiveAddressValidatorFactory(authorization.signers, authorization.scope)\n }\n }\n}\n\n/**\n * Builds the `SignerValidator[]` consumed by `TransactionTransfersValidatorFactory` from a list\n * of authorizations. `SelfSignerValidator` is ALWAYS included so ordinary self-transfers pass;\n * an empty `authorizations` list therefore means \"self only\" \u2014 deny-all for reward/escrow families.\n */\nexport function signerValidatorsFromAuthorizations(authorizations: SignerAuthorization[] = []): SignerValidator[] {\n return [SelfSignerValidator, ...authorizations.map(signerValidatorFromAuthorization)]\n}\n", "import { isDefined, isUndefined } from '@ariestools/sdk'\nimport type { XyoAddress } from '@xyo-network/sdk'\n\nimport type { HydratedTransactionValidationFunction, StepIdentity } from '#protocol-lib'\nimport {\n derivedReceiveAddress,\n elevatedPayloads,\n HydratedTransactionValidationError,\n isTransferPayload,\n rewardAddressFromStepIdentity,\n} from '#protocol-lib'\n\n/** Function type that checks whether a signer is authorized to sign for a given signee address. */\nexport type SignerValidator = (signer: XyoAddress, signee: XyoAddress, context?: { address?: XyoAddress; scope?: string; step?: StepIdentity }) => boolean\n\n/** A signer validator that only allows an address to sign for itself. */\nexport const SelfSignerValidator: SignerValidator = (signer: XyoAddress, signee: XyoAddress) => signer === signee\n\n/** Creates a signer validator that authorizes specified signers to sign for completed step reward addresses. */\nexport const CompletedStepRewardAddressValidatorFactory = (allowedSigners: XyoAddress[]): SignerValidator => (\n signer: XyoAddress,\n signee: XyoAddress,\n context?: { step?: StepIdentity },\n) => {\n const step = context?.step\n if (isDefined(step)) {\n const contextAddress = rewardAddressFromStepIdentity(step)\n return allowedSigners.includes(signer) && signee === contextAddress\n }\n return false\n}\n\n/** Creates a signer validator that authorizes specified signers to sign for derived receive addresses within a given scope. */\nexport const DerivedReceiveAddressValidatorFactory = (allowedSigners: XyoAddress[], allowedScope: string): SignerValidator => (\n signer: XyoAddress,\n signee: XyoAddress,\n context?: { address?: XyoAddress; scope?: string },\n) => {\n const { address, scope } = context ?? {}\n if (scope !== allowedScope) {\n return false\n }\n if (isDefined(address)) {\n const derivedAddress = derivedReceiveAddress(address, scope)\n return allowedSigners.includes(signer) && signee === derivedAddress\n }\n return false\n}\n\n/**\n * Creates a transaction validator that checks all transfers are authorized by the transaction signer.\n *\n * Not part of `validateTransaction`'s built-in list \u2014 the signer validators come from deployment\n * config (`signerValidatorsFromAuthorizations`), so the engine must construct this validator and\n * inject it via `additionalValidators`. Skipping it disables transfer authorization entirely.\n */\nexport function TransactionTransfersValidatorFactory(\n signerValidators: SignerValidator[] = [SelfSignerValidator],\n): HydratedTransactionValidationFunction {\n return async (\n context,\n hydratedTx,\n ) => {\n const errors: HydratedTransactionValidationError[] = []\n const signer = hydratedTx[0].from\n try {\n const payloads = elevatedPayloads(hydratedTx)\n const transfers = payloads.filter(isTransferPayload)\n for (const transfer of transfers) {\n if (isUndefined(signerValidators.find(v => v(signer, transfer.from, transfer.context)))) {\n errors.push(new HydratedTransactionValidationError(\n hydratedTx[0]._hash,\n hydratedTx,\n `transfer from address ${transfer.from} is not authorized by signer ${signer}`,\n ))\n }\n }\n } catch (ex) {\n errors.push(new HydratedTransactionValidationError(hydratedTx[0]._hash, hydratedTx, 'validation excepted', ex))\n }\n return errors\n }\n}\n", "import { ZERO_HASH } from '@ariestools/sdk'\nimport { BoundWitnessValidator } from '@xyo-network/sdk'\n\nimport type { HydratedTransactionValidationFunction, HydratedTransactionWithHashMeta } from '#protocol-lib'\nimport { HydratedTransactionValidationError } from '#protocol-lib'\nimport { isXl1PayloadVersionSupported } from '#protocol-model'\n\nconst error = (tx: HydratedTransactionWithHashMeta, message: string): HydratedTransactionValidationError =>\n new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, message)\n\n// Friendly pre-check for the wallet bug we want to surface clearly: signatures\n// emitted under `signatures` instead of `$signatures`. The downstream\n// BoundWitnessValidator would also catch the missing/mismatched signatures,\n// but its message (\"Length mismatch: address/signature\", \"Missing signature\n// [<address>]\") doesn't hint at the actual root cause.\nconst checkSignaturesShape = (tx: HydratedTransactionWithHashMeta): HydratedTransactionValidationError[] => {\n const bw = tx[0] as unknown as Record<string, unknown>\n if (bw.$signatures === undefined) {\n return Array.isArray(bw.signatures)\n ? [error(tx, 'BoundWitness has `signatures` but expected `$signatures` (signatures must be in the meta-prefixed `$signatures` key)')]\n : [error(tx, 'BoundWitness is missing `$signatures`')]\n }\n return []\n}\n\n/**\n * Validates the transaction's BoundWitness wholistically by delegating to\n * `BoundWitnessValidator.validate()`. This covers:\n * - signatures: length matches addresses, every signature is cryptographically\n * valid for its corresponding address against the BW data hash\n * - addresses: uniqueness\n * - array length parity: payload_hashes vs payload_schemas\n * - schemas: per-schema name validators\n * - top-level schema check\n * - PayloadValidator.schemaName check\n * - supported XL1 payload revision, independently of data-hash signature validity\n *\n * Also emits a friendly diagnostic when the common wallet bug of\n * `signatures` vs `$signatures` is detected, so the failure points at the\n * actual root cause instead of buried length/missing-signature errors.\n */\nexport const TransactionBoundWitnessValidator: HydratedTransactionValidationFunction = async (\n context,\n tx,\n) => {\n try {\n if (!isXl1PayloadVersionSupported(tx[0])) {\n return [error(tx, 'Unsupported transaction $version: expected absent or 1000000 (1.0.0)')]\n }\n const shapeErrors = checkSignaturesShape(tx)\n if (shapeErrors.length > 0) return shapeErrors\n const bwValidator = new BoundWitnessValidator(tx[0])\n const bwErrors = await bwValidator.validate()\n return bwErrors.map(e => error(tx, `BoundWitness validation: ${e.message}`))\n } catch (ex) {\n return [error(tx, `Failed TransactionBoundWitnessValidator: ${String(ex)}`)]\n }\n}\n", "import { ZERO_HASH } from '@ariestools/sdk'\n\nimport type { HydratedTransactionValidationFunction } from '#protocol-lib'\nimport { HydratedTransactionValidationError } from '#protocol-lib'\n\n/** Validates that transaction timing fields (nbf and exp) are positive, correctly ordered, and within allowed duration limits. */\nexport const TransactionDurationValidator: HydratedTransactionValidationFunction = (\n context,\n tx,\n) => {\n const errors: HydratedTransactionValidationError[] = []\n const hash = tx?.[0]?._hash ?? ZERO_HASH\n try {\n const { exp, nbf } = tx[0]\n if (nbf < 0) errors.push(new HydratedTransactionValidationError(hash, tx, 'Transaction nbf must be positive'))\n\n if (exp < 0) errors.push(new HydratedTransactionValidationError(hash, tx, 'Transaction exp must be positive'))\n if (exp <= nbf) errors.push(new HydratedTransactionValidationError(hash, tx, 'Transaction exp must greater than nbf'))\n if (exp - nbf > 10_000) errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n 'Transaction exp must not be too far in the future',\n ))\n } catch (ex) {\n errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n `Failed TransactionDurationValidator: ${String(ex)}`,\n ex,\n ))\n }\n\n return errors\n}\n", "import { ZERO_HASH } from '@ariestools/sdk'\n\nimport type { HydratedTransactionValidationFunction } from '#protocol-lib'\nimport { extractElevatedHashes, HydratedTransactionValidationError } from '#protocol-lib'\n\n/** Validates that a hydrated transaction includes all required elevated script hashes. */\nexport const TransactionElevationValidator: HydratedTransactionValidationFunction = (\n context,\n tx,\n) => {\n const errors: HydratedTransactionValidationError[] = []\n try {\n try {\n extractElevatedHashes(tx)\n } catch {\n errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, 'Hydrated transaction does not include all script hashes'))\n }\n } catch (ex) {\n errors.push(new HydratedTransactionValidationError(\n tx?.[0]?._hash ?? ZERO_HASH,\n tx,\n `Failed TransactionElevationValidator: ${String(ex)}`,\n ex,\n ))\n }\n return errors\n}\n", "import { ZERO_HASH } from '@ariestools/sdk'\nimport { addressesContains, asXyoAddress } from '@xyo-network/sdk'\n\nimport type { HydratedTransactionValidationFunction } from '#protocol-lib'\nimport { HydratedTransactionValidationError } from '#protocol-lib'\n\n/** Validates that the transaction's from field is a valid address and is included in the BoundWitness addresses. */\nexport const TransactionFromValidator: HydratedTransactionValidationFunction = (\n context,\n tx,\n) => {\n const errors: HydratedTransactionValidationError[] = []\n try {\n const from = asXyoAddress(tx[0].from)\n if (from === undefined)errors.push(new HydratedTransactionValidationError(\n tx?.[0]?._hash ?? ZERO_HASH,\n tx,\n 'Transaction from is not a valid address',\n ))\n else if (!addressesContains(tx[0], from)) errors.push(new HydratedTransactionValidationError(\n tx?.[0]?._hash ?? ZERO_HASH,\n tx,\n 'Transaction from address must be listed in addresses',\n ))\n } catch (ex) {\n errors.push(new HydratedTransactionValidationError(\n tx?.[0]?._hash ?? ZERO_HASH,\n tx,\n `Failed TransactionFromValidator: ${String(ex)}`,\n ex,\n ))\n }\n return errors\n}\n", "import { hexToBigInt, ZERO_HASH } from '@ariestools/sdk'\n\nimport type {\n HydratedTransactionValidationFunction,\n TransactionFeesBigInt, TransactionFeesHex,\n} from '#protocol-lib'\nimport {\n AttoXL1,\n HydratedTransactionValidationError,\n minTransactionFees,\n} from '#protocol-lib'\n\n/** Validates that transaction fee fields (base, gasLimit, gasPrice, priority) are present and meet minimum requirements. */\nexport const TransactionGasValidator: HydratedTransactionValidationFunction = (\n context,\n tx,\n) => {\n const errors: HydratedTransactionValidationError[] = []\n const hash = tx?.[0]?._hash ?? ZERO_HASH\n try {\n if (tx?.[0].fees === undefined) {\n errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n 'Missing fees',\n ))\n } else {\n const {\n base, gasLimit, gasPrice, priority,\n } = parseFees(tx[0].fees)\n\n if (base === undefined) errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n 'fees.base must be defined and a valid number',\n ))\n else if (base < minTransactionFees.base) errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n `fees.base must be >= ${minTransactionFees.base}`,\n ))\n\n if (gasLimit === undefined) errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n 'fees.gasLimit must be defined and a valid number',\n ))\n else if (gasLimit < minTransactionFees.gasLimit) errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n `fees.gasLimit must be >= ${minTransactionFees.gasLimit}`,\n ))\n\n if (gasPrice === undefined) errors.push(\n new HydratedTransactionValidationError(\n hash,\n tx,\n 'fees.gasPrice must be defined and a valid number',\n ),\n )\n else if (gasPrice < minTransactionFees.gasPrice) errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n `fees.gasPrice must be >= ${minTransactionFees.gasPrice}`,\n ))\n\n if (priority === undefined) errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n 'fees.priority must be defined and a valid number',\n ))\n else if (priority < minTransactionFees.priority) errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n `fees.priority must be >= ${minTransactionFees.priority}`,\n ))\n }\n } catch (ex) {\n errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n `Failed TransactionGasValidator: ${String(ex)}`,\n ex,\n ))\n }\n return errors\n}\n\nconst parseFees = (fees: TransactionFeesHex): Partial<TransactionFeesBigInt> => {\n const ret: Partial<TransactionFeesBigInt> = {}\n const {\n base, gasLimit, gasPrice, priority,\n } = fees\n if (base !== undefined) ret.base = AttoXL1(hexToBigInt(base))\n if (gasLimit !== undefined) ret.gasLimit = AttoXL1(hexToBigInt(gasLimit))\n if (gasPrice !== undefined) ret.gasPrice = AttoXL1(hexToBigInt(gasPrice))\n if (priority !== undefined) ret.priority = AttoXL1(hexToBigInt(priority))\n return ret\n}\n", "import { ZERO_HASH } from '@ariestools/sdk'\nimport { PayloadBuilder } from '@xyo-network/sdk'\nimport type { ValidateFunction } from 'ajv'\nimport { Ajv } from 'ajv'\n\nimport type { HydratedTransactionValidationFunction, TransactionBoundWitness } from '#protocol-lib'\nimport { HydratedTransactionValidationError } from '#protocol-lib'\nimport { TransactionBoundWitnessJsonSchema } from '#schema'\n\nconst ajv = new Ajv({ allErrors: true, strict: true })\n\nlet validate: ValidateFunction<TransactionBoundWitness> | undefined\n\n/** Validates a transaction against the TransactionBoundWitness JSON schema using AJV. */\nexport const TransactionJsonSchemaValidator: HydratedTransactionValidationFunction = (\n context,\n tx,\n) => {\n const errors: HydratedTransactionValidationError[] = []\n try {\n validate ??= ajv.compile(TransactionBoundWitnessJsonSchema)\n if (!validate(PayloadBuilder.omitStorageMeta(tx[0]))) {\n const error = new HydratedTransactionValidationError(\n tx?.[0]?._hash ?? ZERO_HASH,\n tx,\n `failed JSON schema validation: ${ajv.errorsText(validate.errors, { separator: '\\n' })}`,\n validate.errors,\n )\n errors.push(error)\n }\n } catch (ex) {\n errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, 'validation excepted', ex))\n }\n return errors\n}\n", "import { ZERO_HASH } from '@ariestools/sdk'\n\nimport type {\n ChainId,\n HydratedTransactionValidationFunction,\n} from '#protocol-lib'\nimport { HydratedTransactionValidationError } from '#protocol-lib'\n\n/** Validates that the transaction's chain ID matches the expected chain ID from the validation context. */\nexport const TransactionProtocolValidator: HydratedTransactionValidationFunction = async (\n context: { chainId?: ChainId },\n tx,\n) => {\n const errors: HydratedTransactionValidationError[] = []\n try {\n if (context?.chainId !== undefined && tx[0].chain !== context.chainId) {\n errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, `invalid chain id [${context.chainId}, ${tx[0].chain}]`))\n }\n } catch (ex) {\n errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, 'validation excepted', ex))\n }\n return errors\n}\n"],
|
|
5
|
-
"mappings": ";AAAA;AAAA,EACY;AAAA,EAAa;AAAA,OAClB;AAQP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,sBAAsB,IAAiD;AAC9E,QAAM;AAAA,IACJ;AAAA,IAAM;AAAA,IAAU;AAAA,EAClB,IAAI,GAAG;AACP,SAAO,YAAY,IAAI,IAAI,YAAY,QAAQ,IAAI,YAAY,QAAQ;AACzE;AAEA,SAAS,2BACP,SACA,iBACA,UACM;AAMN,MAAI,CAAC,gBAAgB,IAAI,QAAQ,KAAK,KAAK,CAAC,kBAAkB,OAAO,EAAG;AACxE,QAAM,EAAE,KAAK,IAAI;AACjB,aAAW,CAAC,IAAI,MAAM,KAAK,OAAO,QAAQ,QAAQ,SAAS,GAA0B;AACnF,QAAI,OAAO,MAAM;AACf,eAAS,IAAI,KAAK,SAAS,IAAI,KAAK,MAAM,YAAY,MAAM;AAAA,IAC9D;AAAA,EACF;AACF;AAGO,SAAS,mBACd,cACA,UAC4B;AAC5B,QAAM,WAAuC,CAAC;AAE9C,aAAW,MAAM,cAAc;AAE7B,UAAM,UAAU,sBAAsB,EAAE;AACxC,UAAM,WAAW,GAAG;AACpB,aAAS,QAAQ,KAAK,SAAS,QAAQ,KAAK,MAAM;AAGlD,UAAM,kBAAkB,IAAI,IAAI,GAAG,cAAc;AACjD,eAAW,WAAW,UAAU;AAC9B,iCAA2B,SAAS,iBAAiB,QAAQ;AAAA,IAC/D;AAAA,EACF;AAEA,SAAO;AACT;AAQO,SAAS,uBACd,cACA,UAC8B;AAC9B,QAAM,aAAa,IAAI,IAAI,aAAa,QAAQ,QAAM,GAAG,cAAc,CAAC;AACxE,SAAO,SAAS,OAAO,aACrB,WAAW,IAAI,QAAQ,KAAK,KACzB,QAAQ,WAAW,kBACnB,CAAC,kBAAkB,OAAO,CAAC;AAClC;AAGO,SAAS,yCAA+E;AAC7F,SAAO,OAAO,SAAS,kBAAkB;AACvC,UAAM,CAAC,SAAS,QAAQ,IAAI;AAC5B,QAAI;AAEF,YAAM,eAAe,SAAS,OAAO,qCAAqC;AAE1E,UAAI,aAAa,WAAW,EAAG,QAAO,CAAC;AAEvC,YAAM,UAAU,MAAM,QAAQ,qBAAqB,QAAQ,KAAK;AAChE,YAAM,SAA8C,CAAC;AAErD,YAAM,kBAAkB,MAAM;AAAA,QAC5B,uBAAuB,cAAc,QAAQ;AAAA,QAC7C,eAAa,IAAI;AAAA,UACf,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,UACA,kCAAkC,UAAU,KAAK;AAAA,QACnD;AAAA,MACF;AACA,aAAO,KAAK,GAAG,eAAe;AAE9B,YAAM,WAAW,mBAAmB,cAAc,QAAQ;AAG1D,YAAM,YAAY,OAAO,KAAK,QAAQ;AACtC,UAAI,UAAU,WAAW,EAAG,QAAO;AAEnC,YAAM,WAAW,MAAM,QAAQ,eAAe,gBAAgB,SAAS;AAGvE,iBAAW,WAAW,WAAW;AAC/B,YAAI,YAAY,iBAAkB;AAElC,cAAM,UAAU,SAAS,OAAO,KAAK;AACrC,cAAM,eAAe,SAAS,OAAO;AACrC,YAAI,eAAe,SAAS;AAC1B,iBAAO,KAAK,IAAI;AAAA,YACd,QAAQ;AAAA,YACR;AAAA,YACA;AAAA,YACA,kCAAkC,OAAO,uCAAuC,YAAY,cAAc,OAAO;AAAA,UACnH,CAAC;AAAA,QACH;AAAA,MACF;AAEA,aAAO;AAAA,IACT,SAAS,IAAI;AACX,aAAO,CAAC,IAAI;AAAA,QACV,SAAS,SAAS;AAAA,QAClB,SAAS;AAAA,QACT;AAAA,QACA,6CAA8C,GAAa,OAAO;AAAA,QAClE;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;AC/IA,SAAS,aAAAA,kBAAiB;AAO1B,SAAS,oBAAoB;AAG7B,SAAS,2CAA2C;AAEpD,SAAS,4BAA4B,UAAmC,QAAuD;AAC7H,SAAO,OAAO,IAAI,UAAQ,SAAS,KAAK,aAAW,QAAQ,UAAU,QAAQ,QAAQ,cAAc,IAAI,CAAC;AAC1G;AAGA,SAAS,uBACP,IACA,YACA,SACA,gBACuC;AACvC,QAAM,SAAgD,CAAC;AACvD,MAAI,CAAC,aAAa,OAAO,GAAG;AAC1B,WAAO,KAAK,IAAI,oCAAoC,IAAI,SAASA,YAAW,CAAC,IAAI,UAAU,GAAG,iBAAiB,CAAC;AAChH,WAAO;AAAA,EACT;AACA,QAAM,mBAAmB,GAAG,eAAe,QAAQ,QAAQ,KAAK;AAChE,QAAM,uBAAuB,GAAG,eAAe,QAAQ,QAAQ,SAAS;AACxE,QAAM,eAAe,KAAK,IAAI,kBAAkB,oBAAoB;AACpE,MAAI,iBAAiB,IAAI;AACvB,WAAO,KAAK,IAAI,oCAAoC,IAAI,SAASA,YAAW,CAAC,IAAI,UAAU,GAAG,wBAAwB,CAAC;AAAA,EACzH;AAEA,QAAM,iBAAiB,GAAG,gBAAgB,YAAY;AACtD,MAAI,mBAAmB,QAAQ,QAAQ;AACrC,WAAO,KAAK,IAAI,oCAAoC,IAAI,SAASA,YAAW,CAAC,IAAI,UAAU,GAAG,mBAAmB,CAAC;AAAA,EACpH;AAEA,MAAI,kBAAkB,CAAC,eAAe,SAAS,QAAQ,MAAM,GAAG;AAC9D,WAAO,KAAK,IAAI,oCAAoC,IAAI,SAASA,YAAW,CAAC,IAAI,UAAU,GAAG,sBAAsB,QAAQ,MAAM,GAAG,CAAC;AAAA,EACxI;AACA,SAAO;AACT;AAGO,IAAM,kCAET,CAAwC,mBAAyE,CACjH,CAAC,IAAI,UAAU,MACuC;AACtD,QAAM,SAAgD,CAAC;AACvD,MAAI;AACF,UAAM,WAAW,4BAA4B,YAAY,GAAG,cAAc;AAC1E,QAAI,SAAS,WAAW,GAAG,eAAe,QAAQ;AAChD,aAAO,KAAK,IAAI,oCAAoC,IAAI,SAASA,YAAW,CAAC,IAAI,UAAU,GAAG,2BAA2B,CAAC;AAAA,IAC5H;AAGA,eAAW,WAAW,UAAU;AAC9B,aAAO,KAAK,GAAG,uBAAuB,IAAI,YAAY,SAAS,cAAc,CAAC;AAAA,IAChF;AAAA,EACF,SAAS,IAAI;AACX,UAAMC,SAAQ,IAAI,oCAAoC,IAAI,SAASD,YAAW,CAAC,IAAI,UAAU,GAAG,wBAAwB,OAAO,EAAE,CAAC,IAAI,EAAE;AACxI,WAAO,KAAKC,MAAK;AAAA,EACnB;AACA,SAAO;AACT;;;ACrEF,SAAS,eAAe,aAAAC,kBAAiB;AAIzC,SAAS,qBAAqB,6BAA6B;AAG3D,SAAS,mCAAmC;AAGrC,IAAM,kCAAkE,OAC7E,OACG;AACH,QAAM,SAAwC,CAAC;AAC/C,MAAI;AACF,UAAM,WAAW,MAAM,oBAAoB,SAAS,EAAE;AACtD,UAAM,UAAmC,MAAM,QAAQ,IAAI,GAAG,UAAU,IAAI,OAAO,SAAS,UAAU;AACpG,aAAO,CAAC,SAAS,MAAM,sBAAsB;AAAA,QAC3C,cAAc,QAAQ;AAAA,QACtB;AAAA,QACA,cAAc,GAAG,YAAY,KAAK,KAAK,MAAS;AAAA,MAClD,CAAC;AAAA,IACH,CAAC,CAAC;AACF,eAAW,CAAC,EAAE,QAAQ,KAAK,SAAS;AAClC,iBAAW,WAAW,UAAU;AAC9B,eAAO,KAAK,IAAI,4BAA6B,IAAsC,SAASA,YAAW,IAAI,qBAAqB,OAAO,CAAC;AAAA,MAC1I;AAAA,IACF;AAAA,EACF,SAAS,IAAI;AACX,WAAO,KAAK,IAAI,4BAA6B,IAAsC,SAASA,YAAW,IAAI,uBAAuB,EAAE,CAAC;AAAA,EACvI;AACA,SAAO;AACT;;;AChCA,SAAS,aAAAC,mBAAiB;AAC1B,SAAS,kBAAkB;AAO3B,SAAS,sCAAAC,qCAAoC,iCAAiC;;;ACR9E,SAAS,qBAAqB;AAC9B,SAAS,SAAS;;;ACDlB,SAAS,WAAW,mBAAmB;AAIvC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA,qBAAAC;AAAA,EACA;AAAA,OACK;AAMA,IAAM,sBAAuC,CAAC,QAAoB,WAAuB,WAAW;AAGpG,IAAM,6CAA6C,CAAC,mBAAkD,CAC3G,QACA,QACA,YACG;AACH,QAAM,OAAO,SAAS;AACtB,MAAI,UAAU,IAAI,GAAG;AACnB,UAAM,iBAAiB,8BAA8B,IAAI;AACzD,WAAO,eAAe,SAAS,MAAM,KAAK,WAAW;AAAA,EACvD;AACA,SAAO;AACT;AAGO,IAAM,wCAAwC,CAAC,gBAA8B,iBAA0C,CAC5H,QACA,QACA,YACG;AACH,QAAM,EAAE,SAAS,MAAM,IAAI,WAAW,CAAC;AACvC,MAAI,UAAU,cAAc;AAC1B,WAAO;AAAA,EACT;AACA,MAAI,UAAU,OAAO,GAAG;AACtB,UAAM,iBAAiB,sBAAsB,SAAS,KAAK;AAC3D,WAAO,eAAe,SAAS,MAAM,KAAK,WAAW;AAAA,EACvD;AACA,SAAO;AACT;AASO,SAAS,qCACd,mBAAsC,CAAC,mBAAmB,GACnB;AACvC,SAAO,OACL,SACA,eACG;AACH,UAAM,SAA+C,CAAC;AACtD,UAAM,SAAS,WAAW,CAAC,EAAE;AAC7B,QAAI;AACF,YAAM,WAAW,iBAAiB,UAAU;AAC5C,YAAM,YAAY,SAAS,OAAOA,kBAAiB;AACnD,iBAAW,YAAY,WAAW;AAChC,YAAI,YAAY,iBAAiB,KAAK,OAAK,EAAE,QAAQ,SAAS,MAAM,SAAS,OAAO,CAAC,CAAC,GAAG;AACvF,iBAAO,KAAK,IAAI;AAAA,YACd,WAAW,CAAC,EAAE;AAAA,YACd;AAAA,YACA,yBAAyB,SAAS,IAAI,gCAAgC,MAAM;AAAA,UAC9E,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,SAAS,IAAI;AACX,aAAO,KAAK,IAAI,mCAAmC,WAAW,CAAC,EAAE,OAAO,YAAY,uBAAuB,EAAE,CAAC;AAAA,IAChH;AACA,WAAO;AAAA,EACT;AACF;;;ADzEO,IAAM,sCAAsC,EAAE,OAAO;AAAA,EAC1D,MAAM,EAAE,QAAQ,qBAAqB;AAAA,EACrC,SAAS,EAAE,MAAM,aAAa;AAChC,CAAC,EAAE,SAAS,wDAAwD;AAG7D,IAAM,iCAAiC,EAAE,OAAO;AAAA,EACrD,MAAM,EAAE,QAAQ,gBAAgB;AAAA,EAChC,OAAO,EAAE,OAAO;AAAA,EAChB,SAAS,EAAE,MAAM,aAAa;AAChC,CAAC,EAAE,SAAS,iEAAiE;AAGtE,IAAM,yBAAyB,EAAE,mBAAmB,QAAQ;AAAA,EACjE;AAAA,EACA;AACF,CAAC;AAcD,SAAS,iCAAiC,eAAqD;AAC7F,UAAQ,cAAc,MAAM;AAAA,IAC1B,KAAK,uBAAuB;AAC1B,aAAO,2CAA2C,cAAc,OAAO;AAAA,IACzE;AAAA,IACA,KAAK,kBAAkB;AACrB,aAAO,sCAAsC,cAAc,SAAS,cAAc,KAAK;AAAA,IACzF;AAAA,EACF;AACF;AAOO,SAAS,mCAAmC,iBAAwC,CAAC,GAAsB;AAChH,SAAO,CAAC,qBAAqB,GAAG,eAAe,IAAI,gCAAgC,CAAC;AACtF;;;AEzDA,SAAS,aAAAC,kBAAiB;AAC1B,SAAS,yBAAAC,8BAA6B;AAGtC,SAAS,sCAAAC,2CAA0C;AACnD,SAAS,oCAAoC;AAE7C,IAAM,QAAQ,CAAC,IAAqC,YAClD,IAAIA,oCAAmC,KAAK,CAAC,GAAG,SAASF,YAAW,IAAI,OAAO;AAOjF,IAAM,uBAAuB,CAAC,OAA8E;AAC1G,QAAM,KAAK,GAAG,CAAC;AACf,MAAI,GAAG,gBAAgB,QAAW;AAChC,WAAO,MAAM,QAAQ,GAAG,UAAU,IAC9B,CAAC,MAAM,IAAI,sHAAsH,CAAC,IAClI,CAAC,MAAM,IAAI,uCAAuC,CAAC;AAAA,EACzD;AACA,SAAO,CAAC;AACV;AAkBO,IAAM,mCAA0E,OACrF,SACA,OACG;AACH,MAAI;AACF,QAAI,CAAC,6BAA6B,GAAG,CAAC,CAAC,GAAG;AACxC,aAAO,CAAC,MAAM,IAAI,sEAAsE,CAAC;AAAA,IAC3F;AACA,UAAM,cAAc,qBAAqB,EAAE;AAC3C,QAAI,YAAY,SAAS,EAAG,QAAO;AACnC,UAAM,cAAc,IAAIC,uBAAsB,GAAG,CAAC,CAAC;AACnD,UAAM,WAAW,MAAM,YAAY,SAAS;AAC5C,WAAO,SAAS,IAAI,OAAK,MAAM,IAAI,4BAA4B,EAAE,OAAO,EAAE,CAAC;AAAA,EAC7E,SAAS,IAAI;AACX,WAAO,CAAC,MAAM,IAAI,4CAA4C,OAAO,EAAE,CAAC,EAAE,CAAC;AAAA,EAC7E;AACF;;;ACzDA,SAAS,aAAAE,kBAAiB;AAG1B,SAAS,sCAAAC,2CAA0C;AAG5C,IAAM,+BAAsE,CACjF,SACA,OACG;AACH,QAAM,SAA+C,CAAC;AACtD,QAAM,OAAO,KAAK,CAAC,GAAG,SAASD;AAC/B,MAAI;AACF,UAAM,EAAE,KAAK,IAAI,IAAI,GAAG,CAAC;AACzB,QAAI,MAAM,EAAG,QAAO,KAAK,IAAIC,oCAAmC,MAAM,IAAI,kCAAkC,CAAC;AAE7G,QAAI,MAAM,EAAG,QAAO,KAAK,IAAIA,oCAAmC,MAAM,IAAI,kCAAkC,CAAC;AAC7G,QAAI,OAAO,IAAK,QAAO,KAAK,IAAIA,oCAAmC,MAAM,IAAI,uCAAuC,CAAC;AACrH,QAAI,MAAM,MAAM,IAAQ,QAAO,KAAK,IAAIA;AAAA,MACtC;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,SAAS,IAAI;AACX,WAAO,KAAK,IAAIA;AAAA,MACd;AAAA,MACA;AAAA,MACA,wCAAwC,OAAO,EAAE,CAAC;AAAA,MAClD;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;ACjCA,SAAS,aAAAC,kBAAiB;AAG1B,SAAS,uBAAuB,sCAAAC,2CAA0C;AAGnE,IAAM,gCAAuE,CAClF,SACA,OACG;AACH,QAAM,SAA+C,CAAC;AACtD,MAAI;AACF,QAAI;AACF,4BAAsB,EAAE;AAAA,IAC1B,QAAQ;AACN,aAAO,KAAK,IAAIA,oCAAmC,KAAK,CAAC,GAAG,SAASD,YAAW,IAAI,yDAAyD,CAAC;AAAA,IAChJ;AAAA,EACF,SAAS,IAAI;AACX,WAAO,KAAK,IAAIC;AAAA,MACd,KAAK,CAAC,GAAG,SAASD;AAAA,MAClB;AAAA,MACA,yCAAyC,OAAO,EAAE,CAAC;AAAA,MACnD;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;;;AC1BA,SAAS,aAAAE,kBAAiB;AAC1B,SAAS,mBAAmB,oBAAoB;AAGhD,SAAS,sCAAAC,2CAA0C;AAG5C,IAAM,2BAAkE,CAC7E,SACA,OACG;AACH,QAAM,SAA+C,CAAC;AACtD,MAAI;AACF,UAAM,OAAO,aAAa,GAAG,CAAC,EAAE,IAAI;AACpC,QAAI,SAAS,OAAU,QAAO,KAAK,IAAIA;AAAA,MACrC,KAAK,CAAC,GAAG,SAASD;AAAA,MAClB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,aACQ,CAAC,kBAAkB,GAAG,CAAC,GAAG,IAAI,EAAG,QAAO,KAAK,IAAIC;AAAA,MACxD,KAAK,CAAC,GAAG,SAASD;AAAA,MAClB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,SAAS,IAAI;AACX,WAAO,KAAK,IAAIC;AAAA,MACd,KAAK,CAAC,GAAG,SAASD;AAAA,MAClB;AAAA,MACA,oCAAoC,OAAO,EAAE,CAAC;AAAA,MAC9C;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;;;ACjCA,SAAS,eAAAE,cAAa,aAAAC,kBAAiB;AAMvC;AAAA,EACE;AAAA,EACA,sCAAAC;AAAA,EACA;AAAA,OACK;AAGA,IAAM,0BAAiE,CAC5E,SACA,OACG;AACH,QAAM,SAA+C,CAAC;AACtD,QAAM,OAAO,KAAK,CAAC,GAAG,SAASD;AAC/B,MAAI;AACF,QAAI,KAAK,CAAC,EAAE,SAAS,QAAW;AAC9B,aAAO,KAAK,IAAIC;AAAA,QACd;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,YAAM;AAAA,QACJ;AAAA,QAAM;AAAA,QAAU;AAAA,QAAU;AAAA,MAC5B,IAAI,UAAU,GAAG,CAAC,EAAE,IAAI;AAExB,UAAI,SAAS,OAAW,QAAO,KAAK,IAAIA;AAAA,QACtC;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,eACQ,OAAO,mBAAmB,KAAM,QAAO,KAAK,IAAIA;AAAA,QACvD;AAAA,QACA;AAAA,QACA,wBAAwB,mBAAmB,IAAI;AAAA,MACjD,CAAC;AAED,UAAI,aAAa,OAAW,QAAO,KAAK,IAAIA;AAAA,QAC1C;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,eACQ,WAAW,mBAAmB,SAAU,QAAO,KAAK,IAAIA;AAAA,QAC/D;AAAA,QACA;AAAA,QACA,4BAA4B,mBAAmB,QAAQ;AAAA,MACzD,CAAC;AAED,UAAI,aAAa,OAAW,QAAO;AAAA,QACjC,IAAIA;AAAA,UACF;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,eACS,WAAW,mBAAmB,SAAU,QAAO,KAAK,IAAIA;AAAA,QAC/D;AAAA,QACA;AAAA,QACA,4BAA4B,mBAAmB,QAAQ;AAAA,MACzD,CAAC;AAED,UAAI,aAAa,OAAW,QAAO,KAAK,IAAIA;AAAA,QAC1C;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,eACQ,WAAW,mBAAmB,SAAU,QAAO,KAAK,IAAIA;AAAA,QAC/D;AAAA,QACA;AAAA,QACA,4BAA4B,mBAAmB,QAAQ;AAAA,MACzD,CAAC;AAAA,IACH;AAAA,EACF,SAAS,IAAI;AACX,WAAO,KAAK,IAAIA;AAAA,MACd;AAAA,MACA;AAAA,MACA,mCAAmC,OAAO,EAAE,CAAC;AAAA,MAC7C;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,IAAM,YAAY,CAAC,SAA6D;AAC9E,QAAM,MAAsC,CAAC;AAC7C,QAAM;AAAA,IACJ;AAAA,IAAM;AAAA,IAAU;AAAA,IAAU;AAAA,EAC5B,IAAI;AACJ,MAAI,SAAS,OAAW,KAAI,OAAO,QAAQF,aAAY,IAAI,CAAC;AAC5D,MAAI,aAAa,OAAW,KAAI,WAAW,QAAQA,aAAY,QAAQ,CAAC;AACxE,MAAI,aAAa,OAAW,KAAI,WAAW,QAAQA,aAAY,QAAQ,CAAC;AACxE,MAAI,aAAa,OAAW,KAAI,WAAW,QAAQA,aAAY,QAAQ,CAAC;AACxE,SAAO;AACT;;;AClGA,SAAS,aAAAG,kBAAiB;AAC1B,SAAS,sBAAsB;AAE/B,SAAS,WAAW;AAGpB,SAAS,sCAAAC,2CAA0C;AACnD,SAAS,yCAAyC;AAElD,IAAM,MAAM,IAAI,IAAI,EAAE,WAAW,MAAM,QAAQ,KAAK,CAAC;AAErD,IAAI;AAGG,IAAM,iCAAwE,CACnF,SACA,OACG;AACH,QAAM,SAA+C,CAAC;AACtD,MAAI;AACF,iBAAa,IAAI,QAAQ,iCAAiC;AAC1D,QAAI,CAAC,SAAS,eAAe,gBAAgB,GAAG,CAAC,CAAC,CAAC,GAAG;AACpD,YAAMC,SAAQ,IAAID;AAAA,QAChB,KAAK,CAAC,GAAG,SAASD;AAAA,QAClB;AAAA,QACA,kCAAkC,IAAI,WAAW,SAAS,QAAQ,EAAE,WAAW,KAAK,CAAC,CAAC;AAAA,QACtF,SAAS;AAAA,MACX;AACA,aAAO,KAAKE,MAAK;AAAA,IACnB;AAAA,EACF,SAAS,IAAI;AACX,WAAO,KAAK,IAAID,oCAAmC,KAAK,CAAC,GAAG,SAASD,YAAW,IAAI,uBAAuB,EAAE,CAAC;AAAA,EAChH;AACA,SAAO;AACT;;;AClCA,SAAS,aAAAG,mBAAiB;AAM1B,SAAS,sCAAAC,2CAA0C;AAG5C,IAAM,+BAAsE,OACjF,SACA,OACG;AACH,QAAM,SAA+C,CAAC;AACtD,MAAI;AACF,QAAI,SAAS,YAAY,UAAa,GAAG,CAAC,EAAE,UAAU,QAAQ,SAAS;AACrE,aAAO,KAAK,IAAIA,oCAAmC,KAAK,CAAC,GAAG,SAASD,aAAW,IAAI,qBAAqB,QAAQ,OAAO,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC;AAAA,IAC9I;AAAA,EACF,SAAS,IAAI;AACX,WAAO,KAAK,IAAIC,oCAAmC,KAAK,CAAC,GAAG,SAASD,aAAW,IAAI,uBAAuB,EAAE,CAAC;AAAA,EAChH;AACA,SAAO;AACT;;;ATGO,IAAM,sBAA6D,OACxE,SACA,IACA,yBACkD;AAClD,MAAI;AACF,QAAI,CAAC,0BAA0B,GAAG,CAAC,CAAC,GAAG;AACrC,YAAM,SAAS,GAAG,GAAG,CAAC;AACtB,aAAO,CAAC,IAAIE;AAAA,QACV,WAAW,MAAM,GAAG,SAASC;AAAA,QAC7B;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,aAAoG;AAAA,MACxG;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,wBAAwB,CAAC;AAAA,IAC/B;AACA,UAAM,oBAAoB,MAAM,QAAQ,IAAI,WAAW,IAAI,OAAM,MAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AACrF,WAAO,kBAAkB,KAAK;AAAA,EAChC,SAAS,IAAI;AACX,UAAM,SAAS,KAAK,CAAC;AACrB,WAAO,CAAC,IAAID;AAAA,MACV,QAAQ,SAASC;AAAA,MACjB;AAAA,MACA,qCAAsC,GAAa;AAAA,MACnD;AAAA,IACF,CAAC;AAAA,EACH;AACF;",
|
|
6
|
-
"names": ["ZERO_HASH", "error", "ZERO_HASH", "ZERO_HASH", "HydratedTransactionValidationError", "isTransferPayload", "ZERO_HASH", "BoundWitnessValidator", "HydratedTransactionValidationError", "ZERO_HASH", "HydratedTransactionValidationError", "ZERO_HASH", "HydratedTransactionValidationError", "ZERO_HASH", "HydratedTransactionValidationError", "hexToBigInt", "ZERO_HASH", "HydratedTransactionValidationError", "ZERO_HASH", "HydratedTransactionValidationError", "error", "ZERO_HASH", "HydratedTransactionValidationError", "HydratedTransactionValidationError", "ZERO_HASH"]
|
|
3
|
+
"sources": ["../../src/modules/validation/block/validators/BlockCumulativeBalanceValidator.ts", "../../src/modules/validation/block/validators/BlockTransactionUniquenessValidator.ts", "../../src/modules/validation/boundwitness/validators/BoundWitnessReferences.ts", "../../src/modules/validation/boundwitness/validators/BoundWitnessSignatures.ts", "../../src/modules/validation/transaction/validateTransaction.ts", "../../src/modules/validation/transaction/validators/SignerAuthorization.ts", "../../src/modules/validation/transaction/validators/TransactionTransfersValidator.ts", "../../src/modules/validation/transaction/validators/TransactionBoundWitnessValidator.ts", "../../src/modules/validation/transaction/validators/TransactionDurationValidator.ts", "../../src/modules/validation/transaction/validators/TransactionElevationValidator.ts", "../../src/modules/validation/transaction/validators/TransactionFromValidator.ts", "../../src/modules/validation/transaction/validators/TransactionGasValidator.ts", "../../src/modules/validation/transaction/validators/TransactionJsonSchemaValidator.ts", "../../src/modules/validation/transaction/validators/TransactionProtocolValidator.ts", "../../src/modules/validation/transaction/validators/TransactionSignatureCanonicalityValidator.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n type Hex, hexToBigInt, ZERO_HASH,\n} from '@ariestools/sdk'\nimport type { XyoAddress } from '@xyo-network/sdk'\n\nimport type {\n HydratedBlockStateValidationFunction,\n HydratedBlockWithHashMeta,\n TransactionBoundWitnessWithHashMeta,\n} from '#protocol-lib'\nimport {\n HydratedBlockStateValidationError,\n isTransactionBoundWitnessWithHashMeta,\n isTransferPayload,\n TransferSchema,\n XYO_ZERO_ADDRESS,\n} from '#protocol-lib'\n\n/** Compute the maximum fee commitment for a transaction (base + priority + gasLimit). */\nfunction maxTransactionFeeCost(tx: TransactionBoundWitnessWithHashMeta): bigint {\n const {\n base, gasLimit, priority,\n } = tx.fees\n return hexToBigInt(base) + hexToBigInt(priority) + hexToBigInt(gasLimit)\n}\n\nfunction accumulateTransferOutflows(\n payload: HydratedBlockWithHashMeta[1][number],\n txPayloadHashes: Set<string>,\n outflows: Record<XyoAddress, bigint>,\n): void {\n // Transfers are matched by _hash only. Producer-synthesized system transfers (fee burn,\n // gas payment, block reward) are intentionally unreferenced by any transaction and thus\n // excluded \u2014 the sender's fee commitment is already charged via maxTransactionFeeCost.\n // Note: _dataHash references, though accepted by BoundWitnessReferencesValidator, do not\n // count here and are therefore never balance-checked.\n if (!txPayloadHashes.has(payload._hash) || !isTransferPayload(payload)) return\n const { from } = payload\n for (const [to, amount] of Object.entries(payload.transfers) as [XyoAddress, Hex][]) {\n if (to !== from) {\n outflows[from] = (outflows[from] ?? 0n) + hexToBigInt(amount)\n }\n }\n}\n\n/** Accumulate outflows per address from fees and transfers in the given transactions. */\nexport function accumulateOutflows(\n transactions: TransactionBoundWitnessWithHashMeta[],\n payloads: HydratedBlockWithHashMeta[1],\n): Record<XyoAddress, bigint> {\n const outflows: Record<XyoAddress, bigint> = {}\n\n for (const tx of transactions) {\n // Fee cost charged to the transaction sender\n const feeCost = maxTransactionFeeCost(tx)\n const feePayer = tx.from\n outflows[feePayer] = (outflows[feePayer] ?? 0n) + feeCost\n\n // Find transfer payloads belonging to this transaction\n const txPayloadHashes = new Set(tx.payload_hashes)\n for (const payload of payloads) {\n accumulateTransferOutflows(payload, txPayloadHashes, outflows)\n }\n }\n\n return outflows\n}\n\n/**\n * Find transaction-referenced payloads that claim the Transfer schema but fail full Transfer\n * validation. These must be surfaced as errors rather than skipped: the balance applier treats\n * every payload with the Transfer schema as a transfer, so a malformed one that validation\n * ignores would still be applied (or crash the applier).\n */\nexport function findMalformedTransfers(\n transactions: TransactionBoundWitnessWithHashMeta[],\n payloads: HydratedBlockWithHashMeta[1],\n): HydratedBlockWithHashMeta[1] {\n const referenced = new Set(transactions.flatMap(tx => tx.payload_hashes))\n return payloads.filter(payload =>\n referenced.has(payload._hash)\n && payload.schema === TransferSchema\n && !isTransferPayload(payload))\n}\n\n/** Creates a block state validator that checks cumulative outflows per address do not exceed pre-block balances. */\nexport function BlockCumulativeBalanceValidatorFactory(): HydratedBlockStateValidationFunction {\n return async (context, hydratedBlock) => {\n const [blockBw, payloads] = hydratedBlock\n try {\n // Find all transactions in the block\n const transactions = payloads.filter(isTransactionBoundWitnessWithHashMeta)\n\n if (transactions.length === 0) return []\n\n const chainId = await context.chainIdAtBlockNumber(blockBw.block)\n const errors: HydratedBlockStateValidationError[] = []\n\n const malformedErrors = Array.from(\n findMalformedTransfers(transactions, payloads),\n malformed => new HydratedBlockStateValidationError(\n blockBw._hash,\n chainId,\n hydratedBlock,\n `Transaction-referenced payload ${malformed._hash} claims the Transfer schema but is not a valid Transfer`,\n ),\n )\n errors.push(...malformedErrors)\n\n const outflows = accumulateOutflows(transactions, payloads)\n\n // Query pre-block balances for all addresses with outflows\n const addresses = Object.keys(outflows) as XyoAddress[]\n if (addresses.length === 0) return errors\n\n const balances = await context.accountBalance.accountBalances(addresses)\n\n // Check each address\n for (const address of addresses) {\n if (address === XYO_ZERO_ADDRESS) continue // Skip zero address as it's used for burn transactions and doesn't have a balance\n // TODO: Add specific validation for block reward transfer\n const balance = balances[address] ?? 0n\n const totalOutflow = outflows[address]\n if (totalOutflow > balance) {\n errors.push(new HydratedBlockStateValidationError(\n blockBw._hash,\n chainId,\n hydratedBlock,\n `Cumulative outflow for address ${address} exceeds available balance: outflow ${totalOutflow} > balance ${balance}`,\n ))\n }\n }\n\n return errors\n } catch (ex) {\n return [new HydratedBlockStateValidationError(\n blockBw?._hash ?? ZERO_HASH,\n blockBw?.chain,\n hydratedBlock,\n `BlockCumulativeBalanceValidator excepted: ${(ex as Error).message}`,\n ex,\n )]\n }\n }\n}\n", "import { ZERO_HASH } from '@ariestools/sdk'\n\nimport type { HydratedBlockStateValidationFunction } from '#protocol-lib'\nimport {\n HydratedBlockStateValidationError,\n isCanonicalSignature,\n isTransactionBoundWitnessWithHashMeta,\n} from '#protocol-lib'\n\n/**\n * Creates a block state validator that rejects a block which would execute the same signed\n * authorization more than once, or which carries a malleated signature.\n *\n * Two checks, both keyed on signature-independent identity:\n *\n * 1. **Duplicate effects.** Transactions are deduplicated by `_dataHash`, not `_hash`. A\n * transaction's `_hash` covers its `$signatures`; `_dataHash` does not. Because secp256k1\n * signatures are malleable, any observer of a signed transaction can derive the twin\n * `(r, n - s)` without the sender's private key. That twin is a *different* `_hash` over\n * the *same* `_dataHash`, so a check keyed on `_hash` treats it as a new transaction and\n * lets the transfer execute a second time.\n *\n * 2. **Non-canonical signatures.** A high-S signature is, by construction, such a twin.\n * Rejecting it at block level keeps a malleated transaction out of the chain even if it\n * slipped past mempool admission.\n *\n * Chain engines must inject this alongside `BlockCumulativeBalanceValidatorFactory` \u2014 see the\n * note on `validateTransaction` about `additionalValidators`.\n */\nexport function BlockTransactionUniquenessValidatorFactory(): HydratedBlockStateValidationFunction {\n return async (context, hydratedBlock) => {\n const [blockBw, payloads] = hydratedBlock\n try {\n const transactions = payloads.filter(isTransactionBoundWitnessWithHashMeta)\n if (transactions.length === 0) return []\n\n const chainId = await context.chainIdAtBlockNumber(blockBw.block)\n const errors: HydratedBlockStateValidationError[] = []\n const error = (message: string) =>\n new HydratedBlockStateValidationError(blockBw._hash, chainId, hydratedBlock, message)\n\n const seen = new Set<string>()\n for (const tx of transactions) {\n if (seen.has(tx._dataHash)) {\n errors.push(error(\n `Block contains more than one transaction with data hash ${tx._dataHash} `\n + `(duplicate at ${tx._hash}); a signed authorization may execute only once`,\n ))\n }\n seen.add(tx._dataHash)\n\n for (const [index, signature] of (tx.$signatures ?? []).entries()) {\n if (!isCanonicalSignature(signature)) {\n errors.push(error(\n `Transaction ${tx._hash} carries a non-canonical (high-S) signature at index ${index}; `\n + 'that is a malleated twin of a valid signature and is not accepted',\n ))\n }\n }\n }\n\n return errors\n } catch (ex) {\n return [new HydratedBlockStateValidationError(\n blockBw?._hash ?? ZERO_HASH,\n blockBw?.chain,\n hydratedBlock,\n `BlockTransactionUniquenessValidator excepted: ${(ex as Error).message}`,\n ex,\n )]\n }\n }\n}\n", "import type { Hash, Promisable } from '@ariestools/sdk'\nimport { ZERO_HASH } from '@ariestools/sdk'\nimport type {\n BoundWitness,\n Payload,\n Schema,\n WithHashMeta,\n} from '@xyo-network/sdk'\nimport { isAnyPayload } from '@xyo-network/sdk'\n\nimport type { HydratedBoundWitnessValidationFunction, HydratedBoundWitnessWithHashMeta } from '#protocol-lib'\nimport { HydratedBoundWitnessValidationError } from '#protocol-lib'\n\nfunction getPayloadsFromPayloadArray(payloads: WithHashMeta<Payload>[], hashes: Hash[]): (WithHashMeta<Payload> | undefined)[] {\n return hashes.map(hash => payloads.find(payload => payload._hash === hash || payload._dataHash === hash))\n}\n\n/** Checks one resolved payload reference for presence, index, schema, and allow-list conformance. */\nfunction payloadReferenceErrors<T extends BoundWitness>(\n bw: WithHashMeta<T>,\n payloadSet: WithHashMeta<Payload>[],\n payload: WithHashMeta<Payload> | undefined,\n allowedSchemas: Schema[] | undefined,\n): HydratedBoundWitnessValidationError[] {\n const errors: HydratedBoundWitnessValidationError[] = []\n if (!isAnyPayload(payload)) {\n errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], 'invalid payload'))\n return errors\n }\n const payloadHashIndex = bw.payload_hashes.indexOf(payload._hash)\n const payloadDataHashIndex = bw.payload_hashes.indexOf(payload._dataHash)\n const payloadIndex = Math.max(payloadHashIndex, payloadDataHashIndex)\n if (payloadIndex === -1) {\n errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], 'payload hash not found'))\n }\n\n const declaredSchema = bw.payload_schemas[payloadIndex]\n if (declaredSchema !== payload.schema) {\n errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], 'mismatched schema'))\n }\n\n if (allowedSchemas && !allowedSchemas.includes(payload.schema)) {\n errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], `disallowed schema [${payload.schema}]`))\n }\n return errors\n}\n\n/** Creates a validator that checks all payload references in a BoundWitness are present, have matching schemas, and optionally conform to an allowed schema list. */\nexport const BoundWitnessReferencesValidator\n\n = <T extends BoundWitness = BoundWitness>(allowedSchemas?: Schema[]): HydratedBoundWitnessValidationFunction<T> => (\n [bw, payloadSet]: HydratedBoundWitnessWithHashMeta<T>,\n ): Promisable<HydratedBoundWitnessValidationError[]> => {\n const errors: HydratedBoundWitnessValidationError[] = []\n try {\n const payloads = getPayloadsFromPayloadArray(payloadSet, bw.payload_hashes)\n if (payloads.length !== bw.payload_hashes.length) {\n errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], 'unable to locate payloads'))\n }\n\n // check if payloads are valid and if their schemas match the declared schemas\n for (const payload of payloads) {\n errors.push(...payloadReferenceErrors(bw, payloadSet, payload, allowedSchemas))\n }\n } catch (ex) {\n const error = new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], `validation excepted: ${String(ex)}`, ex)\n errors.push(error)\n }\n return errors\n }\n", "import { toArrayBuffer, ZERO_HASH } from '@ariestools/sdk'\nimport type {\n BoundWitness, WithStorageMeta, XyoAddress,\n} from '@xyo-network/sdk'\nimport { BoundWitnessBuilder, BoundWitnessValidator } from '@xyo-network/sdk'\n\nimport type { BoundWitnessValidationFunction } from '#protocol-lib'\nimport { BoundWitnessValidationError } from '#protocol-lib'\n\n/** Validates that all signatures on a BoundWitness are cryptographically valid for their corresponding addresses. */\nexport const BoundWitnessSignaturesValidator: BoundWitnessValidationFunction = async (\n bw: BoundWitness,\n) => {\n const errors: BoundWitnessValidationError[] = []\n try {\n const dataHash = await BoundWitnessBuilder.dataHash(bw)\n const results: [XyoAddress, Error[]][] = await Promise.all(bw.addresses.map(async (address, index) => {\n return [address, await BoundWitnessValidator.validateSignature(\n toArrayBuffer(dataHash),\n address,\n toArrayBuffer(bw.$signatures[index] ?? undefined),\n )]\n }))\n for (const [, bwErrors] of results) {\n for (const bwError of bwErrors) {\n errors.push(new BoundWitnessValidationError((bw as WithStorageMeta<BoundWitness>)?._hash ?? ZERO_HASH, bw, 'validation errors', bwError))\n }\n }\n } catch (ex) {\n errors.push(new BoundWitnessValidationError((bw as WithStorageMeta<BoundWitness>)?._hash ?? ZERO_HASH, bw, 'validation excepted', ex))\n }\n return errors\n}\n", "import { ZERO_HASH } from '@ariestools/sdk'\nimport { asHashMeta } from '@xyo-network/sdk'\n\nimport type {\n HydratedTransactionValidationFunction,\n HydratedTransactionValidationFunctionContext,\n HydratedTransactionWithHashMeta,\n} from '#protocol-lib'\nimport { HydratedTransactionValidationError, isTransactionBoundWitness } from '#protocol-lib'\n\nimport {\n TransactionBoundWitnessValidator,\n TransactionDurationValidator,\n TransactionElevationValidator, TransactionFromValidator, TransactionGasValidator, TransactionProtocolValidator,\n TransactionSignatureCanonicalityValidator,\n} from './validators/index.ts'\n\n/**\n * Validates a hydrated transaction using built-in validators plus any additional validators provided.\n *\n * Transfer authorization (`TransactionTransfersValidatorFactory`) is intentionally NOT part of the\n * built-in list: it requires deployment configuration (the node's `SignerAuthorization[]`), which is\n * not available at this layer. Chain engines MUST inject it via `additionalValidators` \u2014 otherwise\n * nothing verifies that a transfer's `from` is authorized by the transaction signer. See\n * xyo-chain `buildValidators()`, which injects it at both mempool admission and block validation.\n */\nexport const validateTransaction: HydratedTransactionValidationFunction = async (\n context: HydratedTransactionValidationFunctionContext,\n tx: HydratedTransactionWithHashMeta,\n additionalValidators?: HydratedTransactionValidationFunction[],\n): Promise<HydratedTransactionValidationError[]> => {\n try {\n if (!isTransactionBoundWitness(tx[0])) {\n const castTx = tx.at(0)\n return [new HydratedTransactionValidationError(\n asHashMeta(castTx)?._hash ?? ZERO_HASH,\n tx,\n 'failed isTransactionBoundWitness identity check',\n )]\n }\n\n const validators: HydratedTransactionValidationFunction<HydratedTransactionValidationFunctionContext>[] = [\n TransactionProtocolValidator,\n TransactionDurationValidator,\n TransactionFromValidator,\n TransactionGasValidator,\n TransactionElevationValidator,\n TransactionSignatureCanonicalityValidator,\n TransactionBoundWitnessValidator,\n ...(additionalValidators ?? []),\n ]\n const validationResults = await Promise.all(validators.map(async v => v(context, tx)))\n return validationResults.flat()\n } catch (ex) {\n const castTx = tx?.[0]\n return [new HydratedTransactionValidationError(\n castTx?._hash ?? ZERO_HASH,\n tx,\n 'Failed TransactionGasValidator: ' + (ex as Error).message,\n ex,\n )]\n }\n}\n", "import { XyoAddressZod } from '@xyo-network/sdk'\nimport { z } from 'zod'\n\nimport type { SignerValidator } from './TransactionTransfersValidator.ts'\nimport {\n CompletedStepRewardAddressValidatorFactory, DerivedReceiveAddressValidatorFactory, SelfSignerValidator,\n} from './TransactionTransfersValidator.ts'\n\n/** Authorizes the listed signers to sign for completed-step-reward addresses. */\nexport const CompletedStepRewardAuthorizationZod = z.object({\n type: z.literal('completedStepReward'),\n signers: z.array(XyoAddressZod),\n}).describe('Authorizes signers for completed-step-reward addresses')\n\n/** Authorizes the listed signers to sign for derived-receive addresses within a scope. */\nexport const DerivedReceiveAuthorizationZod = z.object({\n type: z.literal('derivedReceive'),\n scope: z.string(),\n signers: z.array(XyoAddressZod),\n}).describe('Authorizes signers for derived-receive addresses within a scope')\n\n/** A single signer authorization, discriminated by `type` (the deriving-function selector). */\nexport const SignerAuthorizationZod = z.discriminatedUnion('type', [\n CompletedStepRewardAuthorizationZod,\n DerivedReceiveAuthorizationZod,\n])\n\n/** Type-level representation of Completed Step Reward Authorization. */\nexport type CompletedStepRewardAuthorization = z.infer<typeof CompletedStepRewardAuthorizationZod>\n/** Type-level representation of Derived Receive Authorization. */\nexport type DerivedReceiveAuthorization = z.infer<typeof DerivedReceiveAuthorizationZod>\n/** Type-level representation of Signer Authorization. */\nexport type SignerAuthorization = z.infer<typeof SignerAuthorizationZod>\n\n/**\n * Registry mapping an authorization `type` to the SignerValidator factory that enforces it.\n * The exhaustive switch keeps each variant's params type-safe; add a new address family by\n * adding a union variant above and a case here.\n */\nfunction signerValidatorFromAuthorization(authorization: SignerAuthorization): SignerValidator {\n switch (authorization.type) {\n case 'completedStepReward': {\n return CompletedStepRewardAddressValidatorFactory(authorization.signers)\n }\n case 'derivedReceive': {\n return DerivedReceiveAddressValidatorFactory(authorization.signers, authorization.scope)\n }\n }\n}\n\n/**\n * Builds the `SignerValidator[]` consumed by `TransactionTransfersValidatorFactory` from a list\n * of authorizations. `SelfSignerValidator` is ALWAYS included so ordinary self-transfers pass;\n * an empty `authorizations` list therefore means \"self only\" \u2014 deny-all for reward/escrow families.\n */\nexport function signerValidatorsFromAuthorizations(authorizations: SignerAuthorization[] = []): SignerValidator[] {\n return [SelfSignerValidator, ...authorizations.map(signerValidatorFromAuthorization)]\n}\n", "import { isDefined, isUndefined } from '@ariestools/sdk'\nimport type { XyoAddress } from '@xyo-network/sdk'\n\nimport type { HydratedTransactionValidationFunction, StepIdentity } from '#protocol-lib'\nimport {\n derivedReceiveAddress,\n elevatedPayloads,\n HydratedTransactionValidationError,\n isTransferPayload,\n rewardAddressFromStepIdentity,\n} from '#protocol-lib'\n\n/** Function type that checks whether a signer is authorized to sign for a given signee address. */\nexport type SignerValidator = (signer: XyoAddress, signee: XyoAddress, context?: { address?: XyoAddress; scope?: string; step?: StepIdentity }) => boolean\n\n/** A signer validator that only allows an address to sign for itself. */\nexport const SelfSignerValidator: SignerValidator = (signer: XyoAddress, signee: XyoAddress) => signer === signee\n\n/** Creates a signer validator that authorizes specified signers to sign for completed step reward addresses. */\nexport const CompletedStepRewardAddressValidatorFactory = (allowedSigners: XyoAddress[]): SignerValidator => (\n signer: XyoAddress,\n signee: XyoAddress,\n context?: { step?: StepIdentity },\n) => {\n const step = context?.step\n if (isDefined(step)) {\n const contextAddress = rewardAddressFromStepIdentity(step)\n return allowedSigners.includes(signer) && signee === contextAddress\n }\n return false\n}\n\n/** Creates a signer validator that authorizes specified signers to sign for derived receive addresses within a given scope. */\nexport const DerivedReceiveAddressValidatorFactory = (allowedSigners: XyoAddress[], allowedScope: string): SignerValidator => (\n signer: XyoAddress,\n signee: XyoAddress,\n context?: { address?: XyoAddress; scope?: string },\n) => {\n const { address, scope } = context ?? {}\n if (scope !== allowedScope) {\n return false\n }\n if (isDefined(address)) {\n const derivedAddress = derivedReceiveAddress(address, scope)\n return allowedSigners.includes(signer) && signee === derivedAddress\n }\n return false\n}\n\n/**\n * Creates a transaction validator that checks all transfers are authorized by the transaction signer.\n *\n * Not part of `validateTransaction`'s built-in list \u2014 the signer validators come from deployment\n * config (`signerValidatorsFromAuthorizations`), so the engine must construct this validator and\n * inject it via `additionalValidators`. Skipping it disables transfer authorization entirely.\n */\nexport function TransactionTransfersValidatorFactory(\n signerValidators: SignerValidator[] = [SelfSignerValidator],\n): HydratedTransactionValidationFunction {\n return async (\n context,\n hydratedTx,\n ) => {\n const errors: HydratedTransactionValidationError[] = []\n const signer = hydratedTx[0].from\n try {\n const payloads = elevatedPayloads(hydratedTx)\n const transfers = payloads.filter(isTransferPayload)\n for (const transfer of transfers) {\n if (isUndefined(signerValidators.find(v => v(signer, transfer.from, transfer.context)))) {\n errors.push(new HydratedTransactionValidationError(\n hydratedTx[0]._hash,\n hydratedTx,\n `transfer from address ${transfer.from} is not authorized by signer ${signer}`,\n ))\n }\n }\n } catch (ex) {\n errors.push(new HydratedTransactionValidationError(hydratedTx[0]._hash, hydratedTx, 'validation excepted', ex))\n }\n return errors\n }\n}\n", "import { ZERO_HASH } from '@ariestools/sdk'\nimport { BoundWitnessValidator } from '@xyo-network/sdk'\n\nimport type { HydratedTransactionValidationFunction, HydratedTransactionWithHashMeta } from '#protocol-lib'\nimport { HydratedTransactionValidationError } from '#protocol-lib'\nimport { isXl1PayloadVersionSupported } from '#protocol-model'\n\nconst error = (tx: HydratedTransactionWithHashMeta, message: string): HydratedTransactionValidationError =>\n new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, message)\n\n// Friendly pre-check for the wallet bug we want to surface clearly: signatures\n// emitted under `signatures` instead of `$signatures`. The downstream\n// BoundWitnessValidator would also catch the missing/mismatched signatures,\n// but its message (\"Length mismatch: address/signature\", \"Missing signature\n// [<address>]\") doesn't hint at the actual root cause.\nconst checkSignaturesShape = (tx: HydratedTransactionWithHashMeta): HydratedTransactionValidationError[] => {\n const bw = tx[0] as unknown as Record<string, unknown>\n if (bw.$signatures === undefined) {\n return Array.isArray(bw.signatures)\n ? [error(tx, 'BoundWitness has `signatures` but expected `$signatures` (signatures must be in the meta-prefixed `$signatures` key)')]\n : [error(tx, 'BoundWitness is missing `$signatures`')]\n }\n return []\n}\n\n/**\n * Validates the transaction's BoundWitness wholistically by delegating to\n * `BoundWitnessValidator.validate()`. This covers:\n * - signatures: length matches addresses, every signature is cryptographically\n * valid for its corresponding address against the BW data hash\n * - addresses: uniqueness\n * - array length parity: payload_hashes vs payload_schemas\n * - schemas: per-schema name validators\n * - top-level schema check\n * - PayloadValidator.schemaName check\n * - supported XL1 payload revision, independently of data-hash signature validity\n *\n * Also emits a friendly diagnostic when the common wallet bug of\n * `signatures` vs `$signatures` is detected, so the failure points at the\n * actual root cause instead of buried length/missing-signature errors.\n */\nexport const TransactionBoundWitnessValidator: HydratedTransactionValidationFunction = async (\n context,\n tx,\n) => {\n try {\n if (!isXl1PayloadVersionSupported(tx[0])) {\n return [error(tx, 'Unsupported transaction $version: expected absent or 1000000 (1.0.0)')]\n }\n const shapeErrors = checkSignaturesShape(tx)\n if (shapeErrors.length > 0) return shapeErrors\n const bwValidator = new BoundWitnessValidator(tx[0])\n const bwErrors = await bwValidator.validate()\n return bwErrors.map(e => error(tx, `BoundWitness validation: ${e.message}`))\n } catch (ex) {\n return [error(tx, `Failed TransactionBoundWitnessValidator: ${String(ex)}`)]\n }\n}\n", "import { ZERO_HASH } from '@ariestools/sdk'\n\nimport type { HydratedTransactionValidationFunction } from '#protocol-lib'\nimport { HydratedTransactionValidationError } from '#protocol-lib'\n\n/** Validates that transaction timing fields (nbf and exp) are positive, correctly ordered, and within allowed duration limits. */\nexport const TransactionDurationValidator: HydratedTransactionValidationFunction = (\n context,\n tx,\n) => {\n const errors: HydratedTransactionValidationError[] = []\n const hash = tx?.[0]?._hash ?? ZERO_HASH\n try {\n const { exp, nbf } = tx[0]\n if (nbf < 0) errors.push(new HydratedTransactionValidationError(hash, tx, 'Transaction nbf must be positive'))\n\n if (exp < 0) errors.push(new HydratedTransactionValidationError(hash, tx, 'Transaction exp must be positive'))\n if (exp <= nbf) errors.push(new HydratedTransactionValidationError(hash, tx, 'Transaction exp must greater than nbf'))\n if (exp - nbf > 10_000) errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n 'Transaction exp must not be too far in the future',\n ))\n } catch (ex) {\n errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n `Failed TransactionDurationValidator: ${String(ex)}`,\n ex,\n ))\n }\n\n return errors\n}\n", "import { ZERO_HASH } from '@ariestools/sdk'\n\nimport type { HydratedTransactionValidationFunction } from '#protocol-lib'\nimport { extractElevatedHashes, HydratedTransactionValidationError } from '#protocol-lib'\n\n/** Validates that a hydrated transaction includes all required elevated script hashes. */\nexport const TransactionElevationValidator: HydratedTransactionValidationFunction = (\n context,\n tx,\n) => {\n const errors: HydratedTransactionValidationError[] = []\n try {\n try {\n extractElevatedHashes(tx)\n } catch {\n errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, 'Hydrated transaction does not include all script hashes'))\n }\n } catch (ex) {\n errors.push(new HydratedTransactionValidationError(\n tx?.[0]?._hash ?? ZERO_HASH,\n tx,\n `Failed TransactionElevationValidator: ${String(ex)}`,\n ex,\n ))\n }\n return errors\n}\n", "import { ZERO_HASH } from '@ariestools/sdk'\nimport { addressesContains, asXyoAddress } from '@xyo-network/sdk'\n\nimport type { HydratedTransactionValidationFunction } from '#protocol-lib'\nimport { HydratedTransactionValidationError } from '#protocol-lib'\n\n/** Validates that the transaction's from field is a valid address and is included in the BoundWitness addresses. */\nexport const TransactionFromValidator: HydratedTransactionValidationFunction = (\n context,\n tx,\n) => {\n const errors: HydratedTransactionValidationError[] = []\n try {\n const from = asXyoAddress(tx[0].from)\n if (from === undefined)errors.push(new HydratedTransactionValidationError(\n tx?.[0]?._hash ?? ZERO_HASH,\n tx,\n 'Transaction from is not a valid address',\n ))\n else if (!addressesContains(tx[0], from)) errors.push(new HydratedTransactionValidationError(\n tx?.[0]?._hash ?? ZERO_HASH,\n tx,\n 'Transaction from address must be listed in addresses',\n ))\n } catch (ex) {\n errors.push(new HydratedTransactionValidationError(\n tx?.[0]?._hash ?? ZERO_HASH,\n tx,\n `Failed TransactionFromValidator: ${String(ex)}`,\n ex,\n ))\n }\n return errors\n}\n", "import { hexToBigInt, ZERO_HASH } from '@ariestools/sdk'\n\nimport type {\n HydratedTransactionValidationFunction,\n TransactionFeesBigInt, TransactionFeesHex,\n} from '#protocol-lib'\nimport {\n AttoXL1,\n HydratedTransactionValidationError,\n minTransactionFees,\n} from '#protocol-lib'\n\n/** Validates that transaction fee fields (base, gasLimit, gasPrice, priority) are present and meet minimum requirements. */\nexport const TransactionGasValidator: HydratedTransactionValidationFunction = (\n context,\n tx,\n) => {\n const errors: HydratedTransactionValidationError[] = []\n const hash = tx?.[0]?._hash ?? ZERO_HASH\n try {\n if (tx?.[0].fees === undefined) {\n errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n 'Missing fees',\n ))\n } else {\n const {\n base, gasLimit, gasPrice, priority,\n } = parseFees(tx[0].fees)\n\n if (base === undefined) errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n 'fees.base must be defined and a valid number',\n ))\n else if (base < minTransactionFees.base) errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n `fees.base must be >= ${minTransactionFees.base}`,\n ))\n\n if (gasLimit === undefined) errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n 'fees.gasLimit must be defined and a valid number',\n ))\n else if (gasLimit < minTransactionFees.gasLimit) errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n `fees.gasLimit must be >= ${minTransactionFees.gasLimit}`,\n ))\n\n if (gasPrice === undefined) errors.push(\n new HydratedTransactionValidationError(\n hash,\n tx,\n 'fees.gasPrice must be defined and a valid number',\n ),\n )\n else if (gasPrice < minTransactionFees.gasPrice) errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n `fees.gasPrice must be >= ${minTransactionFees.gasPrice}`,\n ))\n\n if (priority === undefined) errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n 'fees.priority must be defined and a valid number',\n ))\n else if (priority < minTransactionFees.priority) errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n `fees.priority must be >= ${minTransactionFees.priority}`,\n ))\n }\n } catch (ex) {\n errors.push(new HydratedTransactionValidationError(\n hash,\n tx,\n `Failed TransactionGasValidator: ${String(ex)}`,\n ex,\n ))\n }\n return errors\n}\n\nconst parseFees = (fees: TransactionFeesHex): Partial<TransactionFeesBigInt> => {\n const ret: Partial<TransactionFeesBigInt> = {}\n const {\n base, gasLimit, gasPrice, priority,\n } = fees\n if (base !== undefined) ret.base = AttoXL1(hexToBigInt(base))\n if (gasLimit !== undefined) ret.gasLimit = AttoXL1(hexToBigInt(gasLimit))\n if (gasPrice !== undefined) ret.gasPrice = AttoXL1(hexToBigInt(gasPrice))\n if (priority !== undefined) ret.priority = AttoXL1(hexToBigInt(priority))\n return ret\n}\n", "import { ZERO_HASH } from '@ariestools/sdk'\nimport { PayloadBuilder } from '@xyo-network/sdk'\nimport type { ValidateFunction } from 'ajv'\nimport { Ajv } from 'ajv'\n\nimport type { HydratedTransactionValidationFunction, TransactionBoundWitness } from '#protocol-lib'\nimport { HydratedTransactionValidationError } from '#protocol-lib'\nimport { TransactionBoundWitnessJsonSchema } from '#schema'\n\nconst ajv = new Ajv({ allErrors: true, strict: true })\n\nlet validate: ValidateFunction<TransactionBoundWitness> | undefined\n\n/** Validates a transaction against the TransactionBoundWitness JSON schema using AJV. */\nexport const TransactionJsonSchemaValidator: HydratedTransactionValidationFunction = (\n context,\n tx,\n) => {\n const errors: HydratedTransactionValidationError[] = []\n try {\n validate ??= ajv.compile(TransactionBoundWitnessJsonSchema)\n if (!validate(PayloadBuilder.omitStorageMeta(tx[0]))) {\n const error = new HydratedTransactionValidationError(\n tx?.[0]?._hash ?? ZERO_HASH,\n tx,\n `failed JSON schema validation: ${ajv.errorsText(validate.errors, { separator: '\\n' })}`,\n validate.errors,\n )\n errors.push(error)\n }\n } catch (ex) {\n errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, 'validation excepted', ex))\n }\n return errors\n}\n", "import { ZERO_HASH } from '@ariestools/sdk'\n\nimport type {\n ChainId,\n HydratedTransactionValidationFunction,\n} from '#protocol-lib'\nimport { HydratedTransactionValidationError } from '#protocol-lib'\n\n/** Validates that the transaction's chain ID matches the expected chain ID from the validation context. */\nexport const TransactionProtocolValidator: HydratedTransactionValidationFunction = async (\n context: { chainId?: ChainId },\n tx,\n) => {\n const errors: HydratedTransactionValidationError[] = []\n try {\n if (context?.chainId !== undefined && tx[0].chain !== context.chainId) {\n errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, `invalid chain id [${context.chainId}, ${tx[0].chain}]`))\n }\n } catch (ex) {\n errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, 'validation excepted', ex))\n }\n return errors\n}\n", "import { ZERO_HASH } from '@ariestools/sdk'\n\nimport type { HydratedTransactionValidationFunction, HydratedTransactionWithHashMeta } from '#protocol-lib'\nimport { HydratedTransactionValidationError, isCanonicalSignature } from '#protocol-lib'\n\nconst error = (tx: HydratedTransactionWithHashMeta, message: string): HydratedTransactionValidationError =>\n new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, message)\n\n/**\n * Rejects transactions carrying a non-canonical (high-S) secp256k1 signature.\n *\n * secp256k1 signatures are malleable: for a valid `(r, s)` the twin `(r, n - s)`\n * is an equally valid signature over the same data by the same key. Because a\n * transaction's `_hash` covers `$signatures` while its `_dataHash` does not, an\n * observer who sees a signed transaction can derive that twin without the\n * sender's private key and submit it as a *different* transaction with the\n * *same* effects \u2014 replaying the transfer.\n *\n * Every signature produced by the XYO SDK is already low-S (libsecp256k1\n * normalizes when signing), so this rule rejects no honestly signed\n * transaction. It is enforced here, at the protocol layer, so a chain stays\n * protected even when running against an SDK build that still accepts the twin.\n *\n * Dropping the twin at admission is necessary but not sufficient on its own:\n * see `TransactionDataHashUniquenessValidator` for the inclusion-side check\n * that catches any duplicate effect regardless of how the signature differs.\n */\nexport const TransactionSignatureCanonicalityValidator: HydratedTransactionValidationFunction = async (\n _context,\n tx,\n) => {\n try {\n const signatures = tx[0]?.$signatures\n if (!Array.isArray(signatures)) return []\n const errors: HydratedTransactionValidationError[] = []\n for (const [index, signature] of signatures.entries()) {\n if (!isCanonicalSignature(signature)) {\n errors.push(error(\n tx,\n `Non-canonical signature at index ${index}: s must be in the lower half of the secp256k1 order (low-S). `\n + 'A high-S signature is a malleated twin of a valid signature and is not accepted.',\n ))\n }\n }\n return errors\n } catch (ex) {\n return [error(tx, `Failed TransactionSignatureCanonicalityValidator: ${String(ex)}`)]\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["ZERO_HASH", "HydratedBlockStateValidationError", "isTransactionBoundWitnessWithHashMeta", "error", "ZERO_HASH", "error", "ZERO_HASH", "ZERO_HASH", "HydratedTransactionValidationError", "isTransferPayload", "ZERO_HASH", "BoundWitnessValidator", "HydratedTransactionValidationError", "ZERO_HASH", "HydratedTransactionValidationError", "ZERO_HASH", "HydratedTransactionValidationError", "ZERO_HASH", "HydratedTransactionValidationError", "hexToBigInt", "ZERO_HASH", "HydratedTransactionValidationError", "ZERO_HASH", "HydratedTransactionValidationError", "error", "ZERO_HASH", "HydratedTransactionValidationError", "ZERO_HASH", "HydratedTransactionValidationError", "isCanonicalSignature", "error", "HydratedTransactionValidationError", "ZERO_HASH"]
|
|
7
7
|
}
|