@aztec/txe 0.0.0-test.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.
- package/dest/bin/index.d.ts +3 -0
- package/dest/bin/index.d.ts.map +1 -0
- package/dest/bin/index.js +30 -0
- package/dest/index.d.ts +8 -0
- package/dest/index.d.ts.map +1 -0
- package/dest/index.js +156 -0
- package/dest/node/txe_node.d.ts +358 -0
- package/dest/node/txe_node.d.ts.map +1 -0
- package/dest/node/txe_node.js +504 -0
- package/dest/oracle/txe_oracle.d.ts +152 -0
- package/dest/oracle/txe_oracle.d.ts.map +1 -0
- package/dest/oracle/txe_oracle.js +833 -0
- package/dest/txe_service/txe_service.d.ts +212 -0
- package/dest/txe_service/txe_service.d.ts.map +1 -0
- package/dest/txe_service/txe_service.js +572 -0
- package/dest/util/encoding.d.ts +103 -0
- package/dest/util/encoding.d.ts.map +1 -0
- package/dest/util/encoding.js +76 -0
- package/dest/util/expected_failure_error.d.ts +4 -0
- package/dest/util/expected_failure_error.d.ts.map +1 -0
- package/dest/util/expected_failure_error.js +5 -0
- package/dest/util/txe_account_data_provider.d.ts +10 -0
- package/dest/util/txe_account_data_provider.d.ts.map +1 -0
- package/dest/util/txe_account_data_provider.js +17 -0
- package/dest/util/txe_public_contract_data_source.d.ts +20 -0
- package/dest/util/txe_public_contract_data_source.d.ts.map +1 -0
- package/dest/util/txe_public_contract_data_source.js +88 -0
- package/dest/util/txe_world_state_db.d.ts +14 -0
- package/dest/util/txe_world_state_db.d.ts.map +1 -0
- package/dest/util/txe_world_state_db.js +27 -0
- package/package.json +93 -0
- package/src/bin/index.ts +39 -0
- package/src/index.ts +213 -0
- package/src/node/txe_node.ts +725 -0
- package/src/oracle/txe_oracle.ts +1241 -0
- package/src/txe_service/txe_service.ts +749 -0
- package/src/util/encoding.ts +92 -0
- package/src/util/expected_failure_error.ts +5 -0
- package/src/util/txe_account_data_provider.ts +23 -0
- package/src/util/txe_public_contract_data_source.ts +101 -0
- package/src/util/txe_world_state_db.ts +38 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import { hexToBuffer } from '@aztec/foundation/string';
|
|
3
|
+
import { type ContractArtifact, ContractArtifactSchema } from '@aztec/stdlib/abi';
|
|
4
|
+
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
|
+
import { type ContractInstanceWithAddress, ContractInstanceWithAddressSchema } from '@aztec/stdlib/contract';
|
|
6
|
+
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
|
|
9
|
+
export type ForeignCallSingle = string;
|
|
10
|
+
|
|
11
|
+
export type ForeignCallArray = string[];
|
|
12
|
+
|
|
13
|
+
export type ForeignCallArgs = (ForeignCallSingle | ForeignCallArray | ContractArtifact | ContractInstanceWithAddress)[];
|
|
14
|
+
|
|
15
|
+
export type ForeignCallResult = {
|
|
16
|
+
values: (ForeignCallSingle | ForeignCallArray)[];
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function fromSingle(obj: ForeignCallSingle) {
|
|
20
|
+
return Fr.fromBuffer(Buffer.from(obj, 'hex'));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function addressFromSingle(obj: ForeignCallSingle) {
|
|
24
|
+
return new AztecAddress(fromSingle(obj));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function fromArray(obj: ForeignCallArray) {
|
|
28
|
+
return obj.map(str => Fr.fromBuffer(hexToBuffer(str)));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Converts an array of Noir unsigned integers to a single tightly-packed buffer.
|
|
33
|
+
* @param uintBitSize If it's an array of Noir u8's, put `8`, etc.
|
|
34
|
+
* @returns
|
|
35
|
+
*/
|
|
36
|
+
export function fromUintArray(obj: ForeignCallArray, uintBitSize: number): Buffer {
|
|
37
|
+
if (uintBitSize % 8 !== 0) {
|
|
38
|
+
throw new Error(`u${uintBitSize} is not a supported type in Noir`);
|
|
39
|
+
}
|
|
40
|
+
const uintByteSize = uintBitSize / 8;
|
|
41
|
+
return Buffer.concat(obj.map(str => hexToBuffer(str).slice(-uintByteSize)));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function toSingle(obj: Fr | AztecAddress): ForeignCallSingle {
|
|
45
|
+
return obj.toString().slice(2);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function toArray(objs: Fr[]): ForeignCallArray {
|
|
49
|
+
return objs.map(obj => obj.toString());
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function bufferToU8Array(buffer: Buffer): ForeignCallArray {
|
|
53
|
+
return toArray(Array.from(buffer).map(byte => new Fr(byte)));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Converts a ForeignCallArray into a tuple which represents a nr BoundedVec.
|
|
58
|
+
* If the input array is shorter than the maxLen, it pads the result with zeros,
|
|
59
|
+
* so that nr can correctly coerce this result into a BoundedVec.
|
|
60
|
+
* @param array
|
|
61
|
+
* @param maxLen - the max length of the BoundedVec.
|
|
62
|
+
* @returns a tuple representing a BoundedVec.
|
|
63
|
+
*/
|
|
64
|
+
export function arrayToBoundedVec(array: ForeignCallArray, maxLen: number): [ForeignCallArray, ForeignCallSingle] {
|
|
65
|
+
if (array.length > maxLen) {
|
|
66
|
+
throw new Error(`Array of length ${array.length} larger than maxLen ${maxLen}`);
|
|
67
|
+
}
|
|
68
|
+
const lengthDiff = maxLen - array.length;
|
|
69
|
+
// We pad the array to the maxLen of the BoundedVec.
|
|
70
|
+
const zeroPaddingArray = toArray(Array(lengthDiff).fill(new Fr(0)));
|
|
71
|
+
|
|
72
|
+
// These variable names match with the BoundedVec members in nr:
|
|
73
|
+
const storage = array.concat(zeroPaddingArray);
|
|
74
|
+
const len = toSingle(new Fr(array.length));
|
|
75
|
+
return [storage, len];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function toForeignCallResult(obj: (ForeignCallSingle | ForeignCallArray)[]) {
|
|
79
|
+
return { values: obj };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export const ForeignCallSingleSchema = z.string();
|
|
83
|
+
|
|
84
|
+
export const ForeignCallArraySchema = z.array(z.string());
|
|
85
|
+
|
|
86
|
+
export const ForeignCallArgsSchema = z.array(
|
|
87
|
+
z.union([ForeignCallSingleSchema, ForeignCallArraySchema, ContractArtifactSchema, ContractInstanceWithAddressSchema]),
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
export const ForeignCallResultSchema = z.object({
|
|
91
|
+
values: z.array(z.union([ForeignCallSingleSchema, ForeignCallArraySchema])),
|
|
92
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
2
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
3
|
+
import { CompleteAddress } from '@aztec/stdlib/contract';
|
|
4
|
+
|
|
5
|
+
export class TXEAccountDataProvider {
|
|
6
|
+
#accounts: AztecAsyncMap<string, Buffer>;
|
|
7
|
+
|
|
8
|
+
constructor(store: AztecAsyncKVStore) {
|
|
9
|
+
this.#accounts = store.openMap('accounts');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async getAccount(key: AztecAddress) {
|
|
13
|
+
const completeAddress = await this.#accounts.getAsync(key.toString());
|
|
14
|
+
if (!completeAddress) {
|
|
15
|
+
throw new Error(`Account not found: ${key.toString()}`);
|
|
16
|
+
}
|
|
17
|
+
return CompleteAddress.fromBuffer(completeAddress);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async setAccount(key: AztecAddress, value: CompleteAddress) {
|
|
21
|
+
await this.#accounts.set(key.toString(), value.toBuffer());
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { PUBLIC_DISPATCH_SELECTOR } from '@aztec/constants';
|
|
2
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
3
|
+
import { PrivateFunctionsTree } from '@aztec/pxe/server';
|
|
4
|
+
import { type ContractArtifact, FunctionSelector } from '@aztec/stdlib/abi';
|
|
5
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
6
|
+
import {
|
|
7
|
+
type ContractClassPublic,
|
|
8
|
+
type ContractDataSource,
|
|
9
|
+
type ContractInstanceWithAddress,
|
|
10
|
+
type PublicFunction,
|
|
11
|
+
computePublicBytecodeCommitment,
|
|
12
|
+
} from '@aztec/stdlib/contract';
|
|
13
|
+
|
|
14
|
+
import type { TXE } from '../oracle/txe_oracle.js';
|
|
15
|
+
|
|
16
|
+
export class TXEPublicContractDataSource implements ContractDataSource {
|
|
17
|
+
constructor(private txeOracle: TXE) {}
|
|
18
|
+
|
|
19
|
+
async getPublicFunction(address: AztecAddress, selector: FunctionSelector): Promise<PublicFunction | undefined> {
|
|
20
|
+
const bytecode = await this.txeOracle.getContractDataProvider().getBytecode(address, selector);
|
|
21
|
+
if (!bytecode) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
return { bytecode, selector };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
getBlockNumber(): Promise<number> {
|
|
28
|
+
return this.txeOracle.getBlockNumber();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
|
|
32
|
+
const contractClass = await this.txeOracle.getContractDataProvider().getContractClass(id);
|
|
33
|
+
const artifact = await this.txeOracle.getContractDataProvider().getContractArtifact(id);
|
|
34
|
+
const tree = await PrivateFunctionsTree.create(artifact);
|
|
35
|
+
const privateFunctionsRoot = await tree.getFunctionTreeRoot();
|
|
36
|
+
|
|
37
|
+
const publicFunctions: PublicFunction[] = [];
|
|
38
|
+
if (contractClass!.packedBytecode.length > 0) {
|
|
39
|
+
publicFunctions.push({
|
|
40
|
+
selector: FunctionSelector.fromField(new Fr(PUBLIC_DISPATCH_SELECTOR)),
|
|
41
|
+
bytecode: contractClass!.packedBytecode,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
id,
|
|
47
|
+
artifactHash: contractClass!.artifactHash,
|
|
48
|
+
packedBytecode: contractClass!.packedBytecode,
|
|
49
|
+
publicFunctions: publicFunctions,
|
|
50
|
+
privateFunctionsRoot: new Fr(privateFunctionsRoot!.root),
|
|
51
|
+
version: contractClass!.version,
|
|
52
|
+
privateFunctions: [],
|
|
53
|
+
unconstrainedFunctions: [],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async getBytecodeCommitment(id: Fr): Promise<Fr | undefined> {
|
|
58
|
+
const contractClass = await this.txeOracle.getContractDataProvider().getContractClass(id);
|
|
59
|
+
return computePublicBytecodeCommitment(contractClass.packedBytecode);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async getContract(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
|
|
63
|
+
const instance = await this.txeOracle.getContractDataProvider().getContractInstance(address);
|
|
64
|
+
return { ...instance, address };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
getContractClassIds(): Promise<Fr[]> {
|
|
68
|
+
throw new Error('Method not implemented.');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined> {
|
|
72
|
+
const instance = await this.txeOracle.getContractDataProvider().getContractInstance(address);
|
|
73
|
+
return this.txeOracle.getContractDataProvider().getContractArtifact(instance.currentContractClassId);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async getContractFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
|
|
77
|
+
const artifact = await this.getContractArtifact(address);
|
|
78
|
+
if (!artifact) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
const functionSelectorsAndNames = await Promise.all(
|
|
82
|
+
artifact.functions.map(async f => ({
|
|
83
|
+
name: f.name,
|
|
84
|
+
selector: await FunctionSelector.fromNameAndParameters({ name: f.name, parameters: f.parameters }),
|
|
85
|
+
})),
|
|
86
|
+
);
|
|
87
|
+
const func = functionSelectorsAndNames.find(f => f.selector.equals(selector));
|
|
88
|
+
|
|
89
|
+
return Promise.resolve(func?.name);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
registerContractFunctionSignatures(_address: AztecAddress, _signatures: []): Promise<void> {
|
|
93
|
+
return Promise.resolve();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// TODO(#10007): Remove this method.
|
|
97
|
+
addContractClass(_contractClass: ContractClassPublic): Promise<void> {
|
|
98
|
+
// We don't really need to do anything for the txe here
|
|
99
|
+
return Promise.resolve();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import { WorldStateDB } from '@aztec/simulator/server';
|
|
3
|
+
import { PublicDataWrite } from '@aztec/stdlib/avm';
|
|
4
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
|
+
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
6
|
+
import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
|
|
7
|
+
import type { MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
|
|
8
|
+
import { MerkleTreeId, type PublicDataTreeLeafPreimage } from '@aztec/stdlib/trees';
|
|
9
|
+
|
|
10
|
+
import type { TXE } from '../oracle/txe_oracle.js';
|
|
11
|
+
|
|
12
|
+
export class TXEWorldStateDB extends WorldStateDB {
|
|
13
|
+
constructor(private merkleDb: MerkleTreeWriteOperations, dataSource: ContractDataSource, private txe: TXE) {
|
|
14
|
+
super(merkleDb, dataSource);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
override async storageRead(contract: AztecAddress, slot: Fr): Promise<Fr> {
|
|
18
|
+
const leafSlot = (await computePublicDataTreeLeafSlot(contract, slot)).toBigInt();
|
|
19
|
+
|
|
20
|
+
const lowLeafResult = await this.merkleDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
|
|
21
|
+
|
|
22
|
+
let value = Fr.ZERO;
|
|
23
|
+
if (lowLeafResult && lowLeafResult.alreadyPresent) {
|
|
24
|
+
const preimage = (await this.merkleDb.getLeafPreimage(
|
|
25
|
+
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
26
|
+
lowLeafResult.index,
|
|
27
|
+
)) as PublicDataTreeLeafPreimage;
|
|
28
|
+
value = preimage.value;
|
|
29
|
+
}
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
override async storageWrite(contract: AztecAddress, slot: Fr, newValue: Fr): Promise<void> {
|
|
34
|
+
await this.txe.addPublicDataWrites([
|
|
35
|
+
new PublicDataWrite(await computePublicDataTreeLeafSlot(contract, slot), newValue),
|
|
36
|
+
]);
|
|
37
|
+
}
|
|
38
|
+
}
|