@aztec/txe 0.0.1-commit.b2a5d0dd1 → 0.0.1-commit.b3d3157a

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 (144) hide show
  1. package/dest/ContractClassRegistry-PII7Q556.js +3 -0
  2. package/dest/ContractClassRegistry-PII7Q556.js.map +7 -0
  3. package/dest/ContractInstanceRegistry-3MHLGFNZ.js +3 -0
  4. package/dest/ContractInstanceRegistry-3MHLGFNZ.js.map +7 -0
  5. package/dest/FeeJuice-TQV5AQK7.js +3 -0
  6. package/dest/FeeJuice-TQV5AQK7.js.map +7 -0
  7. package/dest/MultiCallEntrypoint-SBJUIJY7.js +3 -0
  8. package/dest/MultiCallEntrypoint-SBJUIJY7.js.map +7 -0
  9. package/dest/SchnorrAccount-MQXPIZ44.js +3 -0
  10. package/dest/SchnorrAccount-MQXPIZ44.js.map +7 -0
  11. package/dest/bin/check_txe_oracle_version.d.ts +2 -0
  12. package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
  13. package/dest/bin/check_txe_oracle_version.js +61 -0
  14. package/dest/bin/index.js +3 -30
  15. package/dest/bin/index.js.map +7 -0
  16. package/dest/bin/oracle_test_server.d.ts +3 -0
  17. package/dest/bin/oracle_test_server.d.ts.map +1 -0
  18. package/dest/bin/oracle_test_server.js +41 -0
  19. package/dest/chunk-2FGZE6YL.js +265 -0
  20. package/dest/chunk-2FGZE6YL.js.map +7 -0
  21. package/dest/chunk-6HRVNWJU.js +304 -0
  22. package/dest/chunk-6HRVNWJU.js.map +7 -0
  23. package/dest/chunk-BJVAAXNA.js +3 -0
  24. package/dest/chunk-BJVAAXNA.js.map +7 -0
  25. package/dest/constants.d.ts +5 -1
  26. package/dest/constants.d.ts.map +1 -1
  27. package/dest/constants.js +8 -0
  28. package/dest/dispatcher_pool.d.ts +67 -0
  29. package/dest/dispatcher_pool.d.ts.map +1 -0
  30. package/dest/dispatcher_pool.js +284 -0
  31. package/dest/index.d.ts +185 -7
  32. package/dest/index.d.ts.map +1 -1
  33. package/dest/index.js +70 -190
  34. package/dest/metafile.json +38642 -0
  35. package/dest/msgpackr_fr_extension.d.ts +2 -0
  36. package/dest/msgpackr_fr_extension.d.ts.map +1 -0
  37. package/dest/msgpackr_fr_extension.js +21 -0
  38. package/dest/oracle/interfaces.d.ts +33 -8
  39. package/dest/oracle/interfaces.d.ts.map +1 -1
  40. package/dest/oracle/test-resolver/fixtures.d.ts +43 -0
  41. package/dest/oracle/test-resolver/fixtures.d.ts.map +1 -0
  42. package/dest/oracle/test-resolver/fixtures.js +39 -0
  43. package/dest/oracle/test-resolver/index.d.ts +9 -0
  44. package/dest/oracle/test-resolver/index.d.ts.map +1 -0
  45. package/dest/oracle/test-resolver/index.js +33 -0
  46. package/dest/oracle/test-resolver/resolver.d.ts +34 -0
  47. package/dest/oracle/test-resolver/resolver.d.ts.map +1 -0
  48. package/dest/oracle/test-resolver/resolver.js +114 -0
  49. package/dest/oracle/txe_oracle_public_context.d.ts +26 -2
  50. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  51. package/dest/oracle/txe_oracle_public_context.js +43 -1
  52. package/dest/oracle/txe_oracle_registry.d.ts +147 -0
  53. package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
  54. package/dest/oracle/txe_oracle_registry.js +562 -0
  55. package/dest/oracle/txe_oracle_top_level_context.d.ts +27 -13
  56. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  57. package/dest/oracle/txe_oracle_top_level_context.js +129 -52
  58. package/dest/oracle/txe_oracle_version.d.ts +17 -0
  59. package/dest/oracle/txe_oracle_version.d.ts.map +1 -0
  60. package/dest/oracle/txe_oracle_version.js +14 -0
  61. package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
  62. package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
  63. package/dest/oracle/txe_private_execution_oracle.js +15 -0
  64. package/dest/rpc_server.d.ts +14 -0
  65. package/dest/rpc_server.d.ts.map +1 -0
  66. package/dest/rpc_server.js +78 -0
  67. package/dest/rpc_translator.d.ts +96 -266
  68. package/dest/rpc_translator.d.ts.map +1 -1
  69. package/dest/rpc_translator.js +699 -730
  70. package/dest/server.bundle.js +3 -0
  71. package/dest/server.bundle.js.map +7 -0
  72. package/dest/state_machine/archiver.d.ts +4 -3
  73. package/dest/state_machine/archiver.d.ts.map +1 -1
  74. package/dest/state_machine/archiver.js +24 -14
  75. package/dest/state_machine/dummy_p2p_client.d.ts +11 -6
  76. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  77. package/dest/state_machine/dummy_p2p_client.js +11 -2
  78. package/dest/state_machine/index.d.ts +4 -2
  79. package/dest/state_machine/index.d.ts.map +1 -1
  80. package/dest/state_machine/index.js +16 -2
  81. package/dest/state_machine/mock_epoch_cache.d.ts +1 -3
  82. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  83. package/dest/state_machine/mock_epoch_cache.js +0 -6
  84. package/dest/state_machine/synchronizer.js +1 -1
  85. package/dest/txe_session.d.ts +75 -14
  86. package/dest/txe_session.d.ts.map +1 -1
  87. package/dest/txe_session.js +164 -38
  88. package/dest/utils/encoding.d.ts +191 -0
  89. package/dest/utils/encoding.d.ts.map +1 -0
  90. package/dest/{util → utils}/encoding.js +3 -2
  91. package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
  92. package/dest/utils/expected_failure_error.d.ts.map +1 -0
  93. package/dest/{util → utils}/txe_account_store.d.ts +1 -1
  94. package/dest/utils/txe_account_store.d.ts.map +1 -0
  95. package/dest/utils/txe_artifact_resolver.d.ts +37 -0
  96. package/dest/utils/txe_artifact_resolver.d.ts.map +1 -0
  97. package/dest/utils/txe_artifact_resolver.js +161 -0
  98. package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
  99. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
  100. package/dest/worker.bundle.js +3 -0
  101. package/dest/worker.bundle.js.map +7 -0
  102. package/dest/worker.d.ts +2 -0
  103. package/dest/worker.d.ts.map +1 -0
  104. package/dest/worker.js +92 -0
  105. package/package.json +38 -21
  106. package/src/bin/check_txe_oracle_version.ts +70 -0
  107. package/src/bin/index.ts +11 -2
  108. package/src/bin/oracle_test_server.ts +51 -0
  109. package/src/constants.ts +10 -0
  110. package/src/dispatcher_pool.ts +316 -0
  111. package/src/index.ts +97 -227
  112. package/src/msgpackr_fr_extension.ts +23 -0
  113. package/src/oracle/interfaces.ts +29 -7
  114. package/src/oracle/test-resolver/fixtures.ts +84 -0
  115. package/src/oracle/test-resolver/index.ts +45 -0
  116. package/src/oracle/test-resolver/resolver.ts +165 -0
  117. package/src/oracle/txe_oracle_public_context.ts +60 -0
  118. package/src/oracle/txe_oracle_registry.ts +401 -0
  119. package/src/oracle/txe_oracle_top_level_context.ts +157 -62
  120. package/src/oracle/txe_oracle_version.ts +17 -0
  121. package/src/oracle/txe_private_execution_oracle.ts +30 -0
  122. package/src/rpc_server.ts +87 -0
  123. package/src/rpc_translator.ts +774 -1043
  124. package/src/state_machine/archiver.ts +37 -16
  125. package/src/state_machine/dummy_p2p_client.ts +25 -9
  126. package/src/state_machine/index.ts +17 -4
  127. package/src/state_machine/mock_epoch_cache.ts +0 -8
  128. package/src/state_machine/synchronizer.ts +1 -1
  129. package/src/txe_session.ts +269 -39
  130. package/src/{util → utils}/encoding.ts +3 -2
  131. package/src/utils/txe_artifact_resolver.ts +217 -0
  132. package/src/worker.ts +98 -0
  133. package/dest/util/encoding.d.ts +0 -790
  134. package/dest/util/encoding.d.ts.map +0 -1
  135. package/dest/util/expected_failure_error.d.ts.map +0 -1
  136. package/dest/util/txe_account_store.d.ts.map +0 -1
  137. package/dest/util/txe_public_contract_data_source.d.ts +0 -20
  138. package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
  139. /package/dest/{util → utils}/expected_failure_error.js +0 -0
  140. /package/dest/{util → utils}/txe_account_store.js +0 -0
  141. /package/dest/{util → utils}/txe_public_contract_data_source.js +0 -0
  142. /package/src/{util → utils}/expected_failure_error.ts +0 -0
  143. /package/src/{util → utils}/txe_account_store.ts +0 -0
  144. /package/src/{util → utils}/txe_public_contract_data_source.ts +0 -0
@@ -0,0 +1,37 @@
1
+ import { AztecAddress } from '@aztec/aztec.js/addresses';
2
+ import { type ContractInstanceWithAddress } from '@aztec/aztec.js/contracts';
3
+ import { Fr } from '@aztec/aztec.js/fields';
4
+ import type { ContractStore } from '@aztec/pxe/client/lazy';
5
+ import type { ContractArtifactWithHash } from '@aztec/stdlib/contract';
6
+ export interface ResolvedArtifact {
7
+ artifact: ContractArtifactWithHash;
8
+ instance: ContractInstanceWithAddress;
9
+ }
10
+ /**
11
+ * Resolves and caches contract artifacts and their associated instances.
12
+ *
13
+ * Artifact hash computation is expensive, so this service deduplicates both completed and in-flight computations.
14
+ * Two cache levels are kept: full deploys (artifact + computed instance) keyed by the full deploy context, and loaded +
15
+ * hashed artifacts keyed by the compiled-bytecode hash so deploys of the same contract with different args / salt /
16
+ * deployer reuse the same `ContractArtifactWithHash`.
17
+ */
18
+ export declare class TXEArtifactResolver {
19
+ #private;
20
+ private readonly contractStore;
21
+ private readonly schnorrClassId;
22
+ constructor(contractStore: ContractStore, schnorrClassId: Fr);
23
+ /** Resolves the Schnorr account contract artifact and instance for the given secret, caching the result. */
24
+ resolveAccountArtifact(secret: Fr): Promise<ResolvedArtifact>;
25
+ /** Resolves a contract artifact from disk by path, computes its instance, and caches the result. */
26
+ resolveDeployArtifact({ rootPath, packageName, contractPath, initializer, args, secret, salt, deployer }: {
27
+ rootPath: string;
28
+ packageName: string;
29
+ contractPath: string;
30
+ initializer: string;
31
+ args: Fr[];
32
+ secret: Fr;
33
+ salt: Fr;
34
+ deployer: AztecAddress;
35
+ }): Promise<ResolvedArtifact>;
36
+ }
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhlX2FydGlmYWN0X3Jlc29sdmVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvdHhlX2FydGlmYWN0X3Jlc29sdmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN6RCxPQUFPLEVBQ0wsS0FBSywyQkFBMkIsRUFFakMsTUFBTSwyQkFBMkIsQ0FBQztBQUNuQyxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFHNUMsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDNUQsT0FBTyxLQUFLLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQVF2RSxNQUFNLFdBQVcsZ0JBQWdCO0lBQy9CLFFBQVEsRUFBRSx3QkFBd0IsQ0FBQztJQUNuQyxRQUFRLEVBQUUsMkJBQTJCLENBQUM7Q0FDdkM7QUFpQ0Q7Ozs7Ozs7R0FPRztBQUNILHFCQUFhLG1CQUFtQjs7SUFNNUIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxhQUFhO0lBQzlCLE9BQU8sQ0FBQyxRQUFRLENBQUMsY0FBYztJQUZqQyxZQUNtQixhQUFhLEVBQUUsYUFBYSxFQUM1QixjQUFjLEVBQUUsRUFBRSxFQUNqQztJQUVKLDRHQUE0RztJQUM1RyxzQkFBc0IsQ0FBQyxNQUFNLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUk1RDtJQUVELG9HQUFvRztJQUM5RixxQkFBcUIsQ0FBQyxFQUMxQixRQUFRLEVBQ1IsV0FBVyxFQUNYLFlBQVksRUFDWixXQUFXLEVBQ1gsSUFBSSxFQUNKLE1BQU0sRUFDTixJQUFJLEVBQ0osUUFBUSxFQUNULEVBQUU7UUFDRCxRQUFRLEVBQUUsTUFBTSxDQUFDO1FBQ2pCLFdBQVcsRUFBRSxNQUFNLENBQUM7UUFDcEIsWUFBWSxFQUFFLE1BQU0sQ0FBQztRQUNyQixXQUFXLEVBQUUsTUFBTSxDQUFDO1FBQ3BCLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUNYLE1BQU0sRUFBRSxFQUFFLENBQUM7UUFDWCxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBQ1QsUUFBUSxFQUFFLFlBQVksQ0FBQztLQUN4QixHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQXdCNUI7Q0E4RkYifQ==
@@ -0,0 +1 @@
1
+ {"version":3,"file":"txe_artifact_resolver.d.ts","sourceRoot":"","sources":["../../src/utils/txe_artifact_resolver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EACL,KAAK,2BAA2B,EAEjC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAC;AAG5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAQvE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,wBAAwB,CAAC;IACnC,QAAQ,EAAE,2BAA2B,CAAC;CACvC;AAiCD;;;;;;;GAOG;AACH,qBAAa,mBAAmB;;IAM5B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAFjC,YACmB,aAAa,EAAE,aAAa,EAC5B,cAAc,EAAE,EAAE,EACjC;IAEJ,4GAA4G;IAC5G,sBAAsB,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAI5D;IAED,oGAAoG;IAC9F,qBAAqB,CAAC,EAC1B,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,WAAW,EACX,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,QAAQ,EACT,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,EAAE,EAAE,CAAC;QACX,MAAM,EAAE,EAAE,CAAC;QACX,IAAI,EAAE,EAAE,CAAC;QACT,QAAQ,EAAE,YAAY,CAAC;KACxB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAwB5B;CA8FF"}
@@ -0,0 +1,161 @@
1
+ import { loadContractArtifact } from '@aztec/aztec.js/abi';
2
+ import { AztecAddress } from '@aztec/aztec.js/addresses';
3
+ import { getContractInstanceFromInstantiationParams } from '@aztec/aztec.js/contracts';
4
+ import { Fr } from '@aztec/aztec.js/fields';
5
+ import { PublicKeys, deriveKeys } from '@aztec/aztec.js/keys';
6
+ import { createLogger } from '@aztec/foundation/log';
7
+ import { computeArtifactHash } from '@aztec/stdlib/contract';
8
+ import { createHash } from 'crypto';
9
+ import { createReadStream } from 'fs';
10
+ import { readFile, readdir } from 'fs/promises';
11
+ import { join, parse } from 'path';
12
+ /**
13
+ * Cache + in-flight map pair. Lookup hits the cache, then awaits an in-flight `compute()` if one
14
+ * exists, otherwise starts one and stores it. Guarantees `compute()` runs at most once per `key`
15
+ * across concurrent callers, which matters because `computeArtifactHash` is expensive.
16
+ */ class AsyncCache {
17
+ #cache = new Map();
18
+ #inFlight = new Map();
19
+ getOrCompute(key, compute) {
20
+ const cached = this.#cache.get(key);
21
+ if (cached !== undefined) {
22
+ return Promise.resolve(cached);
23
+ }
24
+ let pending = this.#inFlight.get(key);
25
+ if (!pending) {
26
+ pending = (async ()=>{
27
+ try {
28
+ const value = await compute();
29
+ this.#cache.set(key, value);
30
+ return value;
31
+ } finally{
32
+ this.#inFlight.delete(key);
33
+ }
34
+ })();
35
+ this.#inFlight.set(key, pending);
36
+ }
37
+ return pending;
38
+ }
39
+ }
40
+ /**
41
+ * Resolves and caches contract artifacts and their associated instances.
42
+ *
43
+ * Artifact hash computation is expensive, so this service deduplicates both completed and in-flight computations.
44
+ * Two cache levels are kept: full deploys (artifact + computed instance) keyed by the full deploy context, and loaded +
45
+ * hashed artifacts keyed by the compiled-bytecode hash so deploys of the same contract with different args / salt /
46
+ * deployer reuse the same `ContractArtifactWithHash`.
47
+ */ export class TXEArtifactResolver {
48
+ contractStore;
49
+ schnorrClassId;
50
+ #deployments;
51
+ #artifacts;
52
+ #logger;
53
+ constructor(contractStore, schnorrClassId){
54
+ this.contractStore = contractStore;
55
+ this.schnorrClassId = schnorrClassId;
56
+ this.#deployments = new AsyncCache();
57
+ this.#artifacts = new AsyncCache();
58
+ this.#logger = createLogger('txe:artifact_resolver');
59
+ }
60
+ /** Resolves the Schnorr account contract artifact and instance for the given secret, caching the result. */ resolveAccountArtifact(secret) {
61
+ return this.#deployments.getOrCompute(`SchnorrAccountContract-${secret}`, ()=>this.#computeAccountArtifact(secret));
62
+ }
63
+ /** Resolves a contract artifact from disk by path, computes its instance, and caches the result. */ async resolveDeployArtifact({ rootPath, packageName, contractPath, initializer, args, secret, salt, deployer }) {
64
+ const publicKeys = secret.equals(Fr.ZERO) ? PublicKeys.default() : (await deriveKeys(secret)).publicKeys;
65
+ const publicKeysHash = await publicKeys.hash();
66
+ const artifactPath = await this.#resolveArtifactPath(rootPath, packageName, contractPath);
67
+ const fileHash = await this.#fastHashFile(artifactPath);
68
+ const { dir: contractDirectory, base: contractFilename } = parse(contractPath);
69
+ const cacheKey = `${contractDirectory ?? ''}-${contractFilename}-${initializer}-${args.map((arg)=>arg.toString()).join('-')}-${publicKeysHash}-${salt}-${deployer}-${fileHash}`;
70
+ return this.#deployments.getOrCompute(cacheKey, ()=>this.#computeDeployArtifact(artifactPath, fileHash, initializer, args, salt, publicKeys, publicKeysHash, deployer));
71
+ }
72
+ async #resolveArtifactPath(rootPath, packageName, contractPath) {
73
+ const { dir: contractDirectory, base: contractFilename } = parse(contractPath);
74
+ if (contractDirectory) {
75
+ if (contractDirectory.includes('@')) {
76
+ // env.deploy("../path/to/workspace/root@packageName/contractName")
77
+ const [workspace, pkg] = contractDirectory.split('@');
78
+ const targetPath = join(rootPath, workspace, '/target');
79
+ this.#logger.debug(`Looking for compiled artifact in workspace ${targetPath}`);
80
+ return join(targetPath, `${pkg}-${contractFilename}.json`);
81
+ } else {
82
+ // env.deploy("../path/to/contract/root/contractName")
83
+ const targetPath = join(rootPath, contractDirectory, '/target');
84
+ this.#logger.debug(`Looking for compiled artifact in ${targetPath}`);
85
+ const [artifactPath] = (await readdir(targetPath)).filter((file)=>file.endsWith(`-${contractFilename}.json`));
86
+ return artifactPath;
87
+ }
88
+ } else {
89
+ // env.deploy("contractName")
90
+ return join(rootPath, './target', `${packageName}-${contractFilename}.json`);
91
+ }
92
+ }
93
+ async #computeAccountArtifact(secret) {
94
+ const [artifactFromStore, classWithPreimage] = await Promise.all([
95
+ this.contractStore.getContractArtifact(this.schnorrClassId),
96
+ this.contractStore.getContractClassWithPreimage(this.schnorrClassId)
97
+ ]);
98
+ if (!artifactFromStore || !classWithPreimage) {
99
+ throw new Error(`SchnorrAccount not found in shared contract store at class id ${this.schnorrClassId.toString()}`);
100
+ }
101
+ const artifact = {
102
+ ...artifactFromStore,
103
+ artifactHash: classWithPreimage.artifactHash
104
+ };
105
+ const keys = await deriveKeys(secret);
106
+ const args = [
107
+ keys.publicKeys.ivpkM.x,
108
+ keys.publicKeys.ivpkM.y
109
+ ];
110
+ const instance = await getContractInstanceFromInstantiationParams(artifact, {
111
+ constructorArgs: args,
112
+ skipArgsDecoding: true,
113
+ salt: Fr.ONE,
114
+ publicKeys: keys.publicKeys,
115
+ constructorArtifact: 'constructor',
116
+ deployer: AztecAddress.ZERO
117
+ });
118
+ return {
119
+ artifact,
120
+ instance
121
+ };
122
+ }
123
+ async #computeDeployArtifact(artifactPath, fileHash, initializer, args, salt, publicKeys, publicKeysHash, deployer) {
124
+ // Inner cache: artifact load + hash depends only on the compiled bytecode (`fileHash`), so subsequent deploys of
125
+ // the same contract — regardless of constructor args / deployer / salt — reuse the same `ContractArtifactWithHash`.
126
+ const artifact = await this.#artifacts.getOrCompute(fileHash, async ()=>{
127
+ this.#logger.debug(`Loading compiled artifact ${artifactPath}`);
128
+ const artifactJSON = JSON.parse(await readFile(artifactPath, 'utf-8'));
129
+ const artifactWithoutHash = loadContractArtifact(artifactJSON);
130
+ return {
131
+ ...artifactWithoutHash,
132
+ artifactHash: await computeArtifactHash(artifactWithoutHash)
133
+ };
134
+ });
135
+ this.#logger.debug(`Deploy ${artifact.name} with initializer ${initializer}(${args}) and public keys hash ${publicKeysHash}`);
136
+ const instance = await getContractInstanceFromInstantiationParams(artifact, {
137
+ constructorArgs: args,
138
+ skipArgsDecoding: true,
139
+ salt,
140
+ publicKeys,
141
+ constructorArtifact: initializer || undefined,
142
+ deployer
143
+ });
144
+ return {
145
+ artifact,
146
+ instance
147
+ };
148
+ }
149
+ #fastHashFile(path) {
150
+ return new Promise((resolve)=>{
151
+ const fd = createReadStream(path);
152
+ const hash = createHash('sha1');
153
+ hash.setEncoding('hex');
154
+ fd.on('end', function() {
155
+ hash.end();
156
+ resolve(hash.read());
157
+ });
158
+ fd.pipe(hash);
159
+ });
160
+ }
161
+ }
@@ -0,0 +1,20 @@
1
+ import { BlockNumber } from '@aztec/foundation/branded-types';
2
+ import { Fr } from '@aztec/foundation/curves/bn254';
3
+ import type { ContractStore } from '@aztec/pxe/server';
4
+ import { type ContractArtifact, FunctionSelector } from '@aztec/stdlib/abi';
5
+ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
6
+ import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
7
+ export declare class TXEPublicContractDataSource implements ContractDataSource {
8
+ private blockNumber;
9
+ private contractStore;
10
+ constructor(blockNumber: BlockNumber, contractStore: ContractStore);
11
+ getBlockNumber(): Promise<BlockNumber>;
12
+ getContractClass(id: Fr): Promise<ContractClassPublic | undefined>;
13
+ getBytecodeCommitment(id: Fr): Promise<Fr | undefined>;
14
+ getContract(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined>;
15
+ getContractClassIds(): Promise<Fr[]>;
16
+ getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined>;
17
+ getDebugFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined>;
18
+ registerContractFunctionSignatures(_signatures: []): Promise<void>;
19
+ }
20
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhlX3B1YmxpY19jb250cmFjdF9kYXRhX3NvdXJjZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL3R4ZV9wdWJsaWNfY29udHJhY3RfZGF0YV9zb3VyY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzlELE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsS0FBSyxnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzVFLE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ2hFLE9BQU8sS0FBSyxFQUFFLG1CQUFtQixFQUFFLGtCQUFrQixFQUFFLDJCQUEyQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFbkgscUJBQWEsMkJBQTRCLFlBQVcsa0JBQWtCO0lBRWxFLE9BQU8sQ0FBQyxXQUFXO0lBQ25CLE9BQU8sQ0FBQyxhQUFhO0lBRnZCLFlBQ1UsV0FBVyxFQUFFLFdBQVcsRUFDeEIsYUFBYSxFQUFFLGFBQWEsRUFDbEM7SUFFSixjQUFjLElBQUksT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUVyQztJQUVLLGdCQUFnQixDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixHQUFHLFNBQVMsQ0FBQyxDQVl2RTtJQUVLLHFCQUFxQixDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FHM0Q7SUFFSyxXQUFXLENBQUMsT0FBTyxFQUFFLFlBQVksR0FBRyxPQUFPLENBQUMsMkJBQTJCLEdBQUcsU0FBUyxDQUFDLENBR3pGO0lBRUQsbUJBQW1CLElBQUksT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBRW5DO0lBRUssbUJBQW1CLENBQUMsT0FBTyxFQUFFLFlBQVksR0FBRyxPQUFPLENBQUMsZ0JBQWdCLEdBQUcsU0FBUyxDQUFDLENBR3RGO0lBRUssb0JBQW9CLENBQUMsT0FBTyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUMsQ0FFekc7SUFFRCxrQ0FBa0MsQ0FBQyxXQUFXLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FFakU7Q0FDRiJ9
@@ -0,0 +1 @@
1
+ {"version":3,"file":"txe_public_contract_data_source.d.ts","sourceRoot":"","sources":["../../src/utils/txe_public_contract_data_source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,KAAK,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAEnH,qBAAa,2BAA4B,YAAW,kBAAkB;IAElE,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,aAAa;IAFvB,YACU,WAAW,EAAE,WAAW,EACxB,aAAa,EAAE,aAAa,EAClC;IAEJ,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC,CAErC;IAEK,gBAAgB,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAYvE;IAEK,qBAAqB,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,GAAG,SAAS,CAAC,CAG3D;IAEK,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,2BAA2B,GAAG,SAAS,CAAC,CAGzF;IAED,mBAAmB,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC,CAEnC;IAEK,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAGtF;IAEK,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAEzG;IAED,kCAAkC,CAAC,WAAW,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjE;CACF"}
@@ -0,0 +1,3 @@
1
+ import { createRequire as __txeCreateRequire } from 'node:module';
2
+ const require = __txeCreateRequire(import.meta.url);
3
+ import{TXEDispatcher,activeSessionCount,createLogger}from"./chunk-2FGZE6YL.js";import{__name}from"./chunk-BJVAAXNA.js";import{BackendType,Barretenberg,BarretenbergSync}from"@aztec/bb.js";import{parentPort,workerData}from"node:worker_threads";Barretenberg.initSingleton({backend:BackendType.Wasm,skipSrsInit:!0,threads:1});BarretenbergSync.initSingleton({backend:BackendType.Wasm});if(!parentPort)throw new Error("worker.ts must be loaded as a worker_thread");var port=parentPort,logger=createLogger("txe:worker"),dispatcherOpts={contractStoreSourceDir:workerData.contractStoreSourceDir,schnorrClassId:workerData.schnorrClassId},dispatcher=new TXEDispatcher(logger,dispatcherOpts);function serializeError(err){return err instanceof Error?{message:err.message,name:err.name,stack:err.stack}:{message:String(err)}}__name(serializeError,"serializeError");process.env.TXE_WORKER_MEMSTAT==="1"&&setInterval(()=>{let m=process.memoryUsage();port.postMessage({type:"memstat",sessions:activeSessionCount(),rss:m.rss,heapTotal:m.heapTotal,heapUsed:m.heapUsed,external:m.external,arrayBuffers:m.arrayBuffers})},2e3).unref();port.on("message",msg=>{switch(msg.type){case"foreign-call":(async()=>{try{let value=await dispatcher.resolve_foreign_call(msg.callData);port.postMessage({type:"result",requestId:msg.requestId,ok:!0,value})}catch(err){port.postMessage({type:"result",requestId:msg.requestId,ok:!1,error:serializeError(err)})}})();return;case"dispose-session":dispatcher.disposeSession(msg.sessionId).catch(err=>logger.warn("disposeSession failed",err));return}});
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/worker.ts"],
4
+ "sourcesContent": ["import { BackendType, Barretenberg, BarretenbergSync } from '@aztec/bb.js';\nimport { type Logger, createLogger } from '@aztec/foundation/log';\n\nimport { parentPort, workerData } from 'node:worker_threads';\n\n// Importing `./index.js` registers the msgpackr Fr extension transitively (via\n// ./msgpackr_fr_extension.js); this must happen before any `sendMessage` call.\nimport { TXEDispatcher, type TXEDispatcherOptions, type TXEForeignCallInput, activeSessionCount } from './index.js';\n\n// Seed both bb.js singletons with the WASM backend before any crypto call. `initSingleton`\n// binds the singleton to whichever backend the first call requests, so this pre-empts the\n// implicit `Barretenberg.initSingleton()` inside `poseidon2Hash` from `@aztec/foundation/crypto`.\n// TXE only needs hashing (no proving, no verification), so WASM is sufficient and\n// `skipSrsInit: true` skips the CRS load. `threads: 1` keeps the WASM backend on a single\n// thread \u2014 additional threads would each spawn a nested worker_thread, multiplying memory cost\n// per pool worker.\nvoid Barretenberg.initSingleton({ backend: BackendType.Wasm, skipSrsInit: true, threads: 1 });\nvoid BarretenbergSync.initSingleton({ backend: BackendType.Wasm });\n\nif (!parentPort) {\n throw new Error('worker.ts must be loaded as a worker_thread');\n}\n\nconst port = parentPort;\nconst logger: Logger = createLogger('txe:worker');\n\n// The pool builds a template LMDB containing the protocol contracts + the SchnorrAccount\n// artifact on the main thread and passes its data dir via `workerData`. The dispatcher clones\n// that LMDB into a per-worker store on first use, so this worker gets a writable copy already\n// populated.\nconst dispatcherOpts: TXEDispatcherOptions = {\n contractStoreSourceDir: workerData.contractStoreSourceDir,\n schnorrClassId: workerData.schnorrClassId,\n};\nconst dispatcher = new TXEDispatcher(logger, dispatcherOpts);\n\ninterface ForeignCallRequest {\n type: 'foreign-call';\n requestId: number;\n callData: TXEForeignCallInput;\n}\n\ninterface DisposeSessionMessage {\n type: 'dispose-session';\n sessionId: number;\n}\n\ntype IncomingMessage = ForeignCallRequest | DisposeSessionMessage;\n\ninterface SerializedError {\n message: string;\n name?: string;\n stack?: string;\n}\n\nfunction serializeError(err: unknown): SerializedError {\n if (err instanceof Error) {\n return { message: err.message, name: err.name, stack: err.stack };\n }\n return { message: String(err) };\n}\n\n// Periodic memstat for diagnostic builds \u2014 set TXE_WORKER_MEMSTAT=1 to enable. Posts JS-heap\n// breakdown + active-session count back to the dispatcher so we can attribute RSS growth\n// between V8 heap (would show in heapUsed) and native (LMDB / world-state / WASM).\nif (process.env.TXE_WORKER_MEMSTAT === '1') {\n setInterval(() => {\n const m = process.memoryUsage();\n port.postMessage({\n type: 'memstat',\n sessions: activeSessionCount(),\n rss: m.rss,\n heapTotal: m.heapTotal,\n heapUsed: m.heapUsed,\n external: m.external,\n arrayBuffers: m.arrayBuffers,\n });\n }, 2000).unref();\n}\n\nport.on('message', (msg: IncomingMessage) => {\n switch (msg.type) {\n case 'foreign-call':\n void (async () => {\n try {\n const value = await dispatcher.resolve_foreign_call(msg.callData);\n port.postMessage({ type: 'result', requestId: msg.requestId, ok: true, value });\n } catch (err) {\n port.postMessage({ type: 'result', requestId: msg.requestId, ok: false, error: serializeError(err) });\n }\n })();\n return;\n case 'dispose-session':\n // Fire-and-forget; the main thread does not wait for confirmation.\n void dispatcher.disposeSession(msg.sessionId).catch(err => logger.warn(`disposeSession failed`, err));\n return;\n }\n});\n"],
5
+ "mappings": ";;uHAAA,OAAS,YAAa,aAAc,qBAAwB,eAG5D,OAAS,WAAY,eAAkB,sBAalC,aAAa,cAAc,CAAE,QAAS,YAAY,KAAM,YAAa,GAAM,QAAS,CAAE,CAAC,EACvF,iBAAiB,cAAc,CAAE,QAAS,YAAY,IAAK,CAAC,EAEjE,GAAI,CAAC,WACH,MAAM,IAAI,MAAM,6CAA6C,EAG/D,IAAM,KAAO,WACP,OAAiB,aAAa,YAAY,EAM1C,eAAuC,CAC3C,uBAAwB,WAAW,uBACnC,eAAgB,WAAW,cAC7B,EACM,WAAa,IAAI,cAAc,OAAQ,cAAc,EAqB3D,SAAS,eAAe,IAA+B,CACrD,OAAI,eAAe,MACV,CAAE,QAAS,IAAI,QAAS,KAAM,IAAI,KAAM,MAAO,IAAI,KAAM,EAE3D,CAAE,QAAS,OAAO,GAAG,CAAE,CAChC,CALS,wCAUL,QAAQ,IAAI,qBAAuB,KACrC,YAAY,IAAM,CAChB,IAAM,EAAI,QAAQ,YAAY,EAC9B,KAAK,YAAY,CACf,KAAM,UACN,SAAU,mBAAmB,EAC7B,IAAK,EAAE,IACP,UAAW,EAAE,UACb,SAAU,EAAE,SACZ,SAAU,EAAE,SACZ,aAAc,EAAE,YAClB,CAAC,CACH,EAAG,GAAI,EAAE,MAAM,EAGjB,KAAK,GAAG,UAAY,KAAyB,CAC3C,OAAQ,IAAI,KAAM,CAChB,IAAK,gBACG,SAAY,CAChB,GAAI,CACF,IAAM,MAAQ,MAAM,WAAW,qBAAqB,IAAI,QAAQ,EAChE,KAAK,YAAY,CAAE,KAAM,SAAU,UAAW,IAAI,UAAW,GAAI,GAAM,KAAM,CAAC,CAChF,OAAS,IAAK,CACZ,KAAK,YAAY,CAAE,KAAM,SAAU,UAAW,IAAI,UAAW,GAAI,GAAO,MAAO,eAAe,GAAG,CAAE,CAAC,CACtG,CACF,GAAG,EACH,OACF,IAAK,kBAEE,WAAW,eAAe,IAAI,SAAS,EAAE,MAAM,KAAO,OAAO,KAAK,wBAAyB,GAAG,CAAC,EACpG,MACJ,CACF,CAAC",
6
+ "names": []
7
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2VyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvd29ya2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":""}
package/dest/worker.js ADDED
@@ -0,0 +1,92 @@
1
+ import { BackendType, Barretenberg, BarretenbergSync } from '@aztec/bb.js';
2
+ import { createLogger } from '@aztec/foundation/log';
3
+ import { parentPort, workerData } from 'node:worker_threads';
4
+ // Importing `./index.js` registers the msgpackr Fr extension transitively (via
5
+ // ./msgpackr_fr_extension.js); this must happen before any `sendMessage` call.
6
+ import { TXEDispatcher, activeSessionCount } from './index.js';
7
+ // Seed both bb.js singletons with the WASM backend before any crypto call. `initSingleton`
8
+ // binds the singleton to whichever backend the first call requests, so this pre-empts the
9
+ // implicit `Barretenberg.initSingleton()` inside `poseidon2Hash` from `@aztec/foundation/crypto`.
10
+ // TXE only needs hashing (no proving, no verification), so WASM is sufficient and
11
+ // `skipSrsInit: true` skips the CRS load. `threads: 1` keeps the WASM backend on a single
12
+ // thread — additional threads would each spawn a nested worker_thread, multiplying memory cost
13
+ // per pool worker.
14
+ void Barretenberg.initSingleton({
15
+ backend: BackendType.Wasm,
16
+ skipSrsInit: true,
17
+ threads: 1
18
+ });
19
+ void BarretenbergSync.initSingleton({
20
+ backend: BackendType.Wasm
21
+ });
22
+ if (!parentPort) {
23
+ throw new Error('worker.ts must be loaded as a worker_thread');
24
+ }
25
+ const port = parentPort;
26
+ const logger = createLogger('txe:worker');
27
+ // The pool builds a template LMDB containing the protocol contracts + the SchnorrAccount
28
+ // artifact on the main thread and passes its data dir via `workerData`. The dispatcher clones
29
+ // that LMDB into a per-worker store on first use, so this worker gets a writable copy already
30
+ // populated.
31
+ const dispatcherOpts = {
32
+ contractStoreSourceDir: workerData.contractStoreSourceDir,
33
+ schnorrClassId: workerData.schnorrClassId
34
+ };
35
+ const dispatcher = new TXEDispatcher(logger, dispatcherOpts);
36
+ function serializeError(err) {
37
+ if (err instanceof Error) {
38
+ return {
39
+ message: err.message,
40
+ name: err.name,
41
+ stack: err.stack
42
+ };
43
+ }
44
+ return {
45
+ message: String(err)
46
+ };
47
+ }
48
+ // Periodic memstat for diagnostic builds — set TXE_WORKER_MEMSTAT=1 to enable. Posts JS-heap
49
+ // breakdown + active-session count back to the dispatcher so we can attribute RSS growth
50
+ // between V8 heap (would show in heapUsed) and native (LMDB / world-state / WASM).
51
+ if (process.env.TXE_WORKER_MEMSTAT === '1') {
52
+ setInterval(()=>{
53
+ const m = process.memoryUsage();
54
+ port.postMessage({
55
+ type: 'memstat',
56
+ sessions: activeSessionCount(),
57
+ rss: m.rss,
58
+ heapTotal: m.heapTotal,
59
+ heapUsed: m.heapUsed,
60
+ external: m.external,
61
+ arrayBuffers: m.arrayBuffers
62
+ });
63
+ }, 2000).unref();
64
+ }
65
+ port.on('message', (msg)=>{
66
+ switch(msg.type){
67
+ case 'foreign-call':
68
+ void (async ()=>{
69
+ try {
70
+ const value = await dispatcher.resolve_foreign_call(msg.callData);
71
+ port.postMessage({
72
+ type: 'result',
73
+ requestId: msg.requestId,
74
+ ok: true,
75
+ value
76
+ });
77
+ } catch (err) {
78
+ port.postMessage({
79
+ type: 'result',
80
+ requestId: msg.requestId,
81
+ ok: false,
82
+ error: serializeError(err)
83
+ });
84
+ }
85
+ })();
86
+ return;
87
+ case 'dispose-session':
88
+ // Fire-and-forget; the main thread does not wait for confirmation.
89
+ void dispatcher.disposeSession(msg.sessionId).catch((err)=>logger.warn(`disposeSession failed`, err));
90
+ return;
91
+ }
92
+ });
package/package.json CHANGED
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "name": "@aztec/txe",
3
- "version": "0.0.1-commit.b2a5d0dd1",
3
+ "version": "0.0.1-commit.b3d3157a",
4
4
  "type": "module",
5
- "exports": "./dest/index.js",
5
+ "exports": {
6
+ "./server": {
7
+ "types": "./dest/rpc_server.d.ts",
8
+ "import": "./dest/server.bundle.js"
9
+ }
10
+ },
6
11
  "bin": "./dest/bin/index.js",
7
12
  "typedocOptions": {
8
13
  "entryPoints": [
@@ -12,15 +17,18 @@
12
17
  "tsconfig": "./tsconfig.json"
13
18
  },
14
19
  "scripts": {
15
- "build": "yarn clean && ../scripts/tsc.sh",
20
+ "build": "yarn clean && ../scripts/tsc.sh && node ./esbuild.config.mjs",
16
21
  "build:dev": "../scripts/tsc.sh --watch",
17
22
  "clean": "rm -rf ./dest .tsbuildinfo",
18
23
  "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}",
19
24
  "dev": "LOG_LEVEL=\"debug; trace: simulator:state_manager; info: json-rpc:proxy\" node ./dest/bin/index.js",
20
- "start": "node --no-warnings ./dest/bin/index.js"
25
+ "start": "node --no-warnings ./dest/bin/index.js",
26
+ "start:oracle-test-resolver": "node --no-warnings ./dest/bin/oracle_test_server.js",
27
+ "check_txe_oracle_version": "node ./dest/bin/check_txe_oracle_version.js"
21
28
  },
22
29
  "inherits": [
23
- "../package.common.json"
30
+ "../package.common.json",
31
+ "./package.local.json"
24
32
  ],
25
33
  "jest": {
26
34
  "moduleNameMapper": {
@@ -61,38 +69,47 @@
61
69
  ]
62
70
  },
63
71
  "dependencies": {
64
- "@aztec/accounts": "0.0.1-commit.b2a5d0dd1",
65
- "@aztec/archiver": "0.0.1-commit.b2a5d0dd1",
66
- "@aztec/aztec-node": "0.0.1-commit.b2a5d0dd1",
67
- "@aztec/aztec.js": "0.0.1-commit.b2a5d0dd1",
68
- "@aztec/bb-prover": "0.0.1-commit.b2a5d0dd1",
69
- "@aztec/constants": "0.0.1-commit.b2a5d0dd1",
70
- "@aztec/foundation": "0.0.1-commit.b2a5d0dd1",
71
- "@aztec/key-store": "0.0.1-commit.b2a5d0dd1",
72
- "@aztec/kv-store": "0.0.1-commit.b2a5d0dd1",
73
- "@aztec/protocol-contracts": "0.0.1-commit.b2a5d0dd1",
74
- "@aztec/pxe": "0.0.1-commit.b2a5d0dd1",
75
- "@aztec/simulator": "0.0.1-commit.b2a5d0dd1",
76
- "@aztec/stdlib": "0.0.1-commit.b2a5d0dd1",
77
- "@aztec/world-state": "0.0.1-commit.b2a5d0dd1",
78
- "zod": "^3.23.8"
72
+ "@aztec/accounts": "0.0.1-commit.b3d3157a",
73
+ "@aztec/archiver": "0.0.1-commit.b3d3157a",
74
+ "@aztec/aztec-node": "0.0.1-commit.b3d3157a",
75
+ "@aztec/aztec.js": "0.0.1-commit.b3d3157a",
76
+ "@aztec/bb-prover": "0.0.1-commit.b3d3157a",
77
+ "@aztec/bb.js": "0.0.1-commit.b3d3157a",
78
+ "@aztec/constants": "0.0.1-commit.b3d3157a",
79
+ "@aztec/foundation": "0.0.1-commit.b3d3157a",
80
+ "@aztec/key-store": "0.0.1-commit.b3d3157a",
81
+ "@aztec/kv-store": "0.0.1-commit.b3d3157a",
82
+ "@aztec/protocol-contracts": "0.0.1-commit.b3d3157a",
83
+ "@aztec/pxe": "0.0.1-commit.b3d3157a",
84
+ "@aztec/simulator": "0.0.1-commit.b3d3157a",
85
+ "@aztec/standard-contracts": "0.0.1-commit.b3d3157a",
86
+ "@aztec/stdlib": "0.0.1-commit.b3d3157a",
87
+ "@aztec/world-state": "0.0.1-commit.b3d3157a",
88
+ "msgpackr": "^1.11.2",
89
+ "zod": "^4"
79
90
  },
80
91
  "devDependencies": {
81
92
  "@jest/globals": "^30.0.0",
82
93
  "@types/jest": "^30.0.0",
83
94
  "@types/node": "^22.15.17",
84
95
  "@typescript/native-preview": "7.0.0-dev.20260113.1",
96
+ "esbuild": "^0.27.0",
85
97
  "jest": "^30.0.0",
86
98
  "jest-mock-extended": "^4.0.0",
87
99
  "ts-node": "^10.9.1",
88
100
  "typescript": "^5.3.3"
89
101
  },
90
102
  "files": [
103
+ "dest/bin/index.js",
104
+ "dest/worker.bundle.js",
105
+ "dest/server.bundle.js",
106
+ "dest/chunk-*.js",
107
+ "dest/*-*.js",
108
+ "dest/rpc_server.d.ts",
91
109
  "dest",
92
110
  "src",
93
111
  "!*.test.*"
94
112
  ],
95
- "types": "./dest/index.d.ts",
96
113
  "engines": {
97
114
  "node": ">=20.10"
98
115
  }
@@ -0,0 +1,70 @@
1
+ import { keccak256String } from '@aztec/foundation/crypto/keccak';
2
+ import { getOracleInterfaceSignature, readNumericGlobal } from '@aztec/pxe/bin';
3
+
4
+ import { dirname, join } from 'path';
5
+ import { fileURLToPath } from 'url';
6
+
7
+ import { TXE_ORACLE_INTERFACE_HASH, TXE_ORACLE_VERSION_MAJOR } from '../oracle/txe_oracle_version.js';
8
+
9
+ /**
10
+ * Verifies that the TXE oracle interfaces match the expected interface hash.
11
+ *
12
+ * The TXE oracle interfaces need to be versioned to ensure compatibility between Aztec.nr tests and TXE. This function
13
+ * computes a hash of the TXE oracle interfaces and compares it against a known hash. If they don't match, it means an
14
+ * interface has changed and the TXE oracle version needs to be bumped:
15
+ * - If the change is backward-breaking (e.g. removing/renaming an oracle), bump TXE_ORACLE_VERSION_MAJOR.
16
+ * - If the change is an oracle addition (non-breaking), bump TXE_ORACLE_VERSION_MINOR.
17
+ */
18
+ function assertTxeOracleInterfaceMatches(): void {
19
+ const currentDir = dirname(fileURLToPath(import.meta.url));
20
+ const packageRoot = dirname(dirname(currentDir));
21
+ const interfacesSourcePath = join(packageRoot, 'src/oracle/interfaces.ts');
22
+
23
+ const targets = ['IAvmExecutionOracle', 'ITxeExecutionOracle'];
24
+ // Not an oracle foreign call handler (see TODO(F-335) in interfaces.ts).
25
+ const excludedMembers = ['syncContractNonOracleMethod'];
26
+
27
+ const txeOracleInterfaceSignature = getOracleInterfaceSignature(interfacesSourcePath, targets, excludedMembers);
28
+
29
+ const txeOracleInterfaceHash = keccak256String(txeOracleInterfaceSignature);
30
+ if (txeOracleInterfaceHash !== TXE_ORACLE_INTERFACE_HASH) {
31
+ throw new Error(
32
+ `The TXE oracle interface has changed. Update TXE_ORACLE_INTERFACE_HASH to ${txeOracleInterfaceHash} in txe/src/oracle/txe_oracle_version.ts and bump the TXE oracle version (TXE_ORACLE_VERSION_MAJOR for breaking changes, TXE_ORACLE_VERSION_MINOR for oracle additions).`,
33
+ );
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Verifies that `TXE_ORACLE_VERSION_MAJOR` is identical across its two hand-maintained copies: the TXE TypeScript
39
+ * constant and the Aztec.nr Noir test helper constant. These layers can't import each other, so the major version is
40
+ * duplicated by hand and a mismatch otherwise only surfaces at runtime. This is the TXE counterpart of the contract
41
+ * oracle version check in `pxe/src/bin/check_oracle_version.ts`; the two version families are tracked separately.
42
+ *
43
+ * Only the major version is checked: the minor version legitimately diverges under the "environment minor >= contract
44
+ * minor" tolerance, so asserting minor equality would false-positive.
45
+ */
46
+ function assertTxeOracleVersionMajorInSync(): void {
47
+ const currentDir = dirname(fileURLToPath(import.meta.url));
48
+ // Go up from dest/bin/ or src/bin/ to the package root (txe/), then up two more to the git root.
49
+ const packageRoot = dirname(dirname(currentDir));
50
+ const gitRoot = join(packageRoot, '..', '..');
51
+
52
+ const copies = [
53
+ { label: 'txe/src/txe_oracle_version.ts', value: TXE_ORACLE_VERSION_MAJOR },
54
+ {
55
+ label: 'aztec-nr/aztec/src/test/helpers/txe_oracles.nr',
56
+ value: readNumericGlobal(
57
+ join(gitRoot, 'noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr'),
58
+ 'TXE_ORACLE_VERSION_MAJOR',
59
+ ),
60
+ },
61
+ ];
62
+
63
+ if (new Set(copies.map(copy => copy.value)).size > 1) {
64
+ const details = copies.map(copy => `${copy.label}=${copy.value}`).join(', ');
65
+ throw new Error(`TXE_ORACLE_VERSION_MAJOR is out of sync: ${details}. Bump all copies together.`);
66
+ }
67
+ }
68
+
69
+ assertTxeOracleInterfaceMatches();
70
+ assertTxeOracleVersionMajorInSync();
package/src/bin/index.ts CHANGED
@@ -2,7 +2,16 @@
2
2
  import { createLogger } from '@aztec/aztec.js/log';
3
3
  import { startHttpRpcServer } from '@aztec/foundation/json-rpc/server';
4
4
 
5
- import { createTXERpcServer } from '../index.js';
5
+ import { createTXERpcServer } from '../rpc_server.js';
6
+
7
+ // Cap the native world-state thread pool before any import touches @aztec/world-state.
8
+ // `MAX_WORLD_STATE_THREADS` reads HARDWARE_CONCURRENCY at module load and defaults to 16; the
9
+ // pool's worker threads inherit `process.env`, so setting the cap here covers every worker.
10
+ //
11
+ // CAVEAT: HARDWARE_CONCURRENCY is process-global — bb prove/verify, the LMDB reader pool, and
12
+ // the world-state native thread pool all read it. Safe at 2 today because TXE never proves or
13
+ // verifies and only performs light tree updates; raise it if that ever changes.
14
+ process.env.HARDWARE_CONCURRENCY ??= '2';
6
15
 
7
16
  /**
8
17
  * Create and start a new TXE HTTP Server
@@ -23,7 +32,7 @@ async function main() {
23
32
  const logger = createLogger('txe:rpc');
24
33
  logger.info(`Setting up TXE...`);
25
34
 
26
- const txeServer = createTXERpcServer(logger);
35
+ const txeServer = await createTXERpcServer(logger);
27
36
  const { port } = await startHttpRpcServer(txeServer, {
28
37
  host: '127.0.0.1',
29
38
  port: TXE_PORT,
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env -S node --no-warnings
2
+ import { createLogger } from '@aztec/aztec.js/log';
3
+ import { startHttpRpcServer } from '@aztec/foundation/json-rpc/server';
4
+
5
+ import { createOracleTestRpcServer } from '../oracle/test-resolver/index.js';
6
+
7
+ /**
8
+ * Starts an HTTP RPC server that resolves oracle foreign calls using hardcoded fixture scenarios.
9
+ * Used by `nargo test --oracle-resolver` to run `#[oracle_test]` roundtrip tests with a dedicated oracle resolver.
10
+ * Logs fixture coverage on shutdown.
11
+ */
12
+ async function main() {
13
+ const { ORACLE_TEST_PORT = 14830 } = process.env;
14
+
15
+ const logger = createLogger('txe:oracle-test');
16
+
17
+ logger.info('Setting up oracle test resolver...');
18
+ const { server, resolver } = createOracleTestRpcServer(logger);
19
+
20
+ function logCoverageAndExit() {
21
+ const uncalled = resolver.getUncalledFixtures();
22
+ const missing = resolver.getMissingFixtures();
23
+ if (uncalled.length > 0) {
24
+ logger.warn(`Fixtures never called by any test: ${uncalled.join(', ')}`);
25
+ }
26
+ if (missing.length > 0) {
27
+ logger.debug(`Oracles with no fixture defined: ${missing.join(', ')}`);
28
+ }
29
+ if (uncalled.length === 0) {
30
+ logger.info('All fixture oracles were called.');
31
+ }
32
+ process.exit(0);
33
+ }
34
+
35
+ process.on('SIGTERM', logCoverageAndExit);
36
+ process.on('SIGINT', logCoverageAndExit);
37
+
38
+ const { port } = await startHttpRpcServer(server, {
39
+ host: '127.0.0.1',
40
+ port: ORACLE_TEST_PORT,
41
+ timeoutMs: 1e3 * 60 * 5,
42
+ });
43
+
44
+ logger.info(`Oracle test resolver listening on port ${port}`);
45
+ }
46
+
47
+ main().catch(err => {
48
+ // eslint-disable-next-line no-console
49
+ console.error(err);
50
+ process.exit(1);
51
+ });
package/src/constants.ts CHANGED
@@ -1,3 +1,13 @@
1
+ import { PRIVATE_LOG_CIPHERTEXT_LEN } from '@aztec/constants';
1
2
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
2
3
 
3
4
  export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
5
+
6
+ // This is MAX_MESSAGE_CONTENT_LEN - PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN
7
+ export const MAX_PRIVATE_EVENT_LEN = 10;
8
+ export const MAX_PRIVATE_EVENTS_PER_TXE_QUERY = 5;
9
+
10
+ // Arbitrarily set at 64 because we need a bound. Nothing inherent about it.
11
+ export const MAX_OFFCHAIN_EFFECTS_PER_TXE_QUERY = 64;
12
+ // Must match MAX_OFFCHAIN_EFFECT_LEN in noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr.
13
+ export const MAX_OFFCHAIN_EFFECT_LEN = 2 + PRIVATE_LOG_CIPHERTEXT_LEN;