@xyo-network/chain-validation 1.4.8 → 1.5.1

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 (53) hide show
  1. package/dist/neutral/index.mjs +251 -172
  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/elevatedPayload/lib/validateElevatedFromBlock.d.ts.map +1 -1
  9. package/dist/types/elevatedPayload/lib/validateElevatedFromTransaction.d.ts.map +1 -1
  10. package/dist/types/elevatedPayload/lib/validateIncludedInBlock.d.ts.map +1 -1
  11. package/dist/types/elevatedPayload/lib/validateTransactionInBlock.d.ts.map +1 -1
  12. package/dist/types/elevatedPayload/lib/validateTypedPayloadInBlock.d.ts.map +1 -1
  13. package/dist/types/elevatedPayload/payloads/validateChainStakeIntentInBlock.d.ts.map +1 -1
  14. package/dist/types/elevatedPayload/payloads/validateHashInBlock.d.ts.map +1 -1
  15. package/dist/types/elevatedPayload/payloads/validateSchemaInBlock.d.ts.map +1 -1
  16. package/dist/types/elevatedPayload/payloads/validateTransferInBlock.d.ts.map +1 -1
  17. package/dist/types/elevatedPayload/validatePayloadInBlock.d.ts.map +1 -1
  18. package/dist/types/hydratedBlock/validateHydratedBlock.d.ts.map +1 -1
  19. package/dist/types/hydratedBlock/validators/Payloads.d.ts.map +1 -1
  20. package/dist/types/hydratedBlockState/validateHydratedBlockState.d.ts.map +1 -1
  21. package/dist/types/hydratedBlockState/validators/RequiredBalance.d.ts.map +1 -1
  22. package/dist/types/transaction/validateTransaction.d.ts.map +1 -1
  23. package/dist/types/transaction/validators/TransactionDurationValidator.d.ts.map +1 -1
  24. package/dist/types/transaction/validators/TransactionElevationValidator.d.ts.map +1 -1
  25. package/dist/types/transaction/validators/TransactionFromValidator.d.ts.map +1 -1
  26. package/dist/types/transaction/validators/TransactionGasValidator.d.ts.map +1 -1
  27. package/dist/types/transaction/validators/TransactionProtocolValidator.d.ts.map +1 -1
  28. package/package.json +24 -25
  29. package/src/block/validateBlock.ts +5 -4
  30. package/src/block/validators/AllowedPayloadSchemas.ts +7 -3
  31. package/src/block/validators/Fields.ts +6 -2
  32. package/src/block/validators/JsonSchema.ts +12 -8
  33. package/src/block/validators/PreviousHash.ts +15 -11
  34. package/src/elevatedPayload/lib/validateElevatedFromBlock.ts +9 -4
  35. package/src/elevatedPayload/lib/validateElevatedFromTransaction.ts +11 -7
  36. package/src/elevatedPayload/lib/validateIncludedInBlock.ts +6 -2
  37. package/src/elevatedPayload/lib/validateTransactionInBlock.ts +8 -4
  38. package/src/elevatedPayload/lib/validateTypedPayloadInBlock.ts +10 -6
  39. package/src/elevatedPayload/payloads/validateChainStakeIntentInBlock.ts +5 -1
  40. package/src/elevatedPayload/payloads/validateHashInBlock.ts +5 -1
  41. package/src/elevatedPayload/payloads/validateSchemaInBlock.ts +5 -1
  42. package/src/elevatedPayload/payloads/validateTransferInBlock.ts +5 -1
  43. package/src/elevatedPayload/validatePayloadInBlock.ts +9 -5
  44. package/src/hydratedBlock/validateHydratedBlock.ts +13 -7
  45. package/src/hydratedBlock/validators/Payloads.ts +21 -16
  46. package/src/hydratedBlockState/validateHydratedBlockState.ts +15 -8
  47. package/src/hydratedBlockState/validators/RequiredBalance.ts +25 -34
  48. package/src/transaction/validateTransaction.ts +17 -13
  49. package/src/transaction/validators/TransactionDurationValidator.ts +9 -5
  50. package/src/transaction/validators/TransactionElevationValidator.ts +7 -3
  51. package/src/transaction/validators/TransactionFromValidator.ts +7 -3
  52. package/src/transaction/validators/TransactionGasValidator.ts +18 -14
  53. package/src/transaction/validators/TransactionProtocolValidator.ts +1 -5
@@ -5,20 +5,24 @@ export const BlockPreviousHashValidator: BlockValidatorFunction = (
5
5
  block: BlockBoundWitness,
6
6
  ) => {
7
7
  const errors: Error[] = []
8
- const blockNumber = block.block
9
- if (blockNumber > 0n) {
8
+ try {
9
+ const blockNumber = block.block
10
+ if (blockNumber > 0n) {
10
11
  // if this is not the first block, validate previous hashes
11
- if (!isHash(block.previous)) {
12
- errors.push(new Error('previous hash is missing or invalid'))
13
- }
14
- } else if (blockNumber === 0) {
12
+ if (!isHash(block.previous)) {
13
+ errors.push(new Error('previous hash is missing or invalid'))
14
+ }
15
+ } else if (blockNumber === 0) {
15
16
  // if this is the first block, validate previous hashes
16
- if (block.previous !== null) {
17
- errors.push(new Error('previous hash should not be set'))
18
- }
19
- } else {
17
+ if (block.previous !== null) {
18
+ errors.push(new Error('previous hash should not be set'))
19
+ }
20
+ } else {
20
21
  // we have a negative block number
21
- errors.push(new Error('invalid block number'))
22
+ errors.push(new Error('invalid block number'))
23
+ }
24
+ } catch (e) {
25
+ errors.push(new Error(`Failed BlockPreviousHashValidator: ${e instanceof Error ? e.message : String(e)}`))
22
26
  }
23
27
  return errors
24
28
  }
@@ -1,5 +1,5 @@
1
1
  import type { Promisable } from '@xylabs/promise'
2
- import { transactionPayloadsFromHydratedBlock } from '@xyo-network/chain-protocol'
2
+ import { transactionsFromHydratedBlock } from '@xyo-network/chain-protocol'
3
3
  import type { HydratedBlock, InBlockPayloadValidationFunction } from '@xyo-network/xl1-protocol'
4
4
 
5
5
  export const validateElevatedFromBlock: InBlockPayloadValidationFunction = (
@@ -7,9 +7,14 @@ export const validateElevatedFromBlock: InBlockPayloadValidationFunction = (
7
7
  block: HydratedBlock,
8
8
  ): Promisable<Error[]> => {
9
9
  const errors: Error[] = []
10
- const txPayloadHashes = new Set(transactionPayloadsFromHydratedBlock(block).map(tx => tx._hash))
11
- if (txPayloadHashes.has(payload._hash)) {
12
- errors.push(new Error(`Transaction may not include block payload hash [${payload.schema}]: ${payload._hash}`))
10
+ try {
11
+ const txs = transactionsFromHydratedBlock(block)
12
+ const allTxPayloadHashes = new Set(txs.flatMap(tx => tx.payload_hashes))
13
+ if (allTxPayloadHashes.has(payload._hash)) {
14
+ errors.push(new Error(`Transaction may not include block payload hash [${payload.schema}]: ${payload._hash}`))
15
+ }
16
+ } catch (e) {
17
+ errors.push(new Error(`Failed validateElevatedFromBlock: ${e instanceof Error ? e.message : String(e)}`))
13
18
  }
14
19
  return errors
15
20
  }
@@ -7,14 +7,18 @@ export const validateElevatedFromTransaction: InBlockPayloadValidationFunction =
7
7
  block: HydratedBlock,
8
8
  ): Promisable<Error[]> => {
9
9
  const errors: Error[] = []
10
- const txs = transactionsFromHydratedBlock(block)
11
- if (txs.length > 0) {
12
- const hashes = txs.flatMap(tx => tx.payload_hashes)
13
- if (!hashes.includes(payload._hash)) {
14
- errors.push(new Error('Transaction does not include payload'))
10
+ try {
11
+ const txs = transactionsFromHydratedBlock(block)
12
+ if (txs.length > 0) {
13
+ const hashes = txs.flatMap(tx => tx.payload_hashes)
14
+ if (!hashes.includes(payload._hash)) {
15
+ errors.push(new Error('Transaction does not include payload'))
16
+ }
17
+ } else {
18
+ errors.push(new Error('No Transactions in block'))
15
19
  }
16
- } else {
17
- errors.push(new Error('No Transactions in block'))
20
+ } catch (e) {
21
+ errors.push(new Error(`Failed validateElevatedFromTransaction: ${e instanceof Error ? e.message : String(e)}`))
18
22
  }
19
23
  return errors
20
24
  }
@@ -3,8 +3,12 @@ import type { BlockBoundWitness } from '@xyo-network/xl1-protocol'
3
3
 
4
4
  export const validateIncludedInBlock = (payload: WithStorageMeta<Payload>, block: BlockBoundWitness): Error[] => {
5
5
  const errors: Error[] = []
6
- if (!block.payload_hashes.includes(payload._hash)) {
7
- errors.push(new Error('Payload not included in block'))
6
+ try {
7
+ if (!block.payload_hashes.includes(payload._hash)) {
8
+ errors.push(new Error('Payload not included in block'))
9
+ }
10
+ } catch (e) {
11
+ errors.push(new Error(`Failed validateIncludedInBlock: ${e instanceof Error ? e.message : String(e)}`))
8
12
  }
9
13
  return errors
10
14
  }
@@ -9,10 +9,14 @@ export const validateTransactionInBlock: InBlockPayloadValidationFunction = asyn
9
9
  _block: HydratedBlock,
10
10
  ): Promise<Error[]> => {
11
11
  const errors: Error[] = []
12
- if (isTransactionBoundWitness(payload) && isStorageMeta(payload)) {
13
- errors.push(...await BoundWitnessSignaturesValidator(payload))
14
- } else {
15
- errors.push(new Error('Payload failed isTransactionBoundWitness or isStorageMeta'))
12
+ try {
13
+ if (isTransactionBoundWitness(payload) && isStorageMeta(payload)) {
14
+ errors.push(...await BoundWitnessSignaturesValidator(payload))
15
+ } else {
16
+ errors.push(new Error('Payload failed isTransactionBoundWitness or isStorageMeta'))
17
+ }
18
+ } catch (e) {
19
+ errors.push(new Error(`Failed validateTransactionInBlock: ${e instanceof Error ? e.message : String(e)}`))
16
20
  }
17
21
  return errors
18
22
  }
@@ -13,14 +13,18 @@ export const validateTypedPayloadInBlock = async <T extends Payload>(
13
13
  identityFunction: IdentityFunction<T>,
14
14
  ): Promise<Error[]> => {
15
15
  const errors: Error[] = []
16
- if (identityFunction(payload) && isStorageMeta(payload)) {
17
- if (isElevatedFromBlock(payload, block)) {
18
- errors.push(...await validateElevatedFromBlock(payload, block))
16
+ try {
17
+ if (identityFunction(payload) && isStorageMeta(payload)) {
18
+ if (isElevatedFromBlock(payload, block)) {
19
+ errors.push(...await validateElevatedFromBlock(payload, block))
20
+ } else {
21
+ errors.push(...await validateElevatedFromTransaction(payload, block))
22
+ }
19
23
  } else {
20
- errors.push(...await validateElevatedFromTransaction(payload, block))
24
+ errors.push(new Error('Payload failed identityFunction or isElevated or isStorageMeta'))
21
25
  }
22
- } else {
23
- errors.push(new Error('Payload failed identityFunction or isElevated or isStorageMeta'))
26
+ } catch (e) {
27
+ errors.push(new Error(`Failed validateTypedPayloadInBlock: ${e instanceof Error ? e.message : String(e)}`))
24
28
  }
25
29
  return errors
26
30
  }
@@ -8,6 +8,10 @@ export const validateChainStakeIntentInBlock: InBlockPayloadValidationFunction =
8
8
  block: HydratedBlock,
9
9
  ): Promise<Error[]> => {
10
10
  const errors: Error[] = []
11
- errors.push(...await validateTypedPayloadInBlock(payload, block, isChainStakeIntent))
11
+ try {
12
+ errors.push(...await validateTypedPayloadInBlock(payload, block, isChainStakeIntent))
13
+ } catch (e) {
14
+ errors.push(new Error(`Failed validateChainStakeIntentInBlock: ${e instanceof Error ? e.message : String(e)}`))
15
+ }
12
16
  return errors
13
17
  }
@@ -8,6 +8,10 @@ export const validateHashInBlock: InBlockPayloadValidationFunction = async (
8
8
  block: HydratedBlock,
9
9
  ): Promise<Error[]> => {
10
10
  const errors: Error[] = []
11
- errors.push(...await validateTypedPayloadInBlock(payload, block, isHashPayload))
11
+ try {
12
+ errors.push(...await validateTypedPayloadInBlock(payload, block, isHashPayload))
13
+ } catch (e) {
14
+ errors.push(new Error(`Failed validateHashInBlock: ${e instanceof Error ? e.message : String(e)}`))
15
+ }
12
16
  return errors
13
17
  }
@@ -8,6 +8,10 @@ export const validateSchemaInBlock: InBlockPayloadValidationFunction = async (
8
8
  block: HydratedBlock,
9
9
  ): Promise<Error[]> => {
10
10
  const errors: Error[] = []
11
- errors.push(...await validateTypedPayloadInBlock(payload, block, isSchemaPayload))
11
+ try {
12
+ errors.push(...await validateTypedPayloadInBlock(payload, block, isSchemaPayload))
13
+ } catch (e) {
14
+ errors.push(new Error(`Failed validateSchemaInBlock: ${e instanceof Error ? e.message : String(e)}`))
15
+ }
12
16
  return errors
13
17
  }
@@ -9,6 +9,10 @@ export const validateTransferInBlock: InBlockPayloadValidationFunction = async (
9
9
  block: HydratedBlock,
10
10
  ): Promise<Error[]> => {
11
11
  const errors: Error[] = []
12
- errors.push(...await validateTypedPayloadInBlock(payload, block, isTransfer))
12
+ try {
13
+ errors.push(...await validateTypedPayloadInBlock(payload, block, isTransfer))
14
+ } catch (e) {
15
+ errors.push(new Error(`Failed validateTransferInBlock: ${e instanceof Error ? e.message : String(e)}`))
16
+ }
13
17
  return errors
14
18
  }
@@ -27,11 +27,15 @@ export const validatePayloadInBlock: InBlockPayloadValidationFunction = async (
27
27
  block: HydratedBlock,
28
28
  ): Promise<Error[]> => {
29
29
  const errors: Error[] = []
30
- const validator = payloadValidators[payload.schema]
31
- if (validator) {
32
- errors.push(...await validator(payload, block))
33
- } else {
34
- errors.push(new Error(`Unsupported payload schema: ${payload.schema}`))
30
+ try {
31
+ const validator = payloadValidators[payload.schema]
32
+ if (validator) {
33
+ errors.push(...await validator(payload, block))
34
+ } else {
35
+ errors.push(new Error(`Unsupported payload schema: ${payload.schema}`))
36
+ }
37
+ } catch (e) {
38
+ errors.push(new Error(`Failed validatePayloadInBlock: ${e instanceof Error ? e.message : String(e)}`))
35
39
  }
36
40
  return errors
37
41
  }
@@ -10,11 +10,17 @@ export const validateHydratedBlock: HydratedBlockValidatorFunction = async (
10
10
  chainId?: Address,
11
11
  additionalValidators: HydratedBlockValidatorFunction[] = [],
12
12
  ): Promise<Error[]> => {
13
- const errors: Error[] = await validateBlock(hydratedBlock[0], chainId)
14
- const validators: HydratedBlockValidatorFunction[] = [
15
- BoundWitnessReferencesValidator(),
16
- PayloadsInBlockValidator,
17
- ...additionalValidators,
18
- ]
19
- return [...errors, ...(await Promise.all(validators.map(v => v(hydratedBlock, chainId)))).flat()]
13
+ const errors: Error[] = []
14
+ try {
15
+ errors.push(...await validateBlock(hydratedBlock[0], chainId))
16
+ const validators: HydratedBlockValidatorFunction[] = [
17
+ BoundWitnessReferencesValidator(),
18
+ PayloadsInBlockValidator,
19
+ ...additionalValidators,
20
+ ]
21
+ errors.push(...(await Promise.all(validators.map(v => v(hydratedBlock, chainId)))).flat())
22
+ } catch (e) {
23
+ errors.push(new Error(`Failed validateHydratedBlock: ${e instanceof Error ? e.message : String(e)}`))
24
+ }
25
+ return errors
20
26
  }
@@ -11,26 +11,31 @@ export const PayloadsInBlockValidator: HydratedBlockValidatorFunction = async (
11
11
  [block, payloads]: HydratedBlock,
12
12
  ) => {
13
13
  const errors: Error[] = []
14
+ try {
15
+ const payloadMap: Partial<Record<Hash, WithHashStorageMeta<Payload>>> = {}
16
+ for (const payload of payloads) {
17
+ payloadMap[payload._hash] = payload
18
+ }
14
19
 
15
- const payloadMap: Partial<Record<Hash, WithHashStorageMeta<Payload>>> = {}
16
- for (const payload of payloads) {
17
- payloadMap[payload._hash] = payload
18
- }
20
+ const remainingPayloads = { ...payloadMap }
19
21
 
20
- for (let i = 0; i < block.payload_hashes.length; i++) {
21
- const hash = block.payload_hashes[i]
22
- const schema = block.payload_schemas[i]
23
- const payload = payloadMap[hash]
24
- if (payload) {
25
- errors.push(...await validatePayloadInBlock(payload, [block, payloads]))
26
- delete payloadMap[hash]
27
- } else {
28
- errors.push(new Error(`missing payload ${hash} ${schema}`))
22
+ for (let i = 0; i < block.payload_hashes.length; i++) {
23
+ const hash = block.payload_hashes[i]
24
+ const schema = block.payload_schemas[i]
25
+ const payload = payloadMap[hash]
26
+ if (payload) {
27
+ errors.push(...await validatePayloadInBlock(payload, [block, payloads]))
28
+ delete remainingPayloads[hash]
29
+ } else {
30
+ errors.push(new Error(`missing payload ${hash} ${schema}`))
31
+ }
29
32
  }
30
- }
31
33
 
32
- if (Object.keys(payloadMap).length > 0) {
33
- errors.push(new Error(`extra payloads ${Object.keys(payloadMap).join(', ')}`))
34
+ if (Object.keys(remainingPayloads).length > 0) {
35
+ errors.push(new Error(`extra payloads ${Object.keys(payloadMap).join(', ')}`))
36
+ }
37
+ } catch (e) {
38
+ errors.push(new Error(`Failed PayloadsInBlockValidator: ${e instanceof Error ? e.message : String(e)}`))
34
39
  }
35
40
 
36
41
  return errors
@@ -1,6 +1,7 @@
1
1
  import type { Address } from '@xylabs/hex'
2
- import type { ReadArchivist } from '@xyo-network/archivist-model'
3
- import type { HydratedBlock, HydratedBlockStateValidationFunction } from '@xyo-network/xl1-protocol'
2
+ import type {
3
+ AccountBalanceService, HydratedBlock, HydratedBlockStateValidationFunction,
4
+ } from '@xyo-network/xl1-protocol'
4
5
 
5
6
  import { validateHydratedBlock } from '../hydratedBlock/index.ts'
6
7
  import { RequiredBalanceBlockStateValidator } from './validators/index.ts'
@@ -8,13 +9,19 @@ import { RequiredBalanceBlockStateValidator } from './validators/index.ts'
8
9
  export const validateHydratedBlockState: HydratedBlockStateValidationFunction = async (
9
10
  hydratedBlock: HydratedBlock,
10
11
  chainId: Address,
11
- archivist: ReadArchivist,
12
+ services: { accountBalance: AccountBalanceService },
12
13
  additionalValidators: HydratedBlockStateValidationFunction[] = [],
13
14
  ): Promise<Error[]> => {
14
- const errors: Error[] = await validateHydratedBlock(hydratedBlock, chainId)
15
- const validators: HydratedBlockStateValidationFunction[] = [
15
+ const errors: Error[] = []
16
+ try {
17
+ errors.push(...await validateHydratedBlock(hydratedBlock, chainId))
18
+ const validators: HydratedBlockStateValidationFunction[] = [
16
19
  // RequiredBalanceBlockStateValidator,
17
- ...additionalValidators,
18
- ]
19
- return [...errors, ...(await Promise.all(validators.map(v => v(hydratedBlock, chainId, archivist)))).flat()]
20
+ ...additionalValidators,
21
+ ]
22
+ errors.push(...(await Promise.all(validators.map(v => v(hydratedBlock, chainId, services)))).flat())
23
+ } catch (e) {
24
+ errors.push(new Error(`Failed validateHydratedBlockState: ${e instanceof Error ? e.message : String(e)}`))
25
+ }
26
+ return errors
20
27
  }
@@ -1,46 +1,37 @@
1
- import { assertEx } from '@xylabs/assert'
2
- import type { Address } from '@xylabs/hex'
3
- import type { ReadArchivist } from '@xyo-network/archivist-model'
4
- import {
5
- analyzeChain, BalanceAnalyzer, isChainSummaryBalances, netBalancesForPayloads,
6
- } from '@xyo-network/chain-analyze'
7
- import { parseSignedBigInt } from '@xyo-network/chain-protocol'
8
- import type { HydratedBlock, HydratedBlockStateValidationFunction } from '@xyo-network/xl1-protocol'
1
+ import { type Address, hexToBigInt } from '@xylabs/hex'
2
+ import { netBalancesForPayloads } from '@xyo-network/chain-protocol'
3
+ import type {
4
+ AccountBalanceService, HydratedBlock, HydratedBlockStateValidationFunction,
5
+ } from '@xyo-network/xl1-protocol'
9
6
 
10
7
  export const RequiredBalanceBlockStateValidator: HydratedBlockStateValidationFunction = async (
11
8
  block: HydratedBlock,
12
9
  chainId: Address,
13
- archivist: ReadArchivist,
10
+ services: { accountBalance: AccountBalanceService },
14
11
  ) => {
15
12
  const errors: Error[] = []
16
-
13
+ try {
17
14
  // TODO: Filter by non-producer elevated payloads
18
- // to allow for transfers from ZERO address
19
- const netBalances = netBalancesForPayloads(block[1])
20
- const netBalanceAddresses = Object.keys(netBalances) as Address[]
21
- const requiredBalances: Record<Address, bigint> = {}
22
- for (const address of netBalanceAddresses) {
23
- if (netBalances[address] < 0n) {
24
- requiredBalances[address] = -netBalances[address]
15
+ // to allow for transfers from ZERO address
16
+ const netBalances = netBalancesForPayloads(block[1])
17
+ const netBalanceAddresses = Object.keys(netBalances) as Address[]
18
+ const requiredBalances: Record<Address, bigint> = {}
19
+ for (const address of netBalanceAddresses) {
20
+ if (netBalances[address] < 0n) {
21
+ requiredBalances[address] = -netBalances[address]
22
+ }
25
23
  }
26
- }
27
- const previous = block[0].previous
28
- if (previous === null) return [new Error('Insufficient funds because first block')]
29
- const results = await analyzeChain(
30
- archivist,
31
- [
32
- new BalanceAnalyzer(Object.keys(requiredBalances) as Address[], Object.values(requiredBalances)),
33
- ],
34
- previous,
35
- )
36
- const summaryBalances = assertEx(results.find(isChainSummaryBalances), () => new Error('missing summary balances'))
24
+ const previous = block[0].previous
25
+ if (previous === null) return [new Error('Insufficient funds because first block')]
37
26
 
38
- for (const [address, reqBalance] of Object.entries(requiredBalances) as [Address, bigint][]) {
39
- const balance = parseSignedBigInt(summaryBalances.balances[address] ?? { positive: '00' })
40
- if (reqBalance > balance) {
41
- errors.push(new Error(`insufficient balance for ${address} ${balance} < ${requiredBalances[address]}`))
27
+ for (const [address, reqBalance] of Object.entries(requiredBalances) as [Address, bigint][]) {
28
+ const balance = hexToBigInt(services.accountBalance.getBalance(address))
29
+ if (reqBalance > balance) {
30
+ errors.push(new Error(`insufficient balance for ${address} ${balance} < ${requiredBalances[address]}`))
31
+ }
42
32
  }
33
+ } catch (e) {
34
+ errors.push(new Error(`Failed RequiredBalanceBlockStateValidator: ${e instanceof Error ? e.message : String(e)}`))
43
35
  }
44
-
45
- return errors
36
+ return await Promise.resolve(errors)
46
37
  }
@@ -12,18 +12,22 @@ export async function validateTransaction(
12
12
  chainId?: Address,
13
13
  additionalValidators: HydratedTransactionValidatorFunction[] = [],
14
14
  ): Promise<Error[]> {
15
- if (!isTransactionBoundWitness(tx[0])) {
16
- return [new Error('failed isTransactionBoundWitness identity check')]
17
- }
15
+ try {
16
+ if (!isTransactionBoundWitness(tx[0])) {
17
+ return [new Error('failed isTransactionBoundWitness identity check')]
18
+ }
18
19
 
19
- const validators: HydratedTransactionValidatorFunction[] = [
20
- TransactionProtocolValidator,
21
- TransactionJsonSchemaValidator,
22
- TransactionDurationValidator,
23
- TransactionFromValidator,
24
- TransactionGasValidator,
25
- TransactionElevationValidator,
26
- ...additionalValidators,
27
- ]
28
- return (await Promise.all(validators.map(v => v(tx, chainId)))).flat()
20
+ const validators: HydratedTransactionValidatorFunction[] = [
21
+ TransactionProtocolValidator,
22
+ TransactionJsonSchemaValidator,
23
+ TransactionDurationValidator,
24
+ TransactionFromValidator,
25
+ TransactionGasValidator,
26
+ TransactionElevationValidator,
27
+ ...additionalValidators,
28
+ ]
29
+ return (await Promise.all(validators.map(v => v(tx, chainId)))).flat()
30
+ } catch (e) {
31
+ return [(new Error(`Failed TransactionGasValidator: ${e instanceof Error ? e.message : String(e)}`))]
32
+ }
29
33
  }
@@ -6,12 +6,16 @@ export const TransactionDurationValidator: HydratedTransactionValidatorFunction<
6
6
  [tx]: HydratedTransaction,
7
7
  ): Error[] => {
8
8
  const errors: Error[] = []
9
- const { exp, nbf } = tx
10
- if (nbf < 0) errors.push(new Error('Transaction nbf must be positive'))
9
+ try {
10
+ const { exp, nbf } = tx
11
+ if (nbf < 0) errors.push(new Error('Transaction nbf must be positive'))
11
12
 
12
- if (exp < 0) errors.push(new Error('Transaction exp must be positive'))
13
- if (exp <= nbf) errors.push(new Error('Transaction exp must greater than nbf'))
14
- if (exp - nbf > 10_000) errors.push(new Error('Transaction exp must not be too far in the future'))
13
+ if (exp < 0) errors.push(new Error('Transaction exp must be positive'))
14
+ if (exp <= nbf) errors.push(new Error('Transaction exp must greater than nbf'))
15
+ if (exp - nbf > 10_000) errors.push(new Error('Transaction exp must not be too far in the future'))
16
+ } catch (e) {
17
+ errors.push(new Error(`Failed TransactionDurationValidator: ${e instanceof Error ? e.message : String(e)}`))
18
+ }
15
19
 
16
20
  return errors
17
21
  }
@@ -9,9 +9,13 @@ export const TransactionElevationValidator: HydratedTransactionValidatorFunction
9
9
  ): Promisable<Error[]> => {
10
10
  const errors: Error[] = []
11
11
  try {
12
- extractElevatedHashes(tx)
13
- } catch {
14
- errors.push(new Error('Hydrated transaction does not include all script hashes'))
12
+ try {
13
+ extractElevatedHashes(tx)
14
+ } catch {
15
+ errors.push(new Error('Hydrated transaction does not include all script hashes'))
16
+ }
17
+ } catch (e) {
18
+ errors.push(new Error(`Failed TransactionElevationValidator: ${e instanceof Error ? e.message : String(e)}`))
15
19
  }
16
20
  return errors
17
21
  }
@@ -8,8 +8,12 @@ export const TransactionFromValidator: HydratedTransactionValidatorFunction<Tran
8
8
  [tx]: HydratedTransaction,
9
9
  ): Error[] => {
10
10
  const errors: Error[] = []
11
- const from = asAddress(tx.from)
12
- if (from === undefined)errors.push(new Error('Transaction from is not a valid address'))
13
- else if (!addressesContains(tx, from)) errors.push(new Error('Transaction from address must be listed in addresses'))
11
+ try {
12
+ const from = asAddress(tx.from)
13
+ if (from === undefined)errors.push(new Error('Transaction from is not a valid address'))
14
+ else if (!addressesContains(tx, from)) errors.push(new Error('Transaction from address must be listed in addresses'))
15
+ } catch (e) {
16
+ errors.push(new Error(`Failed TransactionFromValidator: ${e instanceof Error ? e.message : String(e)}`))
17
+ }
14
18
  return errors
15
19
  }
@@ -10,24 +10,28 @@ export const TransactionGasValidator: HydratedTransactionValidatorFunction<Trans
10
10
  [tx]: HydratedTransaction,
11
11
  ): Error[] => {
12
12
  const errors: Error[] = []
13
- if (tx?.fees === undefined) {
14
- errors.push(new Error('Missing fees'))
15
- } else {
16
- const {
17
- base, gasLimit, gasPrice, priority,
18
- } = parseFees(tx.fees)
13
+ try {
14
+ if (tx?.fees === undefined) {
15
+ errors.push(new Error('Missing fees'))
16
+ } else {
17
+ const {
18
+ base, gasLimit, gasPrice, priority,
19
+ } = parseFees(tx.fees)
19
20
 
20
- if (base === undefined) errors.push(new Error('fees.base must be defined and a valid number'))
21
- else if (base < minTransactionFees.base) errors.push(new Error(`fees.base must be >= ${minTransactionFees.base}`))
21
+ if (base === undefined) errors.push(new Error('fees.base must be defined and a valid number'))
22
+ else if (base < minTransactionFees.base) errors.push(new Error(`fees.base must be >= ${minTransactionFees.base}`))
22
23
 
23
- if (gasLimit === undefined) errors.push(new Error('fees.gasLimit must be defined and a valid number'))
24
- else if (gasLimit < minTransactionFees.gasLimit) errors.push(new Error(`fees.gasLimit must be >= ${minTransactionFees.gasLimit}`))
24
+ if (gasLimit === undefined) errors.push(new Error('fees.gasLimit must be defined and a valid number'))
25
+ else if (gasLimit < minTransactionFees.gasLimit) errors.push(new Error(`fees.gasLimit must be >= ${minTransactionFees.gasLimit}`))
25
26
 
26
- if (gasPrice === undefined) errors.push(new Error('fees.gasPrice must be defined and a valid number'))
27
- else if (gasPrice < minTransactionFees.gasPrice) errors.push(new Error(`fees.gasPrice must be >= ${minTransactionFees.gasPrice}`))
27
+ if (gasPrice === undefined) errors.push(new Error('fees.gasPrice must be defined and a valid number'))
28
+ else if (gasPrice < minTransactionFees.gasPrice) errors.push(new Error(`fees.gasPrice must be >= ${minTransactionFees.gasPrice}`))
28
29
 
29
- if (priority === undefined) errors.push(new Error('fees.priority must be defined and a valid number'))
30
- else if (priority < minTransactionFees.priority) errors.push(new Error(`fees.priority must be >= ${minTransactionFees.priority}`))
30
+ if (priority === undefined) errors.push(new Error('fees.priority must be defined and a valid number'))
31
+ else if (priority < minTransactionFees.priority) errors.push(new Error(`fees.priority must be >= ${minTransactionFees.priority}`))
32
+ }
33
+ } catch (e) {
34
+ errors.push(new Error(`Failed TransactionGasValidator: ${e instanceof Error ? e.message : String(e)}`))
31
35
  }
32
36
  return errors
33
37
  }
@@ -1,5 +1,4 @@
1
1
  import type { Address } from '@xylabs/hex'
2
- import { BoundWitnessWrapper } from '@xyo-network/boundwitness-wrapper'
3
2
  import type {
4
3
  HydratedTransaction, HydratedTransactionValidatorFunction, TransactionBoundWitness,
5
4
  } from '@xyo-network/xl1-protocol'
@@ -10,14 +9,11 @@ export const TransactionProtocolValidator: HydratedTransactionValidatorFunction<
10
9
  ): Promise<Error[]> => {
11
10
  const errors: Error[] = []
12
11
  try {
13
- if (!await BoundWitnessWrapper.parse(tx).getValid()) {
14
- errors.push(new Error('failed basic boundwitness parse'))
15
- }
16
12
  if (chainId !== undefined && tx.chain !== chainId) {
17
13
  errors.push(new Error('invalid chain id'))
18
14
  }
19
15
  } catch (ex) {
20
16
  errors.push(new Error('validation excepted'), ex as Error)
21
17
  }
22
- return errors
18
+ return await Promise.resolve(errors)
23
19
  }