Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion avm-transpiler/src/transpile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -992,7 +992,7 @@ fn handle_storage_read(
inputs: &Vec<ValueOrArray>,
) {
// For the foreign calls we want to handle, we do not want inputs, as they are getters
assert!(inputs.len() == 1); // storage_slot
assert!(inputs.len() == 2); // output, len - but we dont use this len - its for the oracle

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a bit more detail here. In particular explain that the destination already has a length, and that is the one that will be used. (and why do we need this extra length? what does "the oracle" mean)

However... ideally we'd have an assert here that length==destination.length, if you can force the length to be known at compile time.

If you can't I guess that's life.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarified a bit in the comment (first just reverted the change), but I don't see an easy way to make the second assertion, since the destination size is known at this point, but the second argument is just a memory address. Is it possible to "unwrap" it somehow?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Length should be known at compile time btw, since the output of the opcode is an array explicitly (not a slice)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a question for @sirasistant

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only way for the transpiler to do it is to emit a const opcode with destination.length and an opcode that checks equality between that one and the second argument. But without scratch space it's a pain. (should I reserve scratch space at this point? it has come up several times)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is part of a larger discussion, I would leave as it is for the time being and try to get this in, since it's blocking TXE usage in public ATM (and this was already there, just removed recently)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm ok with it as it is. The question for Alvaro was more on the Noir/Brillig side. If there was any way to mark length as comptime/etc so that it gets to the transpiler as a resolved number.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That'd be possible but I think there is no way to have a literal in foreign call params with the current brillig spec

assert!(destinations.len() == 1); // return values

let slot_offset_maybe = inputs[0];
Expand Down
8 changes: 4 additions & 4 deletions noir-projects/Dockerfile.test
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ COPY . .
# Build & test
RUN cd ./noir-protocol-circuits && ./bootstrap.sh && nargo test --use-legacy --silence-warnings

RUN cd /usr/src/yarn-project/txe && yarn start & echo $! > /tmp/txe.pid && \
RUN cd /usr/src/yarn-project/txe && yarn start & \
# Wait for TXE to initialize
sleep 5 && \
cd ./noir-contracts && \
# We need to increase the timeout since all tests running in parallel hammer TXE at the same time, and processing slows down leading to timeouts
# The only way we currently have to batch tests is via RAYON_NUM_THREADS, which is not ideal
./bootstrap.sh && NARGO_FOREIGN_CALL_TIMEOUT=300000 nargo test --use-legacy --silence-warnings --oracle-resolver http://localhost:8080 ; \
kill $(cat /tmp/txe.pid)
./bootstrap.sh && \
NARGO_FOREIGN_CALL_TIMEOUT=300000 nargo test --use-legacy --silence-warnings --oracle-resolver http://localhost:8080

RUN cd /usr/src/yarn-project/txe && yarn start & echo $! > /tmp/txe.pid && \
RUN cd /usr/src/yarn-project/txe && yarn start & \
# Wait for TXE to initialize
sleep 5 && \
cd ./aztec-nr && \
Expand Down
11 changes: 5 additions & 6 deletions noir-projects/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,19 @@ test:
COPY +build/. /usr/src/noir-projects

RUN cd /usr/src/noir-projects/noir-protocol-circuits && nargo test --silence-warnings
RUN cd /usr/src/yarn-project/txe && yarn start & echo $! > /tmp/txe.pid && \

RUN cd /usr/src/yarn-project/txe && yarn start & \
# Wait for TXE to initialize
sleep 5 && \
cd /usr/src/noir-projects/aztec-nr && nargo test --use-legacy --silence-warnings --oracle-resolver http://localhost:8080 ; \
kill $(cat /tmp/txe.pid)
cd /usr/src/noir-projects/aztec-nr && nargo test --use-legacy --silence-warnings --oracle-resolver http://localhost:8080

RUN cd /usr/src/yarn-project/txe && yarn start & echo $! > /tmp/txe.pid && \
RUN cd /usr/src/yarn-project/txe && yarn start & \
# Wait for TXE to initialize
sleep 5 && \
cd /usr/src/noir-projects/noir-contracts && \
# We need to increase the timeout since all tests running in parallel hammer TXE at the same time and processing slows down, leading to timeouts
# The only way we currently have to batch tests is via RAYON_NUM_THREADS, which is not ideal
NARGO_FOREIGN_CALL_TIMEOUT=300000 nargo test --use-legacy --silence-warnings --oracle-resolver http://localhost:8080 ; \
kill $(cat /tmp/txe.pid)
NARGO_FOREIGN_CALL_TIMEOUT=300000 nargo test --use-legacy --silence-warnings --oracle-resolver http://localhost:8080

format:
FROM +build
Expand Down
4 changes: 2 additions & 2 deletions noir-projects/aztec-nr/aztec/src/context/public_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ unconstrained fn call_static<RET_SIZE>(
}

unconstrained fn storage_read<N>(storage_slot: Field) -> [Field; N] {
storage_read_opcode(storage_slot)
storage_read_opcode(storage_slot, N)
}

unconstrained fn storage_write<N>(storage_slot: Field, values: [Field; N]) {
Expand Down Expand Up @@ -370,7 +370,7 @@ unconstrained fn call_static_opcode<RET_SIZE>(
// ^ return data ^ success

#[oracle(avmOpcodeStorageRead)]
unconstrained fn storage_read_opcode<N>(storage_slot: Field) -> [Field; N] {}
unconstrained fn storage_read_opcode<N>(storage_slot: Field, length: Field) -> [Field; N] {}

#[oracle(avmOpcodeStorageWrite)]
unconstrained fn storage_write_opcode<N>(storage_slot: Field, values: [Field; N]) {}
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/txe/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"formatting": "run -T prettier --check ./src && run -T eslint ./src",
"formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src",
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests",
"dev": "DEBUG='aztec:*' && node ./dest/bin/index.js",
"dev": "DEBUG='aztec:*' LOG_LEVEL=debug && node ./dest/bin/index.js",
"start": "node ./dest/bin/index.js"
},
"inherits": [
Expand Down
31 changes: 29 additions & 2 deletions yarn-project/txe/src/oracle/txe_oracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,13 +434,40 @@ export class TXE implements TypedOracle {
throw new Error('Method not implemented.');
}

async avmOpcodeStorageRead(slot: Fr, length: Fr) {
const db = this.trees.asLatest();

const result = [];

for (let i = 0; i < length.toNumber(); i++) {
const leafSlot = computePublicDataTreeLeafSlot(this.contractAddress, slot).toBigInt();

const lowLeafResult = await db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
if (!lowLeafResult || !lowLeafResult.alreadyPresent) {
result.push(Fr.ZERO);
break;
}

const preimage = (await db.getLeafPreimage(
MerkleTreeId.PUBLIC_DATA_TREE,
lowLeafResult.index,
)) as PublicDataTreeLeafPreimage;

result.push(preimage.value);
}
return result;
}

async storageRead(
contractAddress: Fr,
startStorageSlot: Fr,
blockNumber: number, // TODO(#7230): use block number
blockNumber: number,
numberOfElements: number,
): Promise<Fr[]> {
const db = this.trees.asLatest();
const db =
blockNumber === (await this.getBlockNumber())
? this.trees.asLatest()
: new MerkleTreeSnapshotOperationsFacade(this.trees, blockNumber);

const values = [];
for (let i = 0n; i < numberOfElements; i++) {
Expand Down
36 changes: 34 additions & 2 deletions yarn-project/txe/src/txe_service/txe_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -506,13 +506,41 @@ export class TXEService {
fromSingle(address),
FunctionSelector.fromField(fromSingle(functionSelector)),
fromArray(args),
false,
false,
/* isStaticCall */ false,
/* isDelegateCall */ false,
);

return toForeignCallResult([toArray(result.returnValues), toSingle(new Fr(1))]);
}

async avmOpcodeStaticCall(
_gas: ForeignCallArray,
address: ForeignCallSingle,
_length: ForeignCallSingle,
args: ForeignCallArray,
functionSelector: ForeignCallSingle,
) {
const result = await (this.typedOracle as TXE).avmOpcodeCall(
fromSingle(address),
FunctionSelector.fromField(fromSingle(functionSelector)),
fromArray(args),
/* isStaticCall */ true,
/* isDelegateCall */ false,
);

return toForeignCallResult([toArray(result.returnValues), toSingle(new Fr(1))]);
}

async avmOpcodeStorageRead(slot: ForeignCallSingle, length: ForeignCallSingle) {
const values = await (this.typedOracle as TXE).avmOpcodeStorageRead(fromSingle(slot), fromSingle(length));
return toForeignCallResult([toArray(values)]);
}

async avmOpcodeStorageWrite(startStorageSlot: ForeignCallSingle, values: ForeignCallArray) {
await this.typedOracle.storageWrite(fromSingle(startStorageSlot), fromArray(values));
return toForeignCallResult([]);
}

async getPublicKeysAndPartialAddress(address: ForeignCallSingle) {
const parsedAddress = AztecAddress.fromField(fromSingle(address));
const { publicKeys, partialAddress } = await this.typedOracle.getCompleteAddress(parsedAddress);
Expand Down Expand Up @@ -571,6 +599,10 @@ export class TXEService {
return toForeignCallResult([]);
}

emitEncryptedEventLog(_contractAddress: AztecAddress, _randomness: Fr, _encryptedEvent: Buffer, _counter: number) {
return toForeignCallResult([]);
}

async callPrivateFunction(
targetContractAddress: ForeignCallSingle,
functionSelector: ForeignCallSingle,
Expand Down