Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 10 additions & 9 deletions .github/workflows/e2e_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,13 @@ jobs:
- name: Generate Proofs
run: |
export PATH="$HOME/.bb:$PATH"
bb prove -b ./target/get_header.json -w ./target/get_header.gz --write_vk -o ./target/get_header
bb prove -b ./target/get_account.json -w ./target/get_account.gz --write_vk -o ./target/get_account
bb prove -b ./target/get_storage.json -w ./target/get_storage.gz --write_vk -o ./target/get_storage
bb prove -b ./target/get_receipt.json -w ./target/get_receipt.gz --write_vk -o ./target/get_receipt
bb prove -b ./target/get_transaction.json -w ./target/get_transaction.gz --write_vk -o ./target/get_transaction
bb prove -b ./target/get_log.json -w ./target/get_log.gz --write_vk -o ./target/get_log
mkdir -p proofs
bb prove -b ./target/get_header.json -w ./target/get_header.gz --write_vk -o ./proofs/get_header.proof
bb prove -b ./target/get_account.json -w ./target/get_account.gz --write_vk -o ./proofs/get_account.proof
bb prove -b ./target/get_storage.json -w ./target/get_storage.gz --write_vk -o ./proofs/get_storage.proof
bb prove -b ./target/get_receipt.json -w ./target/get_receipt.gz --write_vk -o ./proofs/get_receipt.proof
bb prove -b ./target/get_transaction.json -w ./target/get_transaction.gz --write_vk -o ./proofs/get_transaction.proof
bb prove -b ./target/get_log.json -w ./target/get_log.gz --write_vk -o ./proofs/get_log.proof

# Note: Solidity verifiers are pre-generated and committed to ethereum/contracts/src/generated-verifier/
# Generating them in CI causes OOM errors due to high memory requirements
Expand All @@ -92,9 +93,9 @@ jobs:
working-directory: ethereum/oracles
run: yarn test:unit

# - name: Run e2e Tests
# working-directory: ethereum/tests
# run: yarn test:e2e
- name: Run e2e Tests
working-directory: ethereum/tests
run: yarn test:e2e

- name: Stop Oracle Server
if: always()
Expand Down
81 changes: 80 additions & 1 deletion ethereum/tests/src/solidityVerifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,93 @@ export interface FoundryArtefact {
abi: Abi;
bytecode: {
object: Hex;
linkReferences?: Record<string, Record<string, Array<{ start: number; length: number }>>>;
};
}

// Cache deployed libraries to avoid redeploying
const deployedLibraries = new Map<string, Address>();

async function deployLibrary(libraryName: string, libraryPath: string): Promise<Address> {
// Check if already deployed
const cacheKey = `${libraryPath}:${libraryName}`;
if (deployedLibraries.has(cacheKey)) {
return deployedLibraries.get(cacheKey)!;
}

// Import and deploy the library
const libraryArtifact = await import(`../../contracts/out/${libraryPath}/${libraryName}.json`, {
with: { type: 'json' }
});

const hash = await client.deployContract({
abi: libraryArtifact.default.abi,
account,
bytecode: libraryArtifact.default.bytecode.object as Hex,
chain: client.chain
});

const receipt = await client.waitForTransactionReceipt({ hash });
assert(receipt.status === 'success', 'Library deployment failed');
assert(!!receipt.contractAddress, 'Library address should not be empty');

deployedLibraries.set(cacheKey, receipt.contractAddress);
return receipt.contractAddress;
}

function linkLibraries(
bytecode: Hex,
linkReferences: Record<string, Record<string, Array<{ start: number; length: number }>>>,
libraryAddresses: Map<string, Address>
): Hex {
let linkedBytecode = bytecode;

for (const [filePath, libraries] of Object.entries(linkReferences)) {
for (const [libraryName, references] of Object.entries(libraries)) {
const libraryAddress = libraryAddresses.get(`${filePath}:${libraryName}`);
assert(!!libraryAddress, `Library ${libraryName} not deployed`);

const addressHex = libraryAddress.slice(2).toLowerCase();

// Replace all occurrences of the library placeholder
for (const ref of references) {
// Each reference has a start position (in bytes, so multiply by 2 for hex string)
// Add 2 to skip '0x' prefix
const startPos = ref.start * 2 + 2;
const endPos = startPos + ref.length * 2;

linkedBytecode = (linkedBytecode.slice(0, startPos) + addressHex + linkedBytecode.slice(endPos)) as Hex;
}
}
}

return linkedBytecode;
}

export async function deploySolidityProofVerifier(artefact: FoundryArtefact): Promise<SolidityProofVerifier> {
let bytecode = artefact.bytecode.object;

// Deploy and link libraries if needed
if (artefact.bytecode.linkReferences && Object.keys(artefact.bytecode.linkReferences).length > 0) {
const libraryAddresses = new Map<string, Address>();

for (const [filePath, libraries] of Object.entries(artefact.bytecode.linkReferences)) {
for (const libraryName of Object.keys(libraries)) {
const address = await deployLibrary(
libraryName,
filePath.replace('src/generated-verifier/', '')
);
libraryAddresses.set(`${filePath}:${libraryName}`, address);
}
}

bytecode = linkLibraries(bytecode, artefact.bytecode.linkReferences, libraryAddresses);
}

const hash = await client.deployContract({
abi: artefact.abi,
account,
bytecode: artefact.bytecode.object,
bytecode,
chain: client.chain
});

Expand Down
Loading