Skip to content

Commit 38c4c21

Browse files
committed
simplify
1 parent 74f2278 commit 38c4c21

File tree

2 files changed

+66
-51
lines changed

2 files changed

+66
-51
lines changed

packages/contracts/sdk/LobService.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -167,18 +167,12 @@ export class LobService {
167167
...inputPublic,
168168
});
169169
const orderId = randomness; // TODO: is randomness a good order id?
170-
const proofs = await Promise.all(
171-
inputsShared.map(({ partyIndex, inputShared }) => {
172-
return this.mpcProver.requestProveAsParty({
173-
orderId,
174-
inputShared,
175-
partyIndex,
176-
circuit: swapCircuit.circuit,
177-
numPublicInputs: 8,
178-
side,
179-
});
180-
}),
181-
);
170+
const proofs = await this.mpcProver.prove(inputsShared, {
171+
orderId,
172+
side,
173+
circuit: swapCircuit.circuit,
174+
numPublicInputs: 8,
175+
});
182176
assert(uniq(proofs).length === 1, "proofs mismatch");
183177
const proof = proofs[0]!;
184178
return {

packages/contracts/sdk/mpc/MpcNetworkService.ts

Lines changed: 60 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,40 +5,51 @@ import fs from "node:fs";
55
import path from "node:path";
66
import { z } from "zod";
77
import { promiseWithResolvers } from "../utils.js";
8-
import { inWorkingDir, makeRunCommand } from "./utils.js";
9-
10-
export type OrderId = string & { __brand: "OrderId" };
11-
export type PartyIndex = 0 | 1 | 2;
12-
/**
13-
* Deterministically determined based on the tokens being swapped
14-
*/
15-
export type Side = "seller" | "buyer";
16-
17-
type Order = {
18-
side: Side;
19-
id: OrderId;
20-
inputShared: string;
21-
result: ReturnType<typeof promiseWithResolvers<string>>;
22-
};
8+
import { inWorkingDir, makeRunCommand, splitInput } from "./utils.js";
239

2410
export class MpcProverService {
25-
// TODO: split this service into per party service to manage storage easier
26-
#storage: Record<PartyIndex, Map<OrderId, Order>> = {
27-
0: new Map(),
28-
1: new Map(),
29-
2: new Map(),
11+
readonly #parties = {
12+
0: new MpcProverPartyService(0),
13+
1: new MpcProverPartyService(1),
14+
2: new MpcProverPartyService(2),
3015
};
16+
17+
async prove(
18+
inputsShared: Awaited<ReturnType<typeof splitInput>>,
19+
params: {
20+
orderId: OrderId;
21+
side: Side;
22+
circuit: CompiledCircuit;
23+
// TODO: infer number of public inputs
24+
numPublicInputs: number;
25+
},
26+
) {
27+
return await Promise.all(
28+
inputsShared.map(async ({ partyIndex, inputShared }) => {
29+
return await this.#parties[partyIndex].requestProveAsParty({
30+
...params,
31+
inputShared,
32+
});
33+
}),
34+
);
35+
}
36+
}
37+
38+
class MpcProverPartyService {
39+
#storage: Map<OrderId, Order> = new Map();
40+
41+
constructor(readonly partyIndex: PartyIndex) {}
42+
3143
async requestProveAsParty(params: {
3244
orderId: OrderId;
3345
side: Side;
34-
partyIndex: PartyIndex;
3546
inputShared: string;
3647
circuit: CompiledCircuit;
3748
// TODO: infer number of public inputs
3849
numPublicInputs: number;
3950
}) {
4051
// TODO(security): authorization
41-
if (this.#storage[params.partyIndex].has(params.orderId)) {
52+
if (this.#storage.has(params.orderId)) {
4253
throw new Error(`order already exists ${params.orderId}`);
4354
}
4455
const order: Order = {
@@ -47,10 +58,9 @@ export class MpcProverService {
4758
side: params.side,
4859
result: promiseWithResolvers(),
4960
};
50-
this.#storage[params.partyIndex].set(params.orderId, order);
61+
this.#storage.set(params.orderId, order);
5162

5263
this.#tryExecuteOrder(params.orderId, {
53-
partyIndex: params.partyIndex,
5464
circuit: params.circuit,
5565
numPublicInputs: params.numPublicInputs,
5666
});
@@ -62,21 +72,20 @@ export class MpcProverService {
6272
orderId: OrderId,
6373

6474
params: {
65-
partyIndex: PartyIndex;
6675
circuit: CompiledCircuit;
6776
numPublicInputs: number;
6877
},
6978
) {
70-
const order = this.#storage[params.partyIndex].get(orderId);
79+
const order = this.#storage.get(orderId);
7180
if (!order) {
7281
throw new Error(
73-
`order not found in party storage ${params.partyIndex}: ${orderId}`,
82+
`order not found in party storage ${this.partyIndex}: ${orderId}`,
7483
);
7584
}
7685

77-
const otherOrders = Array.from(
78-
this.#storage[params.partyIndex].values(),
79-
).filter((o) => o.id !== order.id && o.side !== order.side);
86+
const otherOrders = Array.from(this.#storage.values()).filter(
87+
(o) => o.id !== order.id && o.side !== order.side,
88+
);
8089
if (otherOrders.length === 0) {
8190
return;
8291
}
@@ -87,13 +96,12 @@ export class MpcProverService {
8796
: ([otherOrder.inputShared, order.inputShared] as const);
8897
console.log(
8998
"executing orders",
90-
params.partyIndex,
99+
this.partyIndex,
91100
omit(order, ["inputShared", "result"]),
92101
omit(otherOrder, ["inputShared", "result"]),
93102
);
94103
try {
95-
const { proof } = await this.proveAsParty({
96-
partyIndex: params.partyIndex,
104+
const { proof } = await this.#prove({
97105
circuit: params.circuit,
98106
input0Shared: inputsShared[0],
99107
input1Shared: inputsShared[1],
@@ -108,15 +116,14 @@ export class MpcProverService {
108116
}
109117
}
110118

111-
async proveAsParty(params: {
112-
partyIndex: number;
119+
async #prove(params: {
113120
circuit: CompiledCircuit;
114121
input0Shared: string;
115122
input1Shared: string;
116123
// TODO: infer number of public inputs
117124
numPublicInputs: number;
118125
}) {
119-
console.log("proving as party", params.partyIndex);
126+
console.log("proving as party", this.partyIndex);
120127
return await inWorkingDir(async (workingDir) => {
121128
for (const [traderIndex, inputShared] of [
122129
params.input0Shared,
@@ -125,7 +132,7 @@ export class MpcProverService {
125132
fs.writeFileSync(
126133
path.join(
127134
workingDir,
128-
`Prover${traderIndex}.toml.${params.partyIndex}.shared`,
135+
`Prover${traderIndex}.toml.${this.partyIndex}.shared`,
129136
),
130137
ethers.getBytes(inputShared),
131138
);
@@ -136,7 +143,7 @@ export class MpcProverService {
136143

137144
const runCommand = makeRunCommand(__dirname);
138145
await runCommand(
139-
`./run-party.sh ${workingDir} ${circuitPath} ${params.partyIndex}`,
146+
`./run-party.sh ${workingDir} ${circuitPath} ${this.partyIndex}`,
140147
);
141148

142149
const publicInputs = z
@@ -152,7 +159,7 @@ export class MpcProverService {
152159
);
153160
const proofData = Uint8Array.from(
154161
fs.readFileSync(
155-
path.join(workingDir, `proof.${params.partyIndex}.proof`),
162+
path.join(workingDir, `proof.${this.partyIndex}.proof`),
156163
),
157164
);
158165
// arcane magic
@@ -168,3 +175,17 @@ export class MpcProverService {
168175
});
169176
}
170177
}
178+
179+
export type OrderId = string & { __brand: "OrderId" };
180+
export type PartyIndex = 0 | 1 | 2;
181+
/**
182+
* Deterministically determined based on the tokens being swapped
183+
*/
184+
export type Side = "seller" | "buyer";
185+
186+
type Order = {
187+
side: Side;
188+
id: OrderId;
189+
inputShared: string;
190+
result: ReturnType<typeof promiseWithResolvers<string>>;
191+
};

0 commit comments

Comments
 (0)