Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use multiple instances of UltraHonkBackend #11113

Closed
michaelelliot opened this issue Jan 9, 2025 · 3 comments
Closed

Unable to use multiple instances of UltraHonkBackend #11113

michaelelliot opened this issue Jan 9, 2025 · 3 comments

Comments

@michaelelliot
Copy link
Contributor

michaelelliot commented Jan 9, 2025

Issue

When using multiple instances of UltraHonkBackend, calling .destroy() on one of them (to clean it up and allow WASM memory to be freed) causes all other instances to subsequently fail to initialise, and hang forever when .instantiate() is called on them.

This is currently an issue for ZKpassport's integration tests. See this related issue.

Versions

  • @aztec/bb.js version 0.69.1
  • @noir-lang/noir_js version 1.0.0-beta.1

To reproduce

const circuit = readCircuitFromFile("simple")
const inputs = { x: 1, y: 2 }

const noir = new Noir(circuit)
const { witness } = await noir.execute(inputs)

const prover1 = new UltraHonkBackend(circuit.bytecode)
await prover1.instantiate()
await prover1.generateProof(witness)
await prover1.destroy() // <--- Commenting this out allows it to work

const prover2 = new UltraHonkBackend(circuit.bytecode)
await prover2.instantiate() // <--- This never returns

Sample code

I've created a repo reproducing the issue here. See this line for where it hangs.

@michaelelliot michaelelliot changed the title UltraHonkBackend.destroy() hangs forever Unable to use multiple instances of UltraHonkBackend Jan 9, 2025
@saleel
Copy link
Contributor

saleel commented Jan 9, 2025

Hi @michaelelliot

This looks like an issue with bun where worker.terminate() simply terminate the process.

I tried below code with nodejs and bun

async function test() {
  const circuit = readCircuitFromFile("simple")
  const inputs = { x: 1, y: 2 }

  const noir = new Noir(circuit)
  const { witness } = await noir.execute(inputs)

  const prover = new UltraHonkBackend(circuit.bytecode, { threads: 1 }, { recursive: true })
  console.log("Instantiating prover 1")
  await prover.instantiate() // <--- This never returns
  console.log("Generating proof 1")
  await prover.generateProof(witness)
  console.log("Cleaning up prover 1")
  await prover.destroy()

  const prover2 = new UltraHonkBackend(circuit.bytecode, { threads: 1 }, { recursive: true })
  console.log("Instantiating prover 2")
  await prover2.instantiate()
  console.log("Generating proof 2")
  await prover2.generateProof(witness)
  console.log("Cleaning up prover 2")
  await prover2.destroy()
  console.log("Prover 2 destroyed")
}

test().then(() => {
  console.log("Done")
}).catch((error) => {
  console.error(error)
})

With bun

bun run test.js 
Solving witness
Instantiating prover
Generating proof
Cleaning up prover

With nodejs

node test.js
Solving witness
Instantiating prover
Generating proof
Cleaning up prover
Instantiating prover 2
Generating proof 2
Cleaning up prover 2
Prover 2 destroyed
Done

Bun is not even throwing any error; simply exits when prover2 is instantiated. The problem goes away when I comment out worker_thread.destroy() in bb.js

@michaelelliot
Copy link
Contributor Author

This worked, thanks @saleel!

Disappointing that the issue was with bun, especially since we're using bun test for testing 😅 — but good to know the underlying cause!

@saleel
Copy link
Contributor

saleel commented Jan 10, 2025

Good to hear that.

I have seen another weird bun issue in regards to bb wasm, but it was gone in a newer version of bun. Hopefully this one also gets resolved in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants