@xyo-network/chain-services 1.10.2 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/neutral/AccountBalance/BaseAccountBalanceService.d.ts.map +1 -1
  2. package/dist/neutral/BlockProducer/BaseBlockProducerService.d.ts +17 -3
  3. package/dist/neutral/BlockProducer/BaseBlockProducerService.d.ts.map +1 -1
  4. package/dist/neutral/BlockProducer/generateTransactionFeeTransfers.d.ts +2 -2
  5. package/dist/neutral/BlockProducer/generateTransactionFeeTransfers.d.ts.map +1 -1
  6. package/dist/neutral/ChainBlockNumberIteration/model/BlockNumberIteration.d.ts +2 -2
  7. package/dist/neutral/ChainBlockNumberIteration/model/BlockNumberIteration.d.ts.map +1 -1
  8. package/dist/neutral/ChainValidator/XyoValidator.d.ts +20 -7
  9. package/dist/neutral/ChainValidator/XyoValidator.d.ts.map +1 -1
  10. package/dist/neutral/ChainValidator/model/Validator.d.ts +2 -2
  11. package/dist/neutral/ChainValidator/model/Validator.d.ts.map +1 -1
  12. package/dist/neutral/PendingTransactions/BasePendingTransactions.d.ts +4 -4
  13. package/dist/neutral/PendingTransactions/BasePendingTransactions.d.ts.map +1 -1
  14. package/dist/neutral/PendingTransactions/bundledPayloadToHydratedTransaction.d.ts +2 -2
  15. package/dist/neutral/PendingTransactions/bundledPayloadToHydratedTransaction.d.ts.map +1 -1
  16. package/dist/neutral/PendingTransactions/hydratedTransactionToPayloadBundle.d.ts +2 -2
  17. package/dist/neutral/PendingTransactions/hydratedTransactionToPayloadBundle.d.ts.map +1 -1
  18. package/dist/neutral/StakeIntent/XyoStakeIntentService.d.ts +5 -1
  19. package/dist/neutral/StakeIntent/XyoStakeIntentService.d.ts.map +1 -1
  20. package/dist/neutral/index.mjs +23 -19
  21. package/dist/neutral/index.mjs.map +1 -1
  22. package/package.json +35 -35
  23. package/src/AccountBalance/BaseAccountBalanceService.ts +2 -1
  24. package/src/BlockProducer/BaseBlockProducerService.ts +1 -1
  25. package/src/BlockProducer/generateTransactionFeeTransfers.ts +6 -3
  26. package/src/BlockProducer/spec/BaseBlockProducerService.spec.ts +23 -9
  27. package/src/BlockProducer/spec/generateTransactionTransfer.spec.ts +2 -2
  28. package/src/ChainBlockNumberIteration/model/BlockNumberIteration.ts +2 -2
  29. package/src/ChainValidator/XyoValidator.ts +4 -4
  30. package/src/ChainValidator/model/Validator.ts +2 -2
  31. package/src/PendingTransactions/BasePendingTransactions.ts +8 -7
  32. package/src/PendingTransactions/bundledPayloadToHydratedTransaction.ts +2 -2
  33. package/src/PendingTransactions/hydratedTransactionToPayloadBundle.ts +3 -3
  34. package/src/PendingTransactions/spec/BasePendingTransactions.spec.ts +11 -10
@@ -1,7 +1,8 @@
1
1
  import { assertEx } from '@xylabs/assert'
2
2
  import { type Address, hexFromBigInt } from '@xylabs/hex'
3
+ import { PayloadBuilder } from '@xyo-network/payload-builder'
3
4
  import type {
4
- HydratedTransaction,
5
+ SignedHydratedTransaction,
5
6
  Transfer,
6
7
  XL1,
7
8
  } from '@xyo-network/xl1-protocol'
@@ -9,8 +10,10 @@ import { TransferSchema, XYO_ZERO_ADDRESS } from '@xyo-network/xl1-protocol'
9
10
  import { transactionRequiredGas } from '@xyo-network/xl1-protocol-sdk'
10
11
  import { HydratedTransactionWrapper } from '@xyo-network/xl1-wrappers'
11
12
 
12
- export async function generateTransactionFeeTransfers(address: Address, transactions: HydratedTransaction[]): Promise<Transfer[]> {
13
- const txs = await Promise.all(transactions.map(tx => HydratedTransactionWrapper.parse(tx)))
13
+ export async function generateTransactionFeeTransfers(address: Address, transactions: SignedHydratedTransaction[]): Promise<Transfer[]> {
14
+ const txs = await Promise.all(transactions.map(async (tx) => {
15
+ return HydratedTransactionWrapper.parse([await PayloadBuilder.addStorageMeta(tx[0]), await PayloadBuilder.addStorageMeta(tx[1])])
16
+ }))
14
17
 
15
18
  // merge transactions with the same from address
16
19
  const txBaseFeeCosts: Record<Address, bigint> = {}
@@ -4,8 +4,10 @@ import { filterAs } from '@xylabs/array'
4
4
  import { assertEx } from '@xylabs/assert'
5
5
  import type { CreatableName } from '@xylabs/creatable'
6
6
  import { delay } from '@xylabs/delay'
7
- import type { Address, Hex } from '@xylabs/hex'
8
- import { asAddress, ZERO_HASH } from '@xylabs/hex'
7
+ import type { Address } from '@xylabs/hex'
8
+ import {
9
+ asAddress, hexToBigInt, ZERO_HASH,
10
+ } from '@xylabs/hex'
9
11
  import { Account } from '@xyo-network/account'
10
12
  import type { AccountInstance } from '@xyo-network/account-model'
11
13
  import { MemoryArchivist } from '@xyo-network/archivist-memory'
@@ -17,7 +19,7 @@ import {
17
19
  } from '@xyo-network/payload-model'
18
20
  import { HDWallet } from '@xyo-network/wallet'
19
21
  import type {
20
- BlockBoundWitness, BlockRewardService, ElectionService,
22
+ BlockBoundWitness, BlockRewardService, Chain, ElectionService,
21
23
  HydratedBlock,
22
24
  HydratedBlockStateValidationFunctionV2,
23
25
  StakeIntentService,
@@ -26,7 +28,9 @@ import {
26
28
  asBlockBoundWitness,
27
29
  asChainStakeIntent,
28
30
  asTransactionBoundWitness,
31
+ asTransfer,
29
32
  HydratedBlockStateValidationError,
33
+ XYO_ZERO_ADDRESS,
30
34
  } from '@xyo-network/xl1-protocol'
31
35
  import type { Config } from '@xyo-network/xl1-protocol-sdk'
32
36
  import {
@@ -171,7 +175,7 @@ describe('XyoBlockProducer', () => {
171
175
  let rejectBlock = true
172
176
  const validateHydratedBlockState: HydratedBlockStateValidationFunctionV2 = async (
173
177
  hydratedBlock: HydratedBlock,
174
- chainId: Hex,
178
+ chainId: Chain,
175
179
  ) => {
176
180
  return rejectBlock ? [await Promise.resolve(new HydratedBlockStateValidationError(ZERO_HASH, chainId, hydratedBlock, 'Invalid block'))] : []
177
181
  }
@@ -216,11 +220,21 @@ describe('XyoBlockProducer', () => {
216
220
  expect(result).toBeArrayOfSize(2)
217
221
  const [block, transactionsAndData] = result ?? []
218
222
  expect(block).toBeDefined()
219
- expect(asBlockBoundWitness(block)).toBeDefined()
220
- expect(transactionsAndData).toBeDefined()
221
- expect(transactionsAndData).toBeArray()
222
- const transactions = filterAs(assertEx(transactionsAndData), asTransactionBoundWitness)
223
- expect(transactions).toBeArrayOfSize(newTransactionCount)
223
+ if (block) {
224
+ expect(asBlockBoundWitness(block)).toBeDefined()
225
+ expect(transactionsAndData).toBeDefined()
226
+ expect(transactionsAndData).toBeArray()
227
+ const transactions = filterAs(assertEx(transactionsAndData), asTransactionBoundWitness)
228
+ expect(transactions).toBeArrayOfSize(newTransactionCount)
229
+ const transfers = filterAs(assertEx(transactionsAndData), asTransfer)
230
+ const blockRewardTransfer = transfers.find(transfer => transfer.from === XYO_ZERO_ADDRESS)
231
+ expect(blockRewardTransfer).toBeDefined()
232
+ for (const value of Object.values(blockRewardTransfer?.transfers ?? {})) {
233
+ if (value) {
234
+ expect(hexToBigInt(value)).toEqual(1_500_000_000_000_000_000_000n)
235
+ }
236
+ }
237
+ }
224
238
  })
225
239
  })
226
240
  })
@@ -9,7 +9,7 @@ import { isDefined } from '@xylabs/typeof'
9
9
  import type { Sequence, WithStorageMeta } from '@xyo-network/payload-model'
10
10
  import { XYO_ZERO_ADDRESS } from '@xyo-network/xl1-protocol'
11
11
  import {
12
- defaultTransactionFees, type HydratedTransaction, type Transfer,
12
+ defaultTransactionFees, type SignedHydratedTransactionWithStorageMeta, type Transfer,
13
13
  } from '@xyo-network/xl1-protocol'
14
14
  import {
15
15
  describe, expect, it,
@@ -18,7 +18,7 @@ import {
18
18
  import { generateTransactionFeeTransfers } from '../generateTransactionFeeTransfers.ts'
19
19
 
20
20
  describe('generateTransactionTransfers', () => {
21
- const testCases: HydratedTransaction[][] = [
21
+ const testCases: SignedHydratedTransactionWithStorageMeta[][] = [
22
22
  [
23
23
  [
24
24
  {
@@ -1,7 +1,7 @@
1
1
  import type { Promisable } from '@xylabs/promise'
2
- import type { BlockBoundWitness, HydratedTransaction } from '@xyo-network/xl1-protocol'
2
+ import type { BlockBoundWitness, SignedHydratedTransactionWithStorageMeta } from '@xyo-network/xl1-protocol'
3
3
 
4
4
  export interface BlockNumberIteration {
5
5
  validatePendingBlock(block: BlockBoundWitness): Promisable<Error[]>
6
- validatePendingTransaction(tx: HydratedTransaction): Promise<boolean>
6
+ validatePendingTransaction(tx: SignedHydratedTransactionWithStorageMeta): Promise<boolean>
7
7
  }
@@ -1,15 +1,15 @@
1
1
  import { assertEx } from '@xylabs/assert'
2
2
  import { creatable } from '@xylabs/creatable'
3
- import { Address } from '@xylabs/hex'
4
3
  import { Promisable } from '@xylabs/promise'
5
4
  import { AccountInstance } from '@xyo-network/account-model'
6
5
  import { ArchivistInstance, ReadArchivist } from '@xyo-network/archivist-model'
7
6
  import {
8
7
  BlockBoundWitness,
9
8
  BlockRewardService,
9
+ Chain,
10
10
  ElectionService,
11
11
  HydratedBlockStateValidationFunctionV2,
12
- HydratedTransaction,
12
+ SignedHydratedTransactionWithStorageMeta,
13
13
  StakeIntentService,
14
14
  } from '@xyo-network/xl1-protocol'
15
15
 
@@ -20,7 +20,7 @@ import { Validator } from './model/index.ts'
20
20
  export interface XyoValidatorParams extends BaseServiceParams {
21
21
  account: AccountInstance
22
22
  chainArchivist: ReadArchivist
23
- chainId: Address
23
+ chainId: Chain
24
24
  electionService: ElectionService
25
25
  pendingBundledTransactionsArchivist: ArchivistInstance
26
26
  rewardService: BlockRewardService
@@ -63,7 +63,7 @@ export class XyoValidator<TParams extends XyoValidatorParams = XyoValidatorParam
63
63
  }
64
64
 
65
65
  // TODO: Move to validator and inherit this class from validator
66
- async validatePendingTransaction(hydratedTransaction: HydratedTransaction): Promise<boolean> {
66
+ async validatePendingTransaction(hydratedTransaction: SignedHydratedTransactionWithStorageMeta): Promise<boolean> {
67
67
  const [tx] = hydratedTransaction
68
68
  // Ensure not confirmed already (replay attack)
69
69
  if ((await this.chainArchivist.get([tx._hash])).length > 0) return false
@@ -1,7 +1,7 @@
1
1
  import type { Promisable } from '@xylabs/promise'
2
- import type { BlockBoundWitness, HydratedTransaction } from '@xyo-network/xl1-protocol'
2
+ import type { BlockBoundWitness, SignedHydratedTransactionWithStorageMeta } from '@xyo-network/xl1-protocol'
3
3
 
4
4
  export interface Validator {
5
5
  validatePendingBlock(block: BlockBoundWitness): Promisable<Error[]>
6
- validatePendingTransaction(tx: HydratedTransaction): Promise<boolean>
6
+ validatePendingTransaction(tx: SignedHydratedTransactionWithStorageMeta): Promise<boolean>
7
7
  }
@@ -4,7 +4,7 @@ import { assertEx } from '@xylabs/assert'
4
4
  import { creatable } from '@xylabs/creatable'
5
5
  import { exists } from '@xylabs/exists'
6
6
  import { forget } from '@xylabs/forget'
7
- import { Address, Hash } from '@xylabs/hex'
7
+ import { Hash } from '@xylabs/hex'
8
8
  import { isDefined, isUndefined } from '@xylabs/typeof'
9
9
  import { MemoryArchivist } from '@xyo-network/archivist-memory'
10
10
  import { ArchivistInstance } from '@xyo-network/archivist-model'
@@ -13,7 +13,8 @@ import {
13
13
  Payload, PayloadBundle, Sequence, WithStorageMeta,
14
14
  } from '@xyo-network/payload-model'
15
15
  import {
16
- asBlockBoundWitnessWithHashStorageMeta, HydratedTransaction, isTransactionBoundWitnessWithStorageMeta, PendingTransactionsService,
16
+ asBlockBoundWitnessWithHashStorageMeta, Chain, isTransactionBoundWitnessWithStorageMeta, PendingTransactionsService,
17
+ SignedHydratedTransactionWithStorageMeta,
17
18
  } from '@xyo-network/xl1-protocol'
18
19
  import { TransactionJsonSchemaValidator, validateTransaction } from '@xyo-network/xl1-validation'
19
20
  import { Mutex } from 'async-mutex'
@@ -25,7 +26,7 @@ import { hydratedTransactionToPayloadBundle } from './hydratedTransactionToPaylo
25
26
 
26
27
  export interface BasePendingTransactionsServiceParams extends BaseServiceParams {
27
28
  chainArchivist?: ArchivistInstance
28
- chainId?: Address
29
+ chainId?: Chain
29
30
  pendingBundledTransactionsArchivist?: ArchivistInstance
30
31
  rejectedTransactionsArchivist?: ArchivistInstance
31
32
  }
@@ -134,7 +135,7 @@ export class BasePendingTransactionsService extends BaseService<BasePendingTrans
134
135
  })
135
136
  }
136
137
 
137
- async getPendingTransactions(head: Hash, limit: number): Promise<HydratedTransaction[]> {
138
+ async getPendingTransactions(head: Hash, limit: number): Promise<SignedHydratedTransactionWithStorageMeta[]> {
138
139
  return await this.spanAsync('getPendingTransactions', async () => {
139
140
  // Acquires an exclusive mutex to ensure no race conditions while accessing pending transactions.
140
141
  return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {
@@ -144,7 +145,7 @@ export class BasePendingTransactionsService extends BaseService<BasePendingTrans
144
145
 
145
146
  await this.pruneCuratedPendingTransactionsArchivist(lastHead._hash)
146
147
 
147
- const foundPendingTransactions: HydratedTransaction[] = []
148
+ const foundPendingTransactions: SignedHydratedTransactionWithStorageMeta[] = []
148
149
  let cursor: Sequence | undefined
149
150
 
150
151
  // Continue fetching until the desired number of transactions is reached.
@@ -333,7 +334,7 @@ export class BasePendingTransactionsService extends BaseService<BasePendingTrans
333
334
  * @returns True if the transaction is expired for the given block, false otherwise.
334
335
  */
335
336
  const isTransactionExpired = (block: number) =>
336
- ([txBw]: HydratedTransaction): boolean =>
337
+ ([txBw]: SignedHydratedTransactionWithStorageMeta): boolean =>
337
338
  txBw.exp < block
338
339
 
339
340
  /**
@@ -342,5 +343,5 @@ const isTransactionExpired = (block: number) =>
342
343
  * @returns True if the transaction is active for the given block, false otherwise.
343
344
  */
344
345
  const isTransactionActive = (block: number) =>
345
- ([txBw]: HydratedTransaction): boolean =>
346
+ ([txBw]: SignedHydratedTransactionWithStorageMeta): boolean =>
346
347
  txBw.nbf <= block && txBw.exp >= block
@@ -1,11 +1,11 @@
1
1
  import { PayloadBuilder } from '@xyo-network/payload-builder'
2
2
  import type { PayloadBundle, WithStorageMeta } from '@xyo-network/payload-model'
3
- import type { HydratedTransaction } from '@xyo-network/xl1-protocol'
3
+ import type { SignedHydratedTransactionWithStorageMeta } from '@xyo-network/xl1-protocol'
4
4
  import { asTransactionBoundWitnessWithStorageMeta } from '@xyo-network/xl1-protocol'
5
5
 
6
6
  export const bundledPayloadToHydratedTransaction = async (
7
7
  payload: WithStorageMeta<PayloadBundle>,
8
- ): Promise<HydratedTransaction | undefined> => {
8
+ ): Promise<SignedHydratedTransactionWithStorageMeta | undefined> => {
9
9
  const withStorageMeta = await PayloadBuilder.addStorageMeta(payload.payloads)
10
10
  const tx = asTransactionBoundWitnessWithStorageMeta(withStorageMeta.find(p => p._hash === payload.root))
11
11
  if (tx) {
@@ -2,15 +2,15 @@ import type { Hash } from '@xylabs/hex'
2
2
  import { PayloadBuilder } from '@xyo-network/payload-builder'
3
3
  import type { PayloadBundle } from '@xyo-network/payload-model'
4
4
  import { PayloadBundleSchema } from '@xyo-network/payload-model'
5
- import type { HydratedTransaction } from '@xyo-network/xl1-protocol'
5
+ import type { SignedHydratedTransactionWithStorageMeta } from '@xyo-network/xl1-protocol'
6
6
  import { flattenHydratedTransaction } from '@xyo-network/xl1-protocol-sdk'
7
7
 
8
- export const hydratedTransactionToPayloadBundle = (transaction: HydratedTransaction): PayloadBundle => {
8
+ export const hydratedTransactionToPayloadBundle = (transaction: SignedHydratedTransactionWithStorageMeta): PayloadBundle => {
9
9
  const root = transaction[0]._hash
10
10
  return bundle(root, transaction)
11
11
  }
12
12
 
13
- const bundle = (root: Hash, transaction: HydratedTransaction) => {
13
+ const bundle = (root: Hash, transaction: SignedHydratedTransactionWithStorageMeta) => {
14
14
  const payloads = flattenHydratedTransaction(transaction).flatMap(p => PayloadBuilder.omitStorageMeta(p))
15
15
  return new PayloadBuilder<PayloadBundle>({ schema: PayloadBundleSchema })
16
16
  .fields({ payloads, root })
@@ -14,7 +14,8 @@ import { PayloadBuilder } from '@xyo-network/payload-builder'
14
14
  import type { WithStorageMeta } from '@xyo-network/payload-model'
15
15
  import type {
16
16
  BlockBoundWitness, HashPayload,
17
- HydratedBlock, HydratedTransaction,
17
+ HydratedBlock,
18
+ SignedHydratedTransactionWithStorageMeta,
18
19
  } from '@xyo-network/xl1-protocol'
19
20
  import { HashSchema } from '@xyo-network/xl1-protocol'
20
21
  import {
@@ -64,7 +65,7 @@ describe('BasePendingTransactionsService', () => {
64
65
  })
65
66
 
66
67
  describe('with pending transactions', () => {
67
- let newTransactions: HydratedTransaction[] = []
68
+ let newTransactions: SignedHydratedTransactionWithStorageMeta[] = []
68
69
  beforeEach(async () => {
69
70
  for (let index = 0; index < 5; index++) {
70
71
  const tx = await buildRandomTransaction(TestChainId)
@@ -88,8 +89,8 @@ describe('BasePendingTransactionsService', () => {
88
89
  })
89
90
 
90
91
  describe('with pending and finalized transactions', () => {
91
- let finalizedTransactions: HydratedTransaction[] = []
92
- let newTransactions: HydratedTransaction[] = []
92
+ let finalizedTransactions: SignedHydratedTransactionWithStorageMeta[] = []
93
+ let newTransactions: SignedHydratedTransactionWithStorageMeta[] = []
93
94
  beforeEach(async () => {
94
95
  for (let index = 0; index < 5; index++) {
95
96
  const tx = await buildRandomTransaction(TestChainId)
@@ -118,7 +119,7 @@ describe('BasePendingTransactionsService', () => {
118
119
  .build()
119
120
  beforeEach(async () => {})
120
121
  it('when unique should allow transactions', async () => {
121
- let newTransactions: HydratedTransaction[] = []
122
+ let newTransactions: SignedHydratedTransactionWithStorageMeta[] = []
122
123
  // NOTE: Cast to Account to allow loadPreviousHash to be called
123
124
  const signer = await Account.random()
124
125
  const transaction1 = await buildTransaction(TestChainId, [hashPayload], [], signer, 0, 100)
@@ -133,7 +134,7 @@ describe('BasePendingTransactionsService', () => {
133
134
  expect(result.length).toEqual(newTransactions.length)
134
135
  })
135
136
  it('when non-unique should filter duplicate transactions', async () => {
136
- let newTransactions: HydratedTransaction[] = []
137
+ let newTransactions: SignedHydratedTransactionWithStorageMeta[] = []
137
138
  const previousHash = 'bb27dd470ccf91665d573a16b4f652a47b8a24686d1b44c189c1fa826cd3fef5'
138
139
  // NOTE: Cast to Account to allow loadPreviousHash to be called
139
140
  const signer = await Account.random() as Account
@@ -154,7 +155,7 @@ describe('BasePendingTransactionsService', () => {
154
155
 
155
156
  describe('with expiring transactions', () => {
156
157
  const insertTransaction = async (nbf: number, exp: number) => {
157
- const newTransactions: HydratedTransaction[] = []
158
+ const newTransactions: SignedHydratedTransactionWithStorageMeta[] = []
158
159
  const signer = await Account.random()
159
160
  const hashPayload = new PayloadBuilder<HashPayload>({ schema: HashSchema })
160
161
  .fields({ hash: head._hash })
@@ -237,8 +238,8 @@ describe('BasePendingTransactionsService', () => {
237
238
  })
238
239
 
239
240
  describe('with pending and rejected transactions', () => {
240
- let rejectedTransactions: HydratedTransaction[] = []
241
- let newTransactions: HydratedTransaction[] = []
241
+ let rejectedTransactions: SignedHydratedTransactionWithStorageMeta[] = []
242
+ let newTransactions: SignedHydratedTransactionWithStorageMeta[] = []
242
243
  beforeEach(async () => {
243
244
  for (let index = 0; index < 5; index++) {
244
245
  const tx = await buildRandomTransaction(TestChainId)
@@ -263,7 +264,7 @@ describe('BasePendingTransactionsService', () => {
263
264
  describe('with invalid transactions in mempool', () => {
264
265
  beforeEach(async () => {
265
266
  const incorrectChainId = assertEx(asAddress('1234567890abcdef1234567890abcdef12345678'))
266
- const invalidTransactions: HydratedTransaction[] = [await buildRandomTransaction(incorrectChainId)]
267
+ const invalidTransactions: SignedHydratedTransactionWithStorageMeta[] = [await buildRandomTransaction(incorrectChainId)]
267
268
  const pending = invalidTransactions.map(hydratedTransactionToPayloadBundle)
268
269
  await pendingBundledTransactionsArchivist.insert(pending)
269
270
  })