@xyo-network/chain-validation 1.5.35 → 1.5.36
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/index.mjs +193 -140
- package/dist/neutral/index.mjs.map +1 -1
- package/dist/types/block/validateBlock.d.ts.map +1 -1
- package/dist/types/block/validators/AllowedPayloadSchemas.d.ts.map +1 -1
- package/dist/types/block/validators/Fields.d.ts.map +1 -1
- package/dist/types/block/validators/JsonSchema.d.ts.map +1 -1
- package/dist/types/block/validators/PreviousHash.d.ts.map +1 -1
- package/dist/types/boundwitness/validators/BoundWitnessReferences.d.ts.map +1 -1
- package/dist/types/boundwitness/validators/BoundWitnessSignatures.d.ts.map +1 -1
- package/dist/types/elevatedPayload/lib/validateElevatedFromBlock.d.ts.map +1 -1
- package/dist/types/elevatedPayload/lib/validateElevatedFromTransaction.d.ts.map +1 -1
- package/dist/types/elevatedPayload/lib/validateTransactionInBlock.d.ts.map +1 -1
- package/dist/types/elevatedPayload/payloads/validateChainStakeIntentInBlock.d.ts.map +1 -1
- package/dist/types/elevatedPayload/payloads/validateHashInBlock.d.ts.map +1 -1
- package/dist/types/elevatedPayload/payloads/validateSchemaInBlock.d.ts.map +1 -1
- package/dist/types/elevatedPayload/payloads/validateTransferInBlock.d.ts.map +1 -1
- package/dist/types/elevatedPayload/validatePayloadInBlock.d.ts.map +1 -1
- package/dist/types/hydratedBlock/validateHydratedBlock.d.ts.map +1 -1
- package/dist/types/hydratedBlock/validators/Payloads.d.ts.map +1 -1
- package/dist/types/hydratedBlockState/validateHydratedBlockState.d.ts +2 -2
- package/dist/types/hydratedBlockState/validateHydratedBlockState.d.ts.map +1 -1
- package/dist/types/hydratedBlockState/validators/RequiredBalance.d.ts +2 -2
- package/dist/types/hydratedBlockState/validators/RequiredBalance.d.ts.map +1 -1
- package/dist/types/transaction/validateTransaction.d.ts +1 -1
- package/dist/types/transaction/validateTransaction.d.ts.map +1 -1
- package/dist/types/transaction/validators/TransactionDurationValidator.d.ts.map +1 -1
- package/dist/types/transaction/validators/TransactionElevationValidator.d.ts.map +1 -1
- package/dist/types/transaction/validators/TransactionFromValidator.d.ts.map +1 -1
- package/dist/types/transaction/validators/TransactionGasValidator.d.ts.map +1 -1
- package/dist/types/transaction/validators/TransactionJsonSchemaValidator.d.ts.map +1 -1
- package/package.json +29 -27
- package/src/block/validateBlock.ts +7 -4
- package/src/block/validators/AllowedPayloadSchemas.ts +4 -3
- package/src/block/validators/Fields.ts +4 -3
- package/src/block/validators/JsonSchema.ts +23 -20
- package/src/block/validators/PreviousHash.ts +7 -5
- package/src/boundwitness/validators/BoundWitnessReferences.ts +5 -3
- package/src/boundwitness/validators/BoundWitnessSignatures.ts +6 -4
- package/src/elevatedPayload/lib/validateElevatedFromBlock.ts +12 -7
- package/src/elevatedPayload/lib/validateElevatedFromTransaction.ts +14 -8
- package/src/elevatedPayload/lib/validateIncludedInBlock.ts +2 -2
- package/src/elevatedPayload/lib/validateTransactionInBlock.ts +12 -8
- package/src/elevatedPayload/lib/validateTypedPayloadInBlock.ts +2 -2
- package/src/elevatedPayload/payloads/validateChainStakeIntentInBlock.ts +9 -5
- package/src/elevatedPayload/payloads/validateHashInBlock.ts +9 -5
- package/src/elevatedPayload/payloads/validateSchemaInBlock.ts +9 -5
- package/src/elevatedPayload/payloads/validateTransferInBlock.ts +9 -5
- package/src/elevatedPayload/validatePayloadInBlock.ts +8 -6
- package/src/hydratedBlock/validateHydratedBlock.ts +13 -6
- package/src/hydratedBlock/validators/Payloads.ts +13 -4
- package/src/hydratedBlockState/validateHydratedBlockState.ts +21 -10
- package/src/hydratedBlockState/validators/RequiredBalance.ts +15 -13
- package/src/transaction/validateTransaction.ts +2 -2
- package/src/transaction/validators/TransactionDurationValidator.ts +4 -3
- package/src/transaction/validators/TransactionElevationValidator.ts +4 -3
- package/src/transaction/validators/TransactionFromValidator.ts +4 -3
- package/src/transaction/validators/TransactionGasValidator.ts +4 -3
- package/src/transaction/validators/TransactionJsonSchemaValidator.ts +3 -5
- package/src/transaction/validators/TransactionProtocolValidator.ts +2 -2
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@xyo-network/chain-validation",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.36",
|
|
5
5
|
"description": "XYO Layer One SDK Validation",
|
|
6
6
|
"homepage": "https://xylabs.com",
|
|
7
7
|
"bugs": {
|
|
@@ -34,36 +34,38 @@
|
|
|
34
34
|
"deploy3": "echo Deploy3 not allowed!"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@xylabs/arraybuffer": "^4.
|
|
38
|
-
"@xylabs/hex": "^4.
|
|
39
|
-
"@xylabs/
|
|
40
|
-
"@
|
|
41
|
-
"@xyo-network/boundwitness-
|
|
42
|
-
"@xyo-network/boundwitness-
|
|
43
|
-
"@xyo-network/
|
|
44
|
-
"@xyo-network/chain-
|
|
45
|
-
"@xyo-network/chain-
|
|
46
|
-
"@xyo-network/
|
|
47
|
-
"@xyo-network/payload-
|
|
48
|
-
"@xyo-network/
|
|
49
|
-
"@xyo-network/
|
|
37
|
+
"@xylabs/arraybuffer": "^4.12.29",
|
|
38
|
+
"@xylabs/hex": "^4.12.29",
|
|
39
|
+
"@xylabs/object": "^4.12.29",
|
|
40
|
+
"@xylabs/typeof": "^4.12.29",
|
|
41
|
+
"@xyo-network/boundwitness-builder": "^3.18.10",
|
|
42
|
+
"@xyo-network/boundwitness-model": "^3.18.10",
|
|
43
|
+
"@xyo-network/boundwitness-validator": "^3.18.10",
|
|
44
|
+
"@xyo-network/chain-protocol": "^1.5.36",
|
|
45
|
+
"@xyo-network/chain-schema": "^1.5.36",
|
|
46
|
+
"@xyo-network/chain-utils": "^1.5.36",
|
|
47
|
+
"@xyo-network/payload-builder": "^3.18.10",
|
|
48
|
+
"@xyo-network/payload-model": "^3.18.10",
|
|
49
|
+
"@xyo-network/schema-payload-plugin": "^3.18.10",
|
|
50
|
+
"@xyo-network/xl1-protocol": "^1.5.16",
|
|
51
|
+
"@xyo-network/xl1-protocol-sdk": "^1.5.36",
|
|
50
52
|
"ajv": "^8.17.1"
|
|
51
53
|
},
|
|
52
54
|
"devDependencies": {
|
|
53
|
-
"@types/node": "^24.0.
|
|
54
|
-
"@xylabs/assert": "^4.
|
|
55
|
-
"@xylabs/promise": "^4.
|
|
56
|
-
"@xylabs/ts-scripts-yarn3": "^6.5.
|
|
57
|
-
"@xylabs/tsconfig": "^6.5.
|
|
58
|
-
"@xyo-network/account": "^3.18.
|
|
59
|
-
"@xyo-network/account-model": "^3.18.
|
|
60
|
-
"@xyo-network/archivist-memory": "^3.18.
|
|
61
|
-
"@xyo-network/archivist-model": "^3.18.
|
|
62
|
-
"@xyo-network/wallet": "^3.18.
|
|
63
|
-
"@xyo-network/xl1-protocol-sdk": "^1.5.
|
|
64
|
-
"knip": "^5.61.
|
|
55
|
+
"@types/node": "^24.0.8",
|
|
56
|
+
"@xylabs/assert": "^4.12.29",
|
|
57
|
+
"@xylabs/promise": "^4.12.29",
|
|
58
|
+
"@xylabs/ts-scripts-yarn3": "^6.5.12",
|
|
59
|
+
"@xylabs/tsconfig": "^6.5.12",
|
|
60
|
+
"@xyo-network/account": "^3.18.10",
|
|
61
|
+
"@xyo-network/account-model": "^3.18.10",
|
|
62
|
+
"@xyo-network/archivist-memory": "^3.18.10",
|
|
63
|
+
"@xyo-network/archivist-model": "^3.18.10",
|
|
64
|
+
"@xyo-network/wallet": "^3.18.10",
|
|
65
|
+
"@xyo-network/xl1-protocol-sdk": "^1.5.36",
|
|
66
|
+
"knip": "^5.61.3",
|
|
65
67
|
"typescript": "^5.8.3",
|
|
66
|
-
"vitest": "^3.2.
|
|
68
|
+
"vitest": "^3.2.4"
|
|
67
69
|
},
|
|
68
70
|
"engines": {
|
|
69
71
|
"node": ">=22.3 <23"
|
|
@@ -12,11 +12,14 @@ import {
|
|
|
12
12
|
export const validateBlock: BlockValidatorFunction = async (
|
|
13
13
|
block: BlockBoundWitness,
|
|
14
14
|
chainId?: Address,
|
|
15
|
-
): Promise<
|
|
16
|
-
const errors:
|
|
15
|
+
): Promise<BlockValidationError[]> => {
|
|
16
|
+
const errors: BlockValidationError[] = []
|
|
17
17
|
try {
|
|
18
|
+
const bwErrors = await BoundWitnessSignaturesValidator(block)
|
|
19
|
+
for (const bwError of bwErrors) {
|
|
20
|
+
errors.push(new BlockValidationError((block as WithStorageMeta<BlockBoundWitness>)?._hash ?? ZERO_HASH, block, 'BoundWitness validation failed', bwError))
|
|
21
|
+
}
|
|
18
22
|
const validators: BlockValidatorFunction[] = [
|
|
19
|
-
BoundWitnessSignaturesValidator,
|
|
20
23
|
BlockFieldsValidator,
|
|
21
24
|
BlockPreviousHashValidator,
|
|
22
25
|
BlockJsonSchemaValidator(),
|
|
@@ -26,7 +29,7 @@ export const validateBlock: BlockValidatorFunction = async (
|
|
|
26
29
|
validators.map(validator => validator(block, chainId)),
|
|
27
30
|
)).flat())
|
|
28
31
|
} catch (ex) {
|
|
29
|
-
errors.push(new BlockValidationError((block as WithStorageMeta<BlockBoundWitness>)?._hash ?? ZERO_HASH, block, 'validation excepted'
|
|
32
|
+
errors.push(new BlockValidationError((block as WithStorageMeta<BlockBoundWitness>)?._hash ?? ZERO_HASH, block, 'validation excepted', ex))
|
|
30
33
|
}
|
|
31
34
|
return errors
|
|
32
35
|
}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
export const BlockAllowedPayloadSchemasValidator: BlockValidatorFunction = (
|
|
8
8
|
block: BlockBoundWitness,
|
|
9
9
|
) => {
|
|
10
|
-
const errors:
|
|
10
|
+
const errors: BlockValidationError[] = []
|
|
11
11
|
try {
|
|
12
12
|
for (const schema of block.payload_schemas) {
|
|
13
13
|
if (!isAllowedBlockPayloadSchema(schema)) {
|
|
@@ -18,11 +18,12 @@ export const BlockAllowedPayloadSchemasValidator: BlockValidatorFunction = (
|
|
|
18
18
|
))
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
} catch (
|
|
21
|
+
} catch (ex) {
|
|
22
22
|
errors.push(new BlockValidationError(
|
|
23
23
|
(block as WithStorageMeta<BlockBoundWitness>)?._hash ?? ZERO_HASH,
|
|
24
24
|
block,
|
|
25
|
-
`
|
|
25
|
+
`validation excepted: ${ex}`,
|
|
26
|
+
ex,
|
|
26
27
|
))
|
|
27
28
|
}
|
|
28
29
|
return errors
|
|
@@ -12,7 +12,7 @@ export const BlockFieldsValidator: BlockValidatorFunction = (
|
|
|
12
12
|
block: BlockBoundWitness,
|
|
13
13
|
chainId?: Address,
|
|
14
14
|
) => {
|
|
15
|
-
const errors:
|
|
15
|
+
const errors: BlockValidationError[] = []
|
|
16
16
|
try {
|
|
17
17
|
if (isDefined(chainId) && block.chain !== chainId.toLowerCase()) {
|
|
18
18
|
errors.push(new BlockValidationError((block as WithStorageMeta<BlockBoundWitness>)?._hash ?? ZERO_HASH, block, 'Invalid chain id'))
|
|
@@ -34,11 +34,12 @@ export const BlockFieldsValidator: BlockValidatorFunction = (
|
|
|
34
34
|
`Duplicate Transaction Hashes: ${txHashes}`,
|
|
35
35
|
))
|
|
36
36
|
}
|
|
37
|
-
} catch (
|
|
37
|
+
} catch (ex) {
|
|
38
38
|
errors.push(new BlockValidationError(
|
|
39
39
|
(block as WithStorageMeta<BlockBoundWitness>)?._hash ?? ZERO_HASH,
|
|
40
40
|
block,
|
|
41
|
-
`
|
|
41
|
+
`validation excepted: ${ex}`,
|
|
42
|
+
ex,
|
|
42
43
|
))
|
|
43
44
|
}
|
|
44
45
|
return errors
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ZERO_HASH } from '@xylabs/hex'
|
|
2
|
-
import { toJsonString } from '@xylabs/object'
|
|
3
2
|
import { BlockBoundWitnessWithStorageMetaJsonSchema } from '@xyo-network/chain-schema'
|
|
4
3
|
import type { WithStorageMeta } from '@xyo-network/payload-model'
|
|
5
4
|
import {
|
|
@@ -8,29 +7,33 @@ import {
|
|
|
8
7
|
import type { AnySchema } from 'ajv'
|
|
9
8
|
import { Ajv } from 'ajv'
|
|
10
9
|
|
|
11
|
-
export const BlockJsonSchemaValidator = (jsonSchema: AnySchema = BlockBoundWitnessWithStorageMetaJsonSchema): BlockValidatorFunction =>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
10
|
+
export const BlockJsonSchemaValidator = (jsonSchema: AnySchema = BlockBoundWitnessWithStorageMetaJsonSchema): BlockValidatorFunction => {
|
|
11
|
+
const ajv = new Ajv({ allErrors: true, strict: true })
|
|
12
|
+
const validate = ajv.compile(jsonSchema)
|
|
13
|
+
return async (
|
|
14
|
+
block: BlockBoundWitness,
|
|
15
|
+
) => {
|
|
16
|
+
const errors: BlockValidationError[] = []
|
|
17
|
+
try {
|
|
18
|
+
await validate(block)
|
|
19
|
+
if ((validate.errors ?? []).length > 0) {
|
|
20
|
+
const error = new BlockValidationError(
|
|
21
|
+
(block as WithStorageMeta<BlockBoundWitness>)?._hash ?? ZERO_HASH,
|
|
22
|
+
block,
|
|
23
|
+
`failed JSON schema validation: ${ajv.errorsText(validate.errors, { separator: '\n' })}`,
|
|
24
|
+
)
|
|
25
|
+
error.cause = validate.errors
|
|
26
|
+
errors.push(error)
|
|
27
|
+
}
|
|
28
|
+
} catch (ex) {
|
|
21
29
|
const error = new BlockValidationError(
|
|
22
30
|
(block as WithStorageMeta<BlockBoundWitness>)?._hash ?? ZERO_HASH,
|
|
23
31
|
block,
|
|
24
|
-
`
|
|
32
|
+
`validation excepted: ${ex}`,
|
|
25
33
|
)
|
|
26
|
-
|
|
34
|
+
error.cause = ex
|
|
35
|
+
errors.push(error)
|
|
27
36
|
}
|
|
28
|
-
|
|
29
|
-
errors.push(new BlockValidationError(
|
|
30
|
-
(block as WithStorageMeta<BlockBoundWitness>)?._hash ?? ZERO_HASH,
|
|
31
|
-
block,
|
|
32
|
-
`Failed BlockJsonSchemaValidator: ${e instanceof Error ? e.message : String(e)}`,
|
|
33
|
-
))
|
|
37
|
+
return errors
|
|
34
38
|
}
|
|
35
|
-
return errors
|
|
36
39
|
}
|
|
@@ -6,7 +6,7 @@ import { BlockValidationError } from '@xyo-network/xl1-protocol'
|
|
|
6
6
|
export const BlockPreviousHashValidator: BlockValidatorFunction = (
|
|
7
7
|
block: BlockBoundWitness,
|
|
8
8
|
) => {
|
|
9
|
-
const errors:
|
|
9
|
+
const errors: BlockValidationError[] = []
|
|
10
10
|
try {
|
|
11
11
|
const blockNumber = block.block
|
|
12
12
|
if (blockNumber > 0n) {
|
|
@@ -23,12 +23,14 @@ export const BlockPreviousHashValidator: BlockValidatorFunction = (
|
|
|
23
23
|
// we have a negative block number
|
|
24
24
|
errors.push(new BlockValidationError((block as WithStorageMeta<BlockBoundWitness>)?._hash ?? ZERO_HASH, block, 'invalid block number'))
|
|
25
25
|
}
|
|
26
|
-
} catch (
|
|
27
|
-
|
|
26
|
+
} catch (ex) {
|
|
27
|
+
const error = new BlockValidationError(
|
|
28
28
|
(block as WithStorageMeta<BlockBoundWitness>)?._hash ?? ZERO_HASH,
|
|
29
29
|
block,
|
|
30
|
-
`Failed BlockPreviousHashValidator: ${
|
|
31
|
-
)
|
|
30
|
+
`Failed BlockPreviousHashValidator: ${ex}`,
|
|
31
|
+
)
|
|
32
|
+
error.cause = ex
|
|
33
|
+
errors.push(error)
|
|
32
34
|
}
|
|
33
35
|
return errors
|
|
34
36
|
}
|
|
@@ -18,8 +18,8 @@ export const BoundWitnessReferencesValidator
|
|
|
18
18
|
// eslint-disable-next-line complexity
|
|
19
19
|
= <T extends BoundWitness = BoundWitness>(allowedSchemas?: Schema[]): HydratedBoundWitnessValidationFunction<T> => (
|
|
20
20
|
[bw, payloadSet]: HydratedBoundWitnessWithHashStorageMeta<T>,
|
|
21
|
-
): Promisable<
|
|
22
|
-
const errors:
|
|
21
|
+
): Promisable<HydratedBoundWitnessValidationError[]> => {
|
|
22
|
+
const errors: HydratedBoundWitnessValidationError[] = []
|
|
23
23
|
try {
|
|
24
24
|
const payloads = getPayloadsFromPayloadArray(payloadSet, bw.payload_hashes)
|
|
25
25
|
if (payloads.length !== bw.payload_hashes.length) {
|
|
@@ -49,7 +49,9 @@ export const BoundWitnessReferencesValidator
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
} catch (ex) {
|
|
52
|
-
|
|
52
|
+
const error = new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], `validation excepted: ${ex}`)
|
|
53
|
+
error.cause = ex
|
|
54
|
+
errors.push(error)
|
|
53
55
|
}
|
|
54
56
|
return errors
|
|
55
57
|
}
|
|
@@ -10,17 +10,19 @@ import { BoundWitnessValidationError } from '@xyo-network/xl1-protocol'
|
|
|
10
10
|
export const BoundWitnessSignaturesValidator: BoundWitnessValidationFunction = async (
|
|
11
11
|
bw: BoundWitness,
|
|
12
12
|
) => {
|
|
13
|
-
const errors:
|
|
13
|
+
const errors: BoundWitnessValidationError[] = []
|
|
14
14
|
try {
|
|
15
15
|
const dataHash = await BoundWitnessBuilder.dataHash(bw)
|
|
16
|
-
const results: [Address,
|
|
16
|
+
const results: [Address, Error[]][] = await Promise.all(bw.addresses.map(async (address, index) => {
|
|
17
17
|
return [address, await BoundWitnessValidator.validateSignature(toArrayBuffer(dataHash), toArrayBuffer(address), toArrayBuffer(bw.$signatures[index]))]
|
|
18
18
|
}))
|
|
19
19
|
for (const [, bwErrors] of results) {
|
|
20
|
-
|
|
20
|
+
for (const bwError of bwErrors) {
|
|
21
|
+
errors.push(new BoundWitnessValidationError((bw as WithStorageMeta<BoundWitness>)?._hash ?? ZERO_HASH, bw, 'validation errors', bwError))
|
|
22
|
+
}
|
|
21
23
|
}
|
|
22
24
|
} catch (ex) {
|
|
23
|
-
errors.push(new BoundWitnessValidationError((bw as WithStorageMeta<BoundWitness>)?._hash ?? ZERO_HASH, bw, 'validation excepted'
|
|
25
|
+
errors.push(new BoundWitnessValidationError((bw as WithStorageMeta<BoundWitness>)?._hash ?? ZERO_HASH, bw, 'validation excepted', ex))
|
|
24
26
|
}
|
|
25
27
|
return errors
|
|
26
28
|
}
|
|
@@ -1,20 +1,25 @@
|
|
|
1
|
-
import type { Promisable } from '@xylabs/promise'
|
|
2
|
-
import { transactionsFromHydratedBlock } from '@xyo-network/chain-protocol'
|
|
3
1
|
import type { HydratedBlock, InBlockPayloadValidationFunction } from '@xyo-network/xl1-protocol'
|
|
2
|
+
import { InBlockPayloadValidationError } from '@xyo-network/xl1-protocol'
|
|
3
|
+
import { transactionsFromHydratedBlock } from '@xyo-network/xl1-protocol-sdk'
|
|
4
4
|
|
|
5
5
|
export const validateElevatedFromBlock: InBlockPayloadValidationFunction = (
|
|
6
6
|
payload,
|
|
7
7
|
block: HydratedBlock,
|
|
8
|
-
)
|
|
9
|
-
const errors:
|
|
8
|
+
) => {
|
|
9
|
+
const errors: InBlockPayloadValidationError[] = []
|
|
10
10
|
try {
|
|
11
11
|
const txs = transactionsFromHydratedBlock(block)
|
|
12
12
|
const allTxPayloadHashes = new Set(txs.flatMap(tx => tx.payload_hashes))
|
|
13
13
|
if (allTxPayloadHashes.has(payload._hash)) {
|
|
14
|
-
errors.push(new
|
|
14
|
+
errors.push(new InBlockPayloadValidationError(
|
|
15
|
+
block[0]?._hash,
|
|
16
|
+
block,
|
|
17
|
+
payload,
|
|
18
|
+
`Transaction may not include block payload hash [${payload.schema}]: ${payload._hash}`,
|
|
19
|
+
))
|
|
15
20
|
}
|
|
16
|
-
} catch (
|
|
17
|
-
errors.push(new
|
|
21
|
+
} catch (ex) {
|
|
22
|
+
errors.push(new InBlockPayloadValidationError(block[0]?._hash, block, payload, `validation excepted: ${ex}`, ex))
|
|
18
23
|
}
|
|
19
24
|
return errors
|
|
20
25
|
}
|
|
@@ -1,24 +1,30 @@
|
|
|
1
|
-
import type { Promisable } from '@xylabs/promise'
|
|
2
|
-
import { transactionsFromHydratedBlock } from '@xyo-network/chain-protocol'
|
|
3
1
|
import type { HydratedBlock, InBlockPayloadValidationFunction } from '@xyo-network/xl1-protocol'
|
|
2
|
+
import { InBlockPayloadValidationError } from '@xyo-network/xl1-protocol'
|
|
3
|
+
import { transactionsFromHydratedBlock } from '@xyo-network/xl1-protocol-sdk'
|
|
4
4
|
|
|
5
5
|
export const validateElevatedFromTransaction: InBlockPayloadValidationFunction = (
|
|
6
6
|
payload,
|
|
7
7
|
block: HydratedBlock,
|
|
8
|
-
)
|
|
9
|
-
const errors:
|
|
8
|
+
) => {
|
|
9
|
+
const errors: InBlockPayloadValidationError[] = []
|
|
10
10
|
try {
|
|
11
11
|
const txs = transactionsFromHydratedBlock(block)
|
|
12
12
|
if (txs.length > 0) {
|
|
13
13
|
const hashes = txs.flatMap(tx => tx.payload_hashes)
|
|
14
14
|
if (!hashes.includes(payload._hash)) {
|
|
15
|
-
errors.push(new
|
|
15
|
+
errors.push(new InBlockPayloadValidationError(payload._hash, block, payload, 'Transaction does not include payload'))
|
|
16
16
|
}
|
|
17
17
|
} else {
|
|
18
|
-
errors.push(new
|
|
18
|
+
errors.push(new InBlockPayloadValidationError(payload._hash, block, payload, 'No Transactions in block'))
|
|
19
19
|
}
|
|
20
|
-
} catch (
|
|
21
|
-
errors.push(new
|
|
20
|
+
} catch (ex) {
|
|
21
|
+
errors.push(new InBlockPayloadValidationError(
|
|
22
|
+
payload._hash,
|
|
23
|
+
block,
|
|
24
|
+
payload,
|
|
25
|
+
`Failed validateElevatedFromTransaction: ${ex}`,
|
|
26
|
+
ex,
|
|
27
|
+
))
|
|
22
28
|
}
|
|
23
29
|
return errors
|
|
24
30
|
}
|
|
@@ -7,8 +7,8 @@ export const validateIncludedInBlock = (payload: WithStorageMeta<Payload>, block
|
|
|
7
7
|
if (!block.payload_hashes.includes(payload._hash)) {
|
|
8
8
|
errors.push(new Error('Payload not included in block'))
|
|
9
9
|
}
|
|
10
|
-
} catch (
|
|
11
|
-
errors.push(new Error(`Failed validateIncludedInBlock: ${
|
|
10
|
+
} catch (ex) {
|
|
11
|
+
errors.push(new Error(`Failed validateIncludedInBlock: ${ex}`))
|
|
12
12
|
}
|
|
13
13
|
return errors
|
|
14
14
|
}
|
|
@@ -1,22 +1,26 @@
|
|
|
1
|
+
import { ZERO_HASH } from '@xylabs/hex'
|
|
1
2
|
import { isStorageMeta } from '@xyo-network/payload-model'
|
|
2
3
|
import type { HydratedBlock, InBlockPayloadValidationFunction } from '@xyo-network/xl1-protocol'
|
|
3
|
-
import { isTransactionBoundWitness } from '@xyo-network/xl1-protocol'
|
|
4
|
+
import { InBlockPayloadValidationError, isTransactionBoundWitness } from '@xyo-network/xl1-protocol'
|
|
4
5
|
|
|
5
6
|
import { BoundWitnessSignaturesValidator } from '../../boundwitness/index.ts'
|
|
6
7
|
|
|
7
8
|
export const validateTransactionInBlock: InBlockPayloadValidationFunction = async (
|
|
8
9
|
payload,
|
|
9
|
-
|
|
10
|
-
): Promise<
|
|
11
|
-
const errors:
|
|
10
|
+
block: HydratedBlock,
|
|
11
|
+
): Promise<InBlockPayloadValidationError[]> => {
|
|
12
|
+
const errors: InBlockPayloadValidationError[] = []
|
|
12
13
|
try {
|
|
13
14
|
if (isTransactionBoundWitness(payload) && isStorageMeta(payload)) {
|
|
14
|
-
|
|
15
|
+
const txErrors = await BoundWitnessSignaturesValidator(payload)
|
|
16
|
+
for (const txError of txErrors) {
|
|
17
|
+
errors.push(new InBlockPayloadValidationError(payload._hash, block, payload, `BoundWitnessSignaturesValidator error: ${txError}`, txError))
|
|
18
|
+
}
|
|
15
19
|
} else {
|
|
16
|
-
errors.push(new
|
|
20
|
+
errors.push(new InBlockPayloadValidationError(payload._hash, block, payload, 'Payload failed isTransactionBoundWitness or isStorageMeta'))
|
|
17
21
|
}
|
|
18
|
-
} catch (
|
|
19
|
-
errors.push(new
|
|
22
|
+
} catch (ex) {
|
|
23
|
+
errors.push(new InBlockPayloadValidationError(payload._hash ?? ZERO_HASH, block, payload, `validation excepted: ${ex}`, ex))
|
|
20
24
|
}
|
|
21
25
|
return errors
|
|
22
26
|
}
|
|
@@ -23,8 +23,8 @@ export const validateTypedPayloadInBlock = async <T extends Payload>(
|
|
|
23
23
|
} else {
|
|
24
24
|
errors.push(new Error('Payload failed identityFunction or isElevated or isStorageMeta'))
|
|
25
25
|
}
|
|
26
|
-
} catch (
|
|
27
|
-
errors.push(new Error(`Failed validateTypedPayloadInBlock: ${
|
|
26
|
+
} catch (ex) {
|
|
27
|
+
errors.push(new Error(`Failed validateTypedPayloadInBlock: ${ex}`))
|
|
28
28
|
}
|
|
29
29
|
return errors
|
|
30
30
|
}
|
|
@@ -7,16 +7,20 @@ import { validateTypedPayloadInBlock } from '../lib/index.ts'
|
|
|
7
7
|
export const validateChainStakeIntentInBlock: InBlockPayloadValidationFunction = async (
|
|
8
8
|
payload,
|
|
9
9
|
block: HydratedBlock,
|
|
10
|
-
)
|
|
11
|
-
const errors:
|
|
10
|
+
) => {
|
|
11
|
+
const errors: InBlockPayloadValidationError[] = []
|
|
12
12
|
try {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const typedErrors = await validateTypedPayloadInBlock(payload, block, isChainStakeIntent)
|
|
14
|
+
for (const typedError of typedErrors) {
|
|
15
|
+
errors.push(new InBlockPayloadValidationError(payload._hash, block, payload, `validateTypedPayloadInBlock error: ${typedError}`, typedError))
|
|
16
|
+
}
|
|
17
|
+
} catch (ex) {
|
|
15
18
|
errors.push(new InBlockPayloadValidationError(
|
|
16
19
|
block[0]?._hash ?? ZERO_HASH,
|
|
17
20
|
block,
|
|
18
21
|
payload,
|
|
19
|
-
`
|
|
22
|
+
`validation excepted: ${ex}`,
|
|
23
|
+
ex,
|
|
20
24
|
))
|
|
21
25
|
}
|
|
22
26
|
return errors
|
|
@@ -7,16 +7,20 @@ import { validateTypedPayloadInBlock } from '../lib/index.ts'
|
|
|
7
7
|
export const validateHashInBlock: InBlockPayloadValidationFunction = async (
|
|
8
8
|
payload,
|
|
9
9
|
block: HydratedBlock,
|
|
10
|
-
)
|
|
11
|
-
const errors: (InBlockPayloadValidationError
|
|
10
|
+
) => {
|
|
11
|
+
const errors: (InBlockPayloadValidationError)[] = []
|
|
12
12
|
try {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const typedErrors = await validateTypedPayloadInBlock(payload, block, isHashPayload)
|
|
14
|
+
for (const typedError of typedErrors) {
|
|
15
|
+
errors.push(new InBlockPayloadValidationError(payload._hash, block, payload, `validateTypedPayloadInBlock error: ${typedError}`, typedError))
|
|
16
|
+
}
|
|
17
|
+
} catch (ex) {
|
|
15
18
|
errors.push(new InBlockPayloadValidationError(
|
|
16
19
|
(block?.[0])?._hash ?? ZERO_HASH,
|
|
17
20
|
block,
|
|
18
21
|
payload,
|
|
19
|
-
`
|
|
22
|
+
`validation excepted: ${ex}`,
|
|
23
|
+
ex,
|
|
20
24
|
))
|
|
21
25
|
}
|
|
22
26
|
return errors
|
|
@@ -8,16 +8,20 @@ import { validateTypedPayloadInBlock } from '../lib/index.ts'
|
|
|
8
8
|
export const validateSchemaInBlock: InBlockPayloadValidationFunction = async (
|
|
9
9
|
payload,
|
|
10
10
|
block: HydratedBlock,
|
|
11
|
-
)
|
|
12
|
-
const errors:
|
|
11
|
+
) => {
|
|
12
|
+
const errors: InBlockPayloadValidationError[] = []
|
|
13
13
|
try {
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const typedErrors = await validateTypedPayloadInBlock(payload, block, isSchemaPayload)
|
|
15
|
+
for (const typedError of typedErrors) {
|
|
16
|
+
errors.push(new InBlockPayloadValidationError(payload._hash, block, payload, `validateTypedPayloadInBlock error: ${typedError}`, typedError))
|
|
17
|
+
}
|
|
18
|
+
} catch (ex) {
|
|
16
19
|
errors.push(new InBlockPayloadValidationError(
|
|
17
20
|
(block?.[0])?._hash ?? ZERO_HASH,
|
|
18
21
|
block,
|
|
19
22
|
payload,
|
|
20
|
-
`Failed validateSchemaInBlock: ${
|
|
23
|
+
`Failed validateSchemaInBlock: ${ex}`,
|
|
24
|
+
ex,
|
|
21
25
|
))
|
|
22
26
|
}
|
|
23
27
|
return errors
|
|
@@ -10,16 +10,20 @@ import { validateTypedPayloadInBlock } from '../lib/index.ts'
|
|
|
10
10
|
export const validateTransferInBlock: InBlockPayloadValidationFunction = async (
|
|
11
11
|
payload,
|
|
12
12
|
block: HydratedBlock,
|
|
13
|
-
)
|
|
14
|
-
const errors:
|
|
13
|
+
) => {
|
|
14
|
+
const errors: InBlockPayloadValidationError[] = []
|
|
15
15
|
try {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const typedErrors = await validateTypedPayloadInBlock(payload, block, isTransfer)
|
|
17
|
+
for (const typedError of typedErrors) {
|
|
18
|
+
errors.push(new InBlockPayloadValidationError(payload._hash, block, payload, `validateTypedPayloadInBlock error: ${typedError}`, typedError))
|
|
19
|
+
}
|
|
20
|
+
} catch (ex) {
|
|
18
21
|
errors.push(new InBlockPayloadValidationError(
|
|
19
22
|
(block?.[0])?._hash ?? ZERO_HASH,
|
|
20
23
|
block,
|
|
21
24
|
payload,
|
|
22
|
-
`Failed validateTransferInBlock: ${
|
|
25
|
+
`Failed validateTransferInBlock: ${ex}`,
|
|
26
|
+
ex,
|
|
23
27
|
))
|
|
24
28
|
}
|
|
25
29
|
return errors
|
|
@@ -27,8 +27,8 @@ const payloadValidators: Partial<Record<Schema, InBlockPayloadValidationFunction
|
|
|
27
27
|
export const validatePayloadInBlock: InBlockPayloadValidationFunction = async (
|
|
28
28
|
payload,
|
|
29
29
|
block: HydratedBlock,
|
|
30
|
-
): Promise<
|
|
31
|
-
const errors:
|
|
30
|
+
): Promise<InBlockPayloadValidationError[]> => {
|
|
31
|
+
const errors: InBlockPayloadValidationError[] = []
|
|
32
32
|
try {
|
|
33
33
|
const validator = payloadValidators[payload.schema]
|
|
34
34
|
if (validator) {
|
|
@@ -36,13 +36,15 @@ export const validatePayloadInBlock: InBlockPayloadValidationFunction = async (
|
|
|
36
36
|
} else {
|
|
37
37
|
errors.push(new InBlockPayloadValidationError((block?.[0])?._hash ?? ZERO_HASH, block, payload, `Unsupported payload schema: ${payload.schema}`))
|
|
38
38
|
}
|
|
39
|
-
} catch (
|
|
40
|
-
|
|
39
|
+
} catch (ex) {
|
|
40
|
+
const error = new InBlockPayloadValidationError(
|
|
41
41
|
(block?.[0])?._hash ?? ZERO_HASH,
|
|
42
42
|
block,
|
|
43
43
|
payload,
|
|
44
|
-
`
|
|
45
|
-
)
|
|
44
|
+
`validation excepted: ${ex}`,
|
|
45
|
+
)
|
|
46
|
+
error.cause = ex
|
|
47
|
+
errors.push(error)
|
|
46
48
|
}
|
|
47
49
|
return errors
|
|
48
50
|
}
|
|
@@ -10,21 +10,28 @@ export const validateHydratedBlock: HydratedBlockValidationFunction = async (
|
|
|
10
10
|
hydratedBlock: HydratedBlock,
|
|
11
11
|
chainId?: Address,
|
|
12
12
|
additionalValidators: HydratedBlockValidationFunction[] = [],
|
|
13
|
-
)
|
|
14
|
-
const errors:
|
|
13
|
+
) => {
|
|
14
|
+
const errors: HydratedBlockValidationError[] = []
|
|
15
15
|
try {
|
|
16
|
-
|
|
16
|
+
const validateBlockErrors = await validateBlock(hydratedBlock[0], chainId)
|
|
17
|
+
for (const validateBlockError of validateBlockErrors) {
|
|
18
|
+
errors.push(new HydratedBlockValidationError(hydratedBlock[0]._hash, hydratedBlock, `validateBlock error: ${validateBlockError}`, validateBlockError))
|
|
19
|
+
}
|
|
20
|
+
const bwRefErrors = await BoundWitnessReferencesValidator()(hydratedBlock)
|
|
21
|
+
for (const bwRefError of bwRefErrors) {
|
|
22
|
+
errors.push(new HydratedBlockValidationError(hydratedBlock[0]._hash, hydratedBlock, `boundwitness reference error: ${bwRefError}`, bwRefError))
|
|
23
|
+
}
|
|
17
24
|
const validators: HydratedBlockValidationFunction[] = [
|
|
18
|
-
BoundWitnessReferencesValidator(),
|
|
19
25
|
PayloadsInBlockValidator,
|
|
20
26
|
...additionalValidators,
|
|
21
27
|
]
|
|
22
28
|
errors.push(...(await Promise.all(validators.map(v => v(hydratedBlock, chainId)))).flat())
|
|
23
|
-
} catch (
|
|
29
|
+
} catch (ex) {
|
|
24
30
|
errors.push(new HydratedBlockValidationError(
|
|
25
31
|
hydratedBlock?.[0]?._hash ?? ZERO_HASH,
|
|
26
32
|
hydratedBlock,
|
|
27
|
-
`Failed validateHydratedBlock: ${
|
|
33
|
+
`Failed validateHydratedBlock: ${ex}`,
|
|
34
|
+
ex,
|
|
28
35
|
))
|
|
29
36
|
}
|
|
30
37
|
return errors
|
|
@@ -11,7 +11,7 @@ import { validatePayloadInBlock } from '../../elevatedPayload/validatePayloadInB
|
|
|
11
11
|
export const PayloadsInBlockValidator: HydratedBlockValidationFunction = async (
|
|
12
12
|
[block, payloads]: HydratedBlock,
|
|
13
13
|
) => {
|
|
14
|
-
const errors:
|
|
14
|
+
const errors: HydratedBlockValidationError[] = []
|
|
15
15
|
try {
|
|
16
16
|
const payloadMap: Partial<Record<Hash, WithHashStorageMeta<Payload>>> = {}
|
|
17
17
|
for (const payload of payloads) {
|
|
@@ -25,7 +25,15 @@ export const PayloadsInBlockValidator: HydratedBlockValidationFunction = async (
|
|
|
25
25
|
const schema = block.payload_schemas[i]
|
|
26
26
|
const payload = payloadMap[hash]
|
|
27
27
|
if (payload) {
|
|
28
|
-
|
|
28
|
+
const payloadInBlockErrors = await validatePayloadInBlock(payload, [block, payloads])
|
|
29
|
+
for (const payloadInBlockError of payloadInBlockErrors) {
|
|
30
|
+
errors.push(new HydratedBlockValidationError(
|
|
31
|
+
block?._hash ?? ZERO_HASH,
|
|
32
|
+
[block, payloads],
|
|
33
|
+
`validatePayloadInBlock error: ${payloadInBlockError}`,
|
|
34
|
+
payloadInBlockError,
|
|
35
|
+
))
|
|
36
|
+
}
|
|
29
37
|
delete remainingPayloads[hash]
|
|
30
38
|
} else {
|
|
31
39
|
errors.push(new HydratedBlockValidationError(block?._hash ?? ZERO_HASH, [block, payloads], `missing payload ${hash} ${schema}`))
|
|
@@ -35,11 +43,12 @@ export const PayloadsInBlockValidator: HydratedBlockValidationFunction = async (
|
|
|
35
43
|
if (Object.keys(remainingPayloads).length > 0) {
|
|
36
44
|
errors.push(new HydratedBlockValidationError(block?._hash ?? ZERO_HASH, [block, payloads], `extra payloads ${Object.keys(payloadMap).join(', ')}`))
|
|
37
45
|
}
|
|
38
|
-
} catch (
|
|
46
|
+
} catch (ex) {
|
|
39
47
|
errors.push(new HydratedBlockValidationError(
|
|
40
48
|
block?._hash ?? ZERO_HASH,
|
|
41
49
|
[block, payloads],
|
|
42
|
-
`Failed PayloadsInBlockValidator: ${
|
|
50
|
+
`Failed PayloadsInBlockValidator: ${ex}`,
|
|
51
|
+
ex,
|
|
43
52
|
))
|
|
44
53
|
}
|
|
45
54
|
|