@xyo-network/chain-validation 1.5.32 → 1.5.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/neutral/index.mjs +81 -61
  2. package/dist/neutral/index.mjs.map +1 -1
  3. package/dist/types/block/validateBlock.d.ts.map +1 -1
  4. package/dist/types/block/validators/AllowedPayloadSchemas.d.ts.map +1 -1
  5. package/dist/types/block/validators/Fields.d.ts.map +1 -1
  6. package/dist/types/block/validators/JsonSchema.d.ts.map +1 -1
  7. package/dist/types/block/validators/PreviousHash.d.ts.map +1 -1
  8. package/dist/types/boundwitness/validators/BoundWitnessReferences.d.ts.map +1 -1
  9. package/dist/types/boundwitness/validators/BoundWitnessSignatures.d.ts.map +1 -1
  10. package/dist/types/elevatedPayload/payloads/validateChainStakeIntentInBlock.d.ts.map +1 -1
  11. package/dist/types/elevatedPayload/payloads/validateHashInBlock.d.ts.map +1 -1
  12. package/dist/types/elevatedPayload/payloads/validateSchemaInBlock.d.ts.map +1 -1
  13. package/dist/types/elevatedPayload/payloads/validateTransferInBlock.d.ts.map +1 -1
  14. package/dist/types/elevatedPayload/validatePayloadInBlock.d.ts.map +1 -1
  15. package/dist/types/hydratedBlock/validateHydratedBlock.d.ts.map +1 -1
  16. package/dist/types/hydratedBlock/validators/Payloads.d.ts.map +1 -1
  17. package/dist/types/hydratedBlockState/validateHydratedBlockState.d.ts.map +1 -1
  18. package/dist/types/hydratedBlockState/validators/RequiredBalance.d.ts.map +1 -1
  19. package/dist/types/transaction/validators/TransactionDurationValidator.d.ts.map +1 -1
  20. package/dist/types/transaction/validators/TransactionElevationValidator.d.ts.map +1 -1
  21. package/dist/types/transaction/validators/TransactionFromValidator.d.ts.map +1 -1
  22. package/dist/types/transaction/validators/TransactionGasValidator.d.ts.map +1 -1
  23. package/dist/types/transaction/validators/TransactionJsonSchemaValidator.d.ts.map +1 -1
  24. package/package.json +11 -11
  25. package/src/block/validateBlock.ts +3 -2
  26. package/src/block/validators/AllowedPayloadSchemas.ts +12 -2
  27. package/src/block/validators/Fields.ts +15 -4
  28. package/src/block/validators/JsonSchema.ts +13 -2
  29. package/src/block/validators/PreviousHash.ts +10 -5
  30. package/src/boundwitness/validators/BoundWitnessReferences.ts +8 -7
  31. package/src/boundwitness/validators/BoundWitnessSignatures.ts +3 -2
  32. package/src/elevatedPayload/payloads/validateChainStakeIntentInBlock.ts +7 -1
  33. package/src/elevatedPayload/payloads/validateHashInBlock.ts +7 -1
  34. package/src/elevatedPayload/payloads/validateSchemaInBlock.ts +7 -1
  35. package/src/elevatedPayload/payloads/validateTransferInBlock.ts +7 -1
  36. package/src/elevatedPayload/validatePayloadInBlock.ts +8 -2
  37. package/src/hydratedBlock/validateHydratedBlock.ts +6 -2
  38. package/src/hydratedBlock/validators/Payloads.ts +8 -4
  39. package/src/hydratedBlockState/validateHydratedBlockState.ts +2 -1
  40. package/src/hydratedBlockState/validators/RequiredBalance.ts +11 -2
  41. package/src/transaction/validators/TransactionDurationValidator.ts +15 -5
  42. package/src/transaction/validators/TransactionElevationValidator.ts +7 -2
  43. package/src/transaction/validators/TransactionFromValidator.ts +16 -4
  44. package/src/transaction/validators/TransactionGasValidator.ts +28 -5
  45. package/src/transaction/validators/TransactionJsonSchemaValidator.ts +8 -2
  46. package/src/transaction/validators/TransactionProtocolValidator.ts +3 -3
@@ -1,4 +1,7 @@
1
+ import { ZERO_HASH } from '@xylabs/hex'
2
+ import { toJsonString } from '@xylabs/object'
1
3
  import { BlockBoundWitnessWithStorageMetaJsonSchema } from '@xyo-network/chain-schema'
4
+ import type { WithStorageMeta } from '@xyo-network/payload-model'
2
5
  import {
3
6
  type BlockBoundWitness, BlockValidationError, type BlockValidatorFunction,
4
7
  } from '@xyo-network/xl1-protocol'
@@ -15,11 +18,19 @@ export const BlockJsonSchemaValidator = (jsonSchema: AnySchema = BlockBoundWitne
15
18
  const validate = ajv.compile(jsonSchema)
16
19
  await validate(block)
17
20
  if ((validate.errors ?? []).length > 0) {
18
- const error = new BlockValidationError(block, 'failed JSON schema validation: ')
21
+ const error = new BlockValidationError(
22
+ (block as WithStorageMeta<BlockBoundWitness>)?._hash ?? ZERO_HASH,
23
+ block,
24
+ `failed JSON schema validation: ${toJsonString(block, 10)} ${toJsonString(validate.errors, 10)}`,
25
+ )
19
26
  errors.push(error, ...validate.errors?.map(e => new Error(` ${e.instancePath} ${e.message ?? ''}`)) ?? [])
20
27
  }
21
28
  } catch (e) {
22
- errors.push(new BlockValidationError(block, `Failed BlockJsonSchemaValidator: ${e instanceof Error ? e.message : String(e)}`))
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
+ ))
23
34
  }
24
35
  return errors
25
36
  }
@@ -1,4 +1,5 @@
1
- import { isHash } from '@xylabs/hex'
1
+ import { isHash, ZERO_HASH } from '@xylabs/hex'
2
+ import type { WithStorageMeta } from '@xyo-network/payload-model'
2
3
  import type { BlockBoundWitness, BlockValidatorFunction } from '@xyo-network/xl1-protocol'
3
4
  import { BlockValidationError } from '@xyo-network/xl1-protocol'
4
5
 
@@ -11,19 +12,23 @@ export const BlockPreviousHashValidator: BlockValidatorFunction = (
11
12
  if (blockNumber > 0n) {
12
13
  // if this is not the first block, validate previous hashes
13
14
  if (!isHash(block.previous)) {
14
- errors.push(new BlockValidationError(block, 'previous hash is missing or invalid'))
15
+ errors.push(new BlockValidationError((block as WithStorageMeta<BlockBoundWitness>)?._hash ?? ZERO_HASH, block, 'previous hash is missing or invalid'))
15
16
  }
16
17
  } else if (blockNumber === 0) {
17
18
  // if this is the first block, validate previous hashes
18
19
  if (block.previous !== null) {
19
- errors.push(new BlockValidationError(block, 'previous hash should not be set'))
20
+ errors.push(new BlockValidationError((block as WithStorageMeta<BlockBoundWitness>)?._hash ?? ZERO_HASH, block, 'previous hash should not be set'))
20
21
  }
21
22
  } else {
22
23
  // we have a negative block number
23
- errors.push(new BlockValidationError(block, 'invalid block number'))
24
+ errors.push(new BlockValidationError((block as WithStorageMeta<BlockBoundWitness>)?._hash ?? ZERO_HASH, block, 'invalid block number'))
24
25
  }
25
26
  } catch (e) {
26
- errors.push(new BlockValidationError(block, `Failed BlockPreviousHashValidator: ${e instanceof Error ? e.message : String(e)}`))
27
+ errors.push(new BlockValidationError(
28
+ (block as WithStorageMeta<BlockBoundWitness>)?._hash ?? ZERO_HASH,
29
+ block,
30
+ `Failed BlockPreviousHashValidator: ${e instanceof Error ? e.message : String(e)}`,
31
+ ))
27
32
  }
28
33
  return errors
29
34
  }
@@ -1,4 +1,4 @@
1
- import type { Hash } from '@xylabs/hex'
1
+ import { type Hash, ZERO_HASH } from '@xylabs/hex'
2
2
  import type { Promisable } from '@xylabs/promise'
3
3
  import type { BoundWitness } from '@xyo-network/boundwitness-model'
4
4
  import type {
@@ -15,6 +15,7 @@ function getPayloadsFromPayloadArray(payloads: WithHashStorageMeta<Payload>[], h
15
15
  }
16
16
 
17
17
  export const BoundWitnessReferencesValidator
18
+ // eslint-disable-next-line complexity
18
19
  = <T extends BoundWitness = BoundWitness>(allowedSchemas?: Schema[]): HydratedBoundWitnessValidationFunction<T> => (
19
20
  [bw, payloadSet]: HydratedBoundWitnessWithHashStorageMeta<T>,
20
21
  ): Promisable<(HydratedBoundWitnessValidationError | Error)[]> => {
@@ -22,7 +23,7 @@ export const BoundWitnessReferencesValidator
22
23
  try {
23
24
  const payloads = getPayloadsFromPayloadArray(payloadSet, bw.payload_hashes)
24
25
  if (payloads.length !== bw.payload_hashes.length) {
25
- errors.push(new HydratedBoundWitnessValidationError([bw, payloadSet], 'unable to locate payloads'))
26
+ errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], 'unable to locate payloads'))
26
27
  }
27
28
 
28
29
  // check if payloads are valid and if their schemas match the declared schemas
@@ -32,23 +33,23 @@ export const BoundWitnessReferencesValidator
32
33
  const payloadDataHashIndex = bw.payload_hashes.indexOf(payload._dataHash)
33
34
  const payloadIndex = Math.max(payloadHashIndex, payloadDataHashIndex)
34
35
  if (payloadIndex === -1) {
35
- errors.push(new HydratedBoundWitnessValidationError([bw, payloadSet], 'payload hash not found'))
36
+ errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], 'payload hash not found'))
36
37
  }
37
38
 
38
39
  const declaredSchema = bw.payload_schemas[payloadIndex]
39
40
  if (declaredSchema !== payload.schema) {
40
- errors.push(new HydratedBoundWitnessValidationError([bw, payloadSet], 'mismatched schema'))
41
+ errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], 'mismatched schema'))
41
42
  }
42
43
 
43
44
  if (allowedSchemas && !allowedSchemas.includes(payload.schema)) {
44
- errors.push(new HydratedBoundWitnessValidationError([bw, payloadSet], `disallowed schema [${payload.schema}]`))
45
+ errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], `disallowed schema [${payload.schema}]`))
45
46
  }
46
47
  } else {
47
- errors.push(new HydratedBoundWitnessValidationError([bw, payloadSet], 'invalid payload'))
48
+ errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], 'invalid payload'))
48
49
  }
49
50
  }
50
51
  } catch (ex) {
51
- errors.push(new HydratedBoundWitnessValidationError([bw, payloadSet], 'validation excepted'), ex as Error)
52
+ errors.push(new HydratedBoundWitnessValidationError(bw?._hash ?? ZERO_HASH, [bw, payloadSet], 'validation excepted'), ex as Error)
52
53
  }
53
54
  return errors
54
55
  }
@@ -1,8 +1,9 @@
1
1
  import { toArrayBuffer } from '@xylabs/arraybuffer'
2
- import type { Address } from '@xylabs/hex'
2
+ import { type Address, ZERO_HASH } from '@xylabs/hex'
3
3
  import { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'
4
4
  import type { BoundWitness } from '@xyo-network/boundwitness-model'
5
5
  import { BoundWitnessValidator } from '@xyo-network/boundwitness-validator'
6
+ import type { WithStorageMeta } from '@xyo-network/payload-model'
6
7
  import type { BoundWitnessValidationFunction } from '@xyo-network/xl1-protocol'
7
8
  import { BoundWitnessValidationError } from '@xyo-network/xl1-protocol'
8
9
 
@@ -19,7 +20,7 @@ export const BoundWitnessSignaturesValidator: BoundWitnessValidationFunction = a
19
20
  errors.push(...bwErrors)
20
21
  }
21
22
  } catch (ex) {
22
- errors.push(new BoundWitnessValidationError(bw, 'validation excepted'), ex as Error)
23
+ errors.push(new BoundWitnessValidationError((bw as WithStorageMeta<BoundWitness>)?._hash ?? ZERO_HASH, bw, 'validation excepted'), ex as Error)
23
24
  }
24
25
  return errors
25
26
  }
@@ -1,3 +1,4 @@
1
+ import { ZERO_HASH } from '@xylabs/hex'
1
2
  import type { HydratedBlock, InBlockPayloadValidationFunction } from '@xyo-network/xl1-protocol'
2
3
  import { InBlockPayloadValidationError, isChainStakeIntent } from '@xyo-network/xl1-protocol'
3
4
 
@@ -11,7 +12,12 @@ export const validateChainStakeIntentInBlock: InBlockPayloadValidationFunction =
11
12
  try {
12
13
  errors.push(...await validateTypedPayloadInBlock(payload, block, isChainStakeIntent))
13
14
  } catch (e) {
14
- errors.push(new InBlockPayloadValidationError(block, payload, `Failed validateChainStakeIntentInBlock: ${e instanceof Error ? e.message : String(e)}`))
15
+ errors.push(new InBlockPayloadValidationError(
16
+ block[0]?._hash ?? ZERO_HASH,
17
+ block,
18
+ payload,
19
+ `Failed validateChainStakeIntentInBlock: ${e instanceof Error ? e.message : String(e)}`,
20
+ ))
15
21
  }
16
22
  return errors
17
23
  }
@@ -1,3 +1,4 @@
1
+ import { ZERO_HASH } from '@xylabs/hex'
1
2
  import type { HydratedBlock, InBlockPayloadValidationFunction } from '@xyo-network/xl1-protocol'
2
3
  import { InBlockPayloadValidationError, isHashPayload } from '@xyo-network/xl1-protocol'
3
4
 
@@ -11,7 +12,12 @@ export const validateHashInBlock: InBlockPayloadValidationFunction = async (
11
12
  try {
12
13
  errors.push(...await validateTypedPayloadInBlock(payload, block, isHashPayload))
13
14
  } catch (e) {
14
- errors.push(new InBlockPayloadValidationError(block, payload, `Failed validateHashInBlock: ${e instanceof Error ? e.message : String(e)}`))
15
+ errors.push(new InBlockPayloadValidationError(
16
+ (block?.[0])?._hash ?? ZERO_HASH,
17
+ block,
18
+ payload,
19
+ `Failed validateHashInBlock: ${e instanceof Error ? e.message : String(e)}`,
20
+ ))
15
21
  }
16
22
  return errors
17
23
  }
@@ -1,3 +1,4 @@
1
+ import { ZERO_HASH } from '@xylabs/hex'
1
2
  import { isSchemaPayload } from '@xyo-network/schema-payload-plugin'
2
3
  import type { HydratedBlock, InBlockPayloadValidationFunction } from '@xyo-network/xl1-protocol'
3
4
  import { InBlockPayloadValidationError } from '@xyo-network/xl1-protocol'
@@ -12,7 +13,12 @@ export const validateSchemaInBlock: InBlockPayloadValidationFunction = async (
12
13
  try {
13
14
  errors.push(...await validateTypedPayloadInBlock(payload, block, isSchemaPayload))
14
15
  } catch (e) {
15
- errors.push(new InBlockPayloadValidationError(block, payload, `Failed validateSchemaInBlock: ${e instanceof Error ? e.message : String(e)}`))
16
+ errors.push(new InBlockPayloadValidationError(
17
+ (block?.[0])?._hash ?? ZERO_HASH,
18
+ block,
19
+ payload,
20
+ `Failed validateSchemaInBlock: ${e instanceof Error ? e.message : String(e)}`,
21
+ ))
16
22
  }
17
23
  return errors
18
24
  }
@@ -1,3 +1,4 @@
1
+ import { ZERO_HASH } from '@xylabs/hex'
1
2
  import type {
2
3
  HydratedBlock,
3
4
  InBlockPayloadValidationFunction,
@@ -14,7 +15,12 @@ export const validateTransferInBlock: InBlockPayloadValidationFunction = async (
14
15
  try {
15
16
  errors.push(...await validateTypedPayloadInBlock(payload, block, isTransfer))
16
17
  } catch (e) {
17
- errors.push(new InBlockPayloadValidationError(block, payload, `Failed validateTransferInBlock: ${e instanceof Error ? e.message : String(e)}`))
18
+ errors.push(new InBlockPayloadValidationError(
19
+ (block?.[0])?._hash ?? ZERO_HASH,
20
+ block,
21
+ payload,
22
+ `Failed validateTransferInBlock: ${e instanceof Error ? e.message : String(e)}`,
23
+ ))
18
24
  }
19
25
  return errors
20
26
  }
@@ -1,3 +1,4 @@
1
+ import { ZERO_HASH } from '@xylabs/hex'
1
2
  import { BoundWitnessSchema } from '@xyo-network/boundwitness-model'
2
3
  import type { Schema } from '@xyo-network/payload-model'
3
4
  import { SchemaSchema } from '@xyo-network/schema-payload-plugin'
@@ -33,10 +34,15 @@ export const validatePayloadInBlock: InBlockPayloadValidationFunction = async (
33
34
  if (validator) {
34
35
  errors.push(...await validator(payload, block))
35
36
  } else {
36
- errors.push(new InBlockPayloadValidationError(block, payload, `Unsupported payload schema: ${payload.schema}`))
37
+ errors.push(new InBlockPayloadValidationError((block?.[0])?._hash ?? ZERO_HASH, block, payload, `Unsupported payload schema: ${payload.schema}`))
37
38
  }
38
39
  } catch (e) {
39
- errors.push(new InBlockPayloadValidationError(block, payload, `Failed validatePayloadInBlock: ${e instanceof Error ? e.message : String(e)}`))
40
+ errors.push(new InBlockPayloadValidationError(
41
+ (block?.[0])?._hash ?? ZERO_HASH,
42
+ block,
43
+ payload,
44
+ `Failed validatePayloadInBlock: ${e instanceof Error ? e.message : String(e)}`,
45
+ ))
40
46
  }
41
47
  return errors
42
48
  }
@@ -1,4 +1,4 @@
1
- import type { Address } from '@xylabs/hex'
1
+ import { type Address, ZERO_HASH } from '@xylabs/hex'
2
2
  import type { HydratedBlock, HydratedBlockValidationFunction } from '@xyo-network/xl1-protocol'
3
3
  import { HydratedBlockValidationError } from '@xyo-network/xl1-protocol'
4
4
 
@@ -21,7 +21,11 @@ export const validateHydratedBlock: HydratedBlockValidationFunction = async (
21
21
  ]
22
22
  errors.push(...(await Promise.all(validators.map(v => v(hydratedBlock, chainId)))).flat())
23
23
  } catch (e) {
24
- errors.push(new HydratedBlockValidationError(hydratedBlock, `Failed validateHydratedBlock: ${e instanceof Error ? e.message : String(e)}`))
24
+ errors.push(new HydratedBlockValidationError(
25
+ hydratedBlock?.[0]?._hash ?? ZERO_HASH,
26
+ hydratedBlock,
27
+ `Failed validateHydratedBlock: ${e instanceof Error ? e.message : String(e)}`,
28
+ ))
25
29
  }
26
30
  return errors
27
31
  }
@@ -1,4 +1,4 @@
1
- import type { Hash } from '@xylabs/hex'
1
+ import { type Hash, ZERO_HASH } from '@xylabs/hex'
2
2
  import type { Payload, WithHashStorageMeta } from '@xyo-network/payload-model'
3
3
  import type {
4
4
  HydratedBlock,
@@ -28,15 +28,19 @@ export const PayloadsInBlockValidator: HydratedBlockValidationFunction = async (
28
28
  errors.push(...await validatePayloadInBlock(payload, [block, payloads]))
29
29
  delete remainingPayloads[hash]
30
30
  } else {
31
- errors.push(new HydratedBlockValidationError([block, payloads], `missing payload ${hash} ${schema}`))
31
+ errors.push(new HydratedBlockValidationError(block?._hash ?? ZERO_HASH, [block, payloads], `missing payload ${hash} ${schema}`))
32
32
  }
33
33
  }
34
34
 
35
35
  if (Object.keys(remainingPayloads).length > 0) {
36
- errors.push(new HydratedBlockValidationError([block, payloads], `extra payloads ${Object.keys(payloadMap).join(', ')}`))
36
+ errors.push(new HydratedBlockValidationError(block?._hash ?? ZERO_HASH, [block, payloads], `extra payloads ${Object.keys(payloadMap).join(', ')}`))
37
37
  }
38
38
  } catch (e) {
39
- errors.push(new HydratedBlockValidationError([block, payloads], `Failed PayloadsInBlockValidator: ${e instanceof Error ? e.message : String(e)}`))
39
+ errors.push(new HydratedBlockValidationError(
40
+ block?._hash ?? ZERO_HASH,
41
+ [block, payloads],
42
+ `Failed PayloadsInBlockValidator: ${e instanceof Error ? e.message : String(e)}`,
43
+ ))
40
44
  }
41
45
 
42
46
  return errors
@@ -1,4 +1,4 @@
1
- import type { Address } from '@xylabs/hex'
1
+ import { type Address, ZERO_HASH } from '@xylabs/hex'
2
2
  import type {
3
3
  AccountBalanceService, HydratedBlock, HydratedBlockStateValidationFunction,
4
4
  } from '@xyo-network/xl1-protocol'
@@ -23,6 +23,7 @@ export const validateHydratedBlockState: HydratedBlockStateValidationFunction =
23
23
  errors.push(...(await Promise.all(validators.map(v => v(hydratedBlock, chainId, services)))).flat())
24
24
  } catch (e) {
25
25
  errors.push(new HydratedBlockStateValidationError(
26
+ hydratedBlock?.[0]?._hash ?? ZERO_HASH,
26
27
  chainId,
27
28
  hydratedBlock,
28
29
  `Failed validateHydratedBlockState: ${e instanceof Error ? e.message : String(e)}`,
@@ -1,4 +1,6 @@
1
- import { type Address, hexToBigInt } from '@xylabs/hex'
1
+ import {
2
+ type Address, hexToBigInt, ZERO_HASH,
3
+ } from '@xylabs/hex'
2
4
  import { netBalancesForPayloads } from '@xyo-network/chain-protocol'
3
5
  import { XYO_ZERO_ADDRESS } from '@xyo-network/chain-utils'
4
6
  import type {
@@ -24,12 +26,18 @@ export const RequiredBalanceBlockStateValidator: HydratedBlockStateValidationFun
24
26
  }
25
27
  }
26
28
  const previous = block[0].previous
27
- if (previous === null) return [new HydratedBlockStateValidationError(chainId, block, 'Insufficient funds because first block')]
29
+ if (previous === null) return [new HydratedBlockStateValidationError(
30
+ block?.[0]?._hash ?? ZERO_HASH,
31
+ chainId,
32
+ block,
33
+ 'Insufficient funds because first block',
34
+ )]
28
35
 
29
36
  for (const [address, reqBalance] of Object.entries(requiredBalances) as [Address, bigint][]) {
30
37
  const balance = hexToBigInt(services.accountBalance.getBalance(address))
31
38
  if (address !== XYO_ZERO_ADDRESS && reqBalance > balance) {
32
39
  errors.push(new HydratedBlockStateValidationError(
40
+ block?.[0]?._hash ?? ZERO_HASH,
33
41
  chainId,
34
42
  block,
35
43
  `insufficient balance for ${address} ${balance} < ${requiredBalances[address]}`,
@@ -38,6 +46,7 @@ export const RequiredBalanceBlockStateValidator: HydratedBlockStateValidationFun
38
46
  }
39
47
  } catch (e) {
40
48
  errors.push(new HydratedBlockStateValidationError(
49
+ block?.[0]?._hash ?? ZERO_HASH,
41
50
  chainId,
42
51
  block,
43
52
  `Failed RequiredBalanceBlockStateValidator: ${e instanceof Error ? e.message : String(e)}`,
@@ -1,21 +1,31 @@
1
+ import { ZERO_HASH } from '@xylabs/hex'
1
2
  import type {
2
3
  HydratedTransaction, HydratedTransactionValidationFunction, TransactionBoundWitness,
3
4
  } from '@xyo-network/xl1-protocol'
4
5
  import { HydratedTransactionValidationError } from '@xyo-network/xl1-protocol'
5
6
 
7
+ // eslint-disable-next-line complexity
6
8
  export const TransactionDurationValidator: HydratedTransactionValidationFunction<TransactionBoundWitness> = (
7
9
  tx: HydratedTransaction,
8
10
  ) => {
9
11
  const errors: (HydratedTransactionValidationError | Error)[] = []
10
12
  try {
11
13
  const { exp, nbf } = tx[0]
12
- if (nbf < 0) errors.push(new HydratedTransactionValidationError(tx, 'Transaction nbf must be positive'))
14
+ if (nbf < 0) errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, 'Transaction nbf must be positive'))
13
15
 
14
- if (exp < 0) errors.push(new HydratedTransactionValidationError(tx, 'Transaction exp must be positive'))
15
- if (exp <= nbf) errors.push(new HydratedTransactionValidationError(tx, 'Transaction exp must greater than nbf'))
16
- if (exp - nbf > 10_000) errors.push(new HydratedTransactionValidationError(tx, 'Transaction exp must not be too far in the future'))
16
+ if (exp < 0) errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, 'Transaction exp must be positive'))
17
+ if (exp <= nbf) errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, 'Transaction exp must greater than nbf'))
18
+ if (exp - nbf > 10_000) errors.push(new HydratedTransactionValidationError(
19
+ tx?.[0]?._hash ?? ZERO_HASH,
20
+ tx,
21
+ 'Transaction exp must not be too far in the future',
22
+ ))
17
23
  } catch (e) {
18
- errors.push(new HydratedTransactionValidationError(tx, `Failed TransactionDurationValidator: ${e instanceof Error ? e.message : String(e)}`))
24
+ errors.push(new HydratedTransactionValidationError(
25
+ tx?.[0]?._hash ?? ZERO_HASH,
26
+ tx,
27
+ `Failed TransactionDurationValidator: ${e instanceof Error ? e.message : String(e)}`,
28
+ ))
19
29
  }
20
30
 
21
31
  return errors
@@ -1,3 +1,4 @@
1
+ import { ZERO_HASH } from '@xylabs/hex'
1
2
  import { extractElevatedHashes } from '@xyo-network/chain-protocol'
2
3
  import type {
3
4
  HydratedTransaction, HydratedTransactionValidationFunction, TransactionBoundWitness,
@@ -12,10 +13,14 @@ export const TransactionElevationValidator: HydratedTransactionValidationFunctio
12
13
  try {
13
14
  extractElevatedHashes(tx)
14
15
  } catch {
15
- errors.push(new HydratedTransactionValidationError(tx, 'Hydrated transaction does not include all script hashes'))
16
+ errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, 'Hydrated transaction does not include all script hashes'))
16
17
  }
17
18
  } catch (e) {
18
- errors.push(new HydratedTransactionValidationError(tx, `Failed TransactionElevationValidator: ${e instanceof Error ? e.message : String(e)}`))
19
+ errors.push(new HydratedTransactionValidationError(
20
+ tx?.[0]?._hash ?? ZERO_HASH,
21
+ tx,
22
+ `Failed TransactionElevationValidator: ${e instanceof Error ? e.message : String(e)}`,
23
+ ))
19
24
  }
20
25
  return errors
21
26
  }
@@ -1,4 +1,4 @@
1
- import { asAddress } from '@xylabs/hex'
1
+ import { asAddress, ZERO_HASH } from '@xylabs/hex'
2
2
  import { addressesContains } from '@xyo-network/boundwitness-validator'
3
3
  import type {
4
4
  HydratedTransaction, HydratedTransactionValidationFunction, TransactionBoundWitness,
@@ -11,10 +11,22 @@ export const TransactionFromValidator: HydratedTransactionValidationFunction<Tra
11
11
  const errors: (HydratedTransactionValidationError | Error)[] = []
12
12
  try {
13
13
  const from = asAddress(tx[0].from)
14
- if (from === undefined)errors.push(new HydratedTransactionValidationError(tx, 'Transaction from is not a valid address'))
15
- else if (!addressesContains(tx[0], from)) errors.push(new HydratedTransactionValidationError(tx, 'Transaction from address must be listed in addresses'))
14
+ if (from === undefined)errors.push(new HydratedTransactionValidationError(
15
+ tx?.[0]?._hash ?? ZERO_HASH,
16
+ tx,
17
+ 'Transaction from is not a valid address',
18
+ ))
19
+ else if (!addressesContains(tx[0], from)) errors.push(new HydratedTransactionValidationError(
20
+ tx?.[0]?._hash ?? ZERO_HASH,
21
+ tx,
22
+ 'Transaction from address must be listed in addresses',
23
+ ))
16
24
  } catch (e) {
17
- errors.push(new HydratedTransactionValidationError(tx, `Failed TransactionFromValidator: ${e instanceof Error ? e.message : String(e)}`))
25
+ errors.push(new HydratedTransactionValidationError(
26
+ tx?.[0]?._hash ?? ZERO_HASH,
27
+ tx,
28
+ `Failed TransactionFromValidator: ${e instanceof Error ? e.message : String(e)}`,
29
+ ))
18
30
  }
19
31
  return errors
20
32
  }
@@ -1,4 +1,4 @@
1
- import { hexToBigInt } from '@xylabs/hex'
1
+ import { hexToBigInt, ZERO_HASH } from '@xylabs/hex'
2
2
  import type {
3
3
  HydratedTransaction,
4
4
  HydratedTransactionValidationFunction,
@@ -10,52 +10,75 @@ import {
10
10
  minTransactionFees,
11
11
  } from '@xyo-network/xl1-protocol'
12
12
 
13
+ // eslint-disable-next-line complexity
13
14
  export const TransactionGasValidator: HydratedTransactionValidationFunction<TransactionBoundWitness> = (
14
15
  tx: HydratedTransaction,
15
16
  ) => {
16
17
  const errors: (HydratedTransactionValidationError | Error)[] = []
17
18
  try {
18
19
  if (tx?.[0].fees === undefined) {
19
- errors.push(new HydratedTransactionValidationError(tx, 'Missing fees'))
20
+ errors.push(new HydratedTransactionValidationError(
21
+ tx?.[0]?._hash ?? ZERO_HASH,
22
+ tx,
23
+ 'Missing fees',
24
+ ))
20
25
  } else {
21
26
  const {
22
27
  base, gasLimit, gasPrice, priority,
23
28
  } = parseFees(tx[0].fees)
24
29
 
25
30
  if (base === undefined) errors.push(new HydratedTransactionValidationError(
31
+ tx?.[0]?._hash ?? ZERO_HASH,
26
32
  tx,
27
33
  'fees.base must be defined and a valid number',
28
34
  ))
29
35
  else if (base < minTransactionFees.base) errors.push(new HydratedTransactionValidationError(
36
+ tx?.[0]?._hash ?? ZERO_HASH,
30
37
  tx,
31
38
  `fees.base must be >= ${minTransactionFees.base}`,
32
39
  ))
33
40
 
34
- if (gasLimit === undefined) errors.push(new HydratedTransactionValidationError(tx, 'fees.gasLimit must be defined and a valid number'))
41
+ if (gasLimit === undefined) errors.push(new HydratedTransactionValidationError(
42
+ tx?.[0]?._hash ?? ZERO_HASH,
43
+ tx,
44
+ 'fees.gasLimit must be defined and a valid number',
45
+ ))
35
46
  else if (gasLimit < minTransactionFees.gasLimit) errors.push(new HydratedTransactionValidationError(
47
+ tx?.[0]?._hash ?? ZERO_HASH,
36
48
  tx,
37
49
  `fees.gasLimit must be >= ${minTransactionFees.gasLimit}`,
38
50
  ))
39
51
 
40
52
  if (gasPrice === undefined) errors.push(
41
- new HydratedTransactionValidationError(tx, 'fees.gasPrice must be defined and a valid number'),
53
+ new HydratedTransactionValidationError(
54
+ tx?.[0]?._hash ?? ZERO_HASH,
55
+ tx,
56
+ 'fees.gasPrice must be defined and a valid number',
57
+ ),
42
58
  )
43
59
  else if (gasPrice < minTransactionFees.gasPrice) errors.push(new HydratedTransactionValidationError(
60
+ tx?.[0]?._hash ?? ZERO_HASH,
44
61
  tx,
45
62
  `fees.gasPrice must be >= ${minTransactionFees.gasPrice}`,
46
63
  ))
47
64
 
48
65
  if (priority === undefined) errors.push(new HydratedTransactionValidationError(
66
+ tx?.[0]?._hash ?? ZERO_HASH,
49
67
  tx,
50
68
  'fees.priority must be defined and a valid number',
51
69
  ))
52
70
  else if (priority < minTransactionFees.priority) errors.push(new HydratedTransactionValidationError(
71
+ tx?.[0]?._hash ?? ZERO_HASH,
53
72
  tx,
54
73
  `fees.priority must be >= ${minTransactionFees.priority}`,
55
74
  ))
56
75
  }
57
76
  } catch (e) {
58
- errors.push(new HydratedTransactionValidationError(tx, `Failed TransactionGasValidator: ${e instanceof Error ? e.message : String(e)}`))
77
+ errors.push(new HydratedTransactionValidationError(
78
+ tx?.[0]?._hash ?? ZERO_HASH,
79
+ tx,
80
+ `Failed TransactionGasValidator: ${e instanceof Error ? e.message : String(e)}`,
81
+ ))
59
82
  }
60
83
  return errors
61
84
  }
@@ -1,3 +1,5 @@
1
+ import { ZERO_HASH } from '@xylabs/hex'
2
+ import { toJsonString } from '@xylabs/object'
1
3
  import { TransactionBoundWitnessJsonSchema } from '@xyo-network/chain-schema'
2
4
  import { PayloadBuilder } from '@xyo-network/payload-builder'
3
5
  import type {
@@ -19,12 +21,16 @@ export const TransactionJsonSchemaValidator: HydratedTransactionValidationFuncti
19
21
  if (validate === undefined) validate = ajv.compile(TransactionBoundWitnessJsonSchema)
20
22
  // see if you can export the super set
21
23
  if (!validate(PayloadBuilder.omitStorageMeta(tx[0]))) {
22
- const error = new HydratedTransactionValidationError(tx, 'failed JSON schema validation')
24
+ const error = new HydratedTransactionValidationError(
25
+ tx?.[0]?._hash ?? ZERO_HASH,
26
+ tx,
27
+ `failed JSON schema validation: ${toJsonString(tx, 10)} ${toJsonString(validate.errors, 10)}`,
28
+ )
23
29
  error.cause = validate.errors
24
30
  errors.push(error)
25
31
  }
26
32
  } catch (ex) {
27
- errors.push(new HydratedTransactionValidationError(tx, 'validation excepted'), ex as Error)
33
+ errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, 'validation excepted'), ex as Error)
28
34
  }
29
35
  return errors
30
36
  }
@@ -1,4 +1,4 @@
1
- import type { Address } from '@xylabs/hex'
1
+ import { type Address, ZERO_HASH } from '@xylabs/hex'
2
2
  import type {
3
3
  HydratedTransaction, HydratedTransactionValidationFunction, TransactionBoundWitness,
4
4
  } from '@xyo-network/xl1-protocol'
@@ -11,10 +11,10 @@ export const TransactionProtocolValidator: HydratedTransactionValidationFunction
11
11
  const errors: (HydratedTransactionValidationError | Error)[] = []
12
12
  try {
13
13
  if (chainId !== undefined && tx[0].chain !== chainId) {
14
- errors.push(new HydratedTransactionValidationError(tx, 'invalid chain id'))
14
+ errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, 'invalid chain id'))
15
15
  }
16
16
  } catch (ex) {
17
- errors.push(new HydratedTransactionValidationError(tx, 'validation excepted'), ex as Error)
17
+ errors.push(new HydratedTransactionValidationError(tx?.[0]?._hash ?? ZERO_HASH, tx, 'validation excepted'), ex as Error)
18
18
  }
19
19
  return await Promise.resolve(errors)
20
20
  }