diff --git a/ethereum/oracles/src/noir/oracles/recursive/getStorageOracle.ts b/ethereum/oracles/src/noir/oracles/recursive/getStorageOracle.ts new file mode 100644 index 00000000..e78abd6f --- /dev/null +++ b/ethereum/oracles/src/noir/oracles/recursive/getStorageOracle.ts @@ -0,0 +1,19 @@ +import { ForeignCallOutput } from '@noir-lang/noir_js'; +import { NoirArguments } from '../types.js'; +import { decodeGetProofArguments } from '../rpc/proofOracle.js'; +import { GetStorageProver } from '../../circuit/provers/getStorage.js'; +import { MonorepoCircuit } from '../../circuit/circuit.js'; +import { VerificationKey } from '../../circuit/vk.js'; + +export const getStorageOracle = async (args: NoirArguments): Promise => { + const { blockNumber, address, storageKey, chainId } = decodeGetProofArguments(args); + const circuit = await MonorepoCircuit.create('../../', 'get_storage'); + const vk = await VerificationKey.create(circuit.vkAsFieldsPath()); + const { proofAsFields, verifierData } = await new GetStorageProver(circuit).prove( + chainId, + blockNumber, + address, + storageKey + ); + return [verifierData.returnValues(), vk.hash, vk.asFields, proofAsFields]; +}; diff --git a/ethereum/oracles/src/noir/oracles/server/app.ts b/ethereum/oracles/src/noir/oracles/server/app.ts index 09f20cf4..23273cc4 100644 --- a/ethereum/oracles/src/noir/oracles/server/app.ts +++ b/ethereum/oracles/src/noir/oracles/server/app.ts @@ -1,22 +1,24 @@ import { JSONRPCRequest, JSONRPCServer, TypedJSONRPCServer } from 'json-rpc-2.0'; import Fastify from 'fastify'; import http from 'http'; -import { JSONRPCServerMethods, ServerParams, getOracleHandler } from './handlers.js'; +import { JSONRPCServerMethods, ServerParams, getOracleHandler, getRpcOracleHandler } from './handlers.js'; import { MultiChainClient } from '../../../ethereum/client.js'; import { getHeaderOracle } from '../rpc/headerOracle.js'; import { getAccountOracle } from '../rpc/accountOracle.js'; import { getProofOracle } from '../rpc/proofOracle.js'; import { getReceiptOracle } from '../rpc/receiptOracle.js'; import { getTransactionOracle } from '../rpc/transactionOracle.js'; +import { getStorageOracle } from '../recursive/getStorageOracle.js'; const HTTP_STATUS_NO_CONTENT = 204; const jsonRPCServer: TypedJSONRPCServer = new JSONRPCServer(); -jsonRPCServer.addMethod('get_header', getOracleHandler.bind(this, getHeaderOracle)); -jsonRPCServer.addMethod('get_account', getOracleHandler.bind(this, getAccountOracle)); -jsonRPCServer.addMethod('get_proof', getOracleHandler.bind(this, getProofOracle)); -jsonRPCServer.addMethod('get_receipt', getOracleHandler.bind(this, getReceiptOracle)); -jsonRPCServer.addMethod('get_transaction', getOracleHandler.bind(this, getTransactionOracle)); +jsonRPCServer.addMethod('get_header', getRpcOracleHandler.bind(this, getHeaderOracle)); +jsonRPCServer.addMethod('get_account', getRpcOracleHandler.bind(this, getAccountOracle)); +jsonRPCServer.addMethod('get_proof', getRpcOracleHandler.bind(this, getProofOracle)); +jsonRPCServer.addMethod('get_receipt', getRpcOracleHandler.bind(this, getReceiptOracle)); +jsonRPCServer.addMethod('get_transaction', getRpcOracleHandler.bind(this, getTransactionOracle)); +jsonRPCServer.addMethod('recursive_get_storage', getOracleHandler.bind(this, getStorageOracle)); export function buildOracleServer( opts: Fastify.FastifyHttpOptions = {}, diff --git a/ethereum/oracles/src/noir/oracles/server/handlers.ts b/ethereum/oracles/src/noir/oracles/server/handlers.ts index 68ba4879..923ec179 100644 --- a/ethereum/oracles/src/noir/oracles/server/handlers.ts +++ b/ethereum/oracles/src/noir/oracles/server/handlers.ts @@ -1,7 +1,7 @@ import { ForeignCallResult, ForeignCallParams } from './types.js'; import { decodeNoirArguments, encodeForeignCallResult } from './encode.js'; import { MultiChainClient } from '../../../ethereum/client.js'; -import { Oracle } from '../types.js'; +import { Oracle, RpcOracle } from '../types.js'; /** * The format that the Noir oracles server receives the arguments in is slightly different than the format that acvm.js uses. @@ -17,19 +17,25 @@ export type JSONRPCServerMethods = { get_proof(params: ForeignCallParams): ForeignCallResult; get_receipt(params: ForeignCallParams): ForeignCallResult; get_transaction(params: ForeignCallParams): ForeignCallResult; + recursive_get_storage(params: ForeignCallParams): ForeignCallResult; }; export interface ServerParams { client: MultiChainClient; } -export async function getOracleHandler( - oracle: Oracle, +export async function getRpcOracleHandler( + rpcOracle: RpcOracle, params: ForeignCallParams, { client }: ServerParams ): Promise { + const oracle = rpcOracle.bind(null, client); + return getOracleHandler(oracle, params); +} + +export async function getOracleHandler(oracle: Oracle, params: ForeignCallParams): Promise { const noirArguments = decodeNoirArguments(params); - const noirOutputs = await oracle(client, noirArguments); + const noirOutputs = await oracle(noirArguments); const result = encodeForeignCallResult(noirOutputs); return result; } diff --git a/ethereum/oracles/src/noir/oracles/types.ts b/ethereum/oracles/src/noir/oracles/types.ts index 857388c9..d22c57b2 100644 --- a/ethereum/oracles/src/noir/oracles/types.ts +++ b/ethereum/oracles/src/noir/oracles/types.ts @@ -4,4 +4,5 @@ import { MultiChainClient } from '../../ethereum/client.js'; export type NoirArgument = string[]; export type NoirArguments = NoirArgument[]; -export type Oracle = (multiChainClient: MultiChainClient, args: NoirArguments) => Promise; +export type Oracle = (args: NoirArguments) => Promise; +export type RpcOracle = (multiChainClient: MultiChainClient, args: NoirArguments) => Promise;