@@ -5,6 +5,7 @@ import { omit } from "lodash";
55import fs from "node:fs" ;
66import os from "node:os" ;
77import path from "node:path" ;
8+ import PQueue , { type QueueAddOptions } from "p-queue" ;
89import { decodeNativeHonkProof , promiseWithResolvers } from "../utils.js" ;
910import { inWorkingDir , makeRunCommand , splitInput } from "./utils.js" ;
1011
@@ -36,6 +37,7 @@ export class MpcProverService {
3637
3738class MpcProverPartyService {
3839 #storage: Map < OrderId , Order > = new Map ( ) ;
40+ #queue = new PQueue ( { concurrency : 1 } ) ;
3941
4042 constructor ( readonly partyIndex : PartyIndex ) { }
4143
@@ -57,59 +59,62 @@ class MpcProverPartyService {
5759 } ;
5860 this . #storage. set ( params . orderId , order ) ;
5961
60- this . #tryExecuteOrder( params . orderId , {
61- circuit : params . circuit ,
62- } ) ;
62+ // add this order to other order's queue
63+ // TODO(perf): this is O(N^2) but we should do better
64+ for ( const otherOrder of this . #storage. values ( ) ) {
65+ this . #addOrdersToQueue( {
66+ orderA : order ,
67+ orderB : otherOrder ,
68+ circuit : params . circuit ,
69+ } ) ;
70+ }
6371
6472 return await order . result . promise ;
6573 }
6674
67- async #tryExecuteOrder(
68- orderId : OrderId ,
69- params : {
70- circuit : CompiledCircuit ;
71- } ,
72- ) {
73- const order = this . #storage. get ( orderId ) ;
74- if ( ! order ) {
75- throw new Error (
76- `order not found in party storage ${ this . partyIndex } : ${ orderId } ` ,
77- ) ;
78- }
79-
80- const otherOrders = Array . from ( this . #storage. values ( ) ) . filter (
81- ( o ) => o . id !== order . id && o . side !== order . side ,
82- ) ;
83- if ( otherOrders . length === 0 ) {
75+ #addOrdersToQueue( params : {
76+ orderA : Order ;
77+ orderB : Order ;
78+ circuit : CompiledCircuit ;
79+ } ) {
80+ if ( params . orderA . id === params . orderB . id ) {
81+ // can't match with itself
8482 return ;
8583 }
86- const otherOrder = otherOrders [ 0 ] ! ;
87- const inputsShared =
88- order . side === "seller"
89- ? ( [ order . inputShared , otherOrder . inputShared ] as const )
90- : ( [ otherOrder . inputShared , order . inputShared ] as const ) ;
91- console . log (
92- "executing orders" ,
93- this . partyIndex ,
94- omit ( order , [ "inputShared" , "result" ] ) ,
95- omit ( otherOrder , [ "inputShared" , "result" ] ) ,
96- ) ;
97- try {
98- const { proof } = await proveAsParty ( {
99- circuit : params . circuit ,
100- partyIndex : this . partyIndex ,
101- input0Shared : inputsShared [ 0 ] ,
102- input1Shared : inputsShared [ 1 ] ,
103- } ) ;
104- const proofHex = ethers . hexlify ( proof ) ;
105- order . result . resolve ( proofHex ) ;
106- otherOrder . result . resolve ( proofHex ) ;
107- this . #storage. delete ( order . id ) ;
108- this . #storage. delete ( otherOrder . id ) ;
109- } catch ( error ) {
110- order . result . reject ( error ) ;
111- otherOrder . result . reject ( error ) ;
84+ if ( params . orderA . side === params . orderB . side ) {
85+ // pre-check that orders are on opposite sides
86+ return ;
11287 }
88+
89+ const options : QueueAddOptions = { throwOnTimeout : true } ;
90+ this . #queue. add ( async ( ) => {
91+ const [ order , otherOrder ] =
92+ params . orderA . side === "seller"
93+ ? [ params . orderA , params . orderB ]
94+ : [ params . orderB , params . orderA ] ;
95+ console . log (
96+ "executing orders" ,
97+ this . partyIndex ,
98+ omit ( order , [ "inputShared" , "result" ] ) ,
99+ omit ( otherOrder , [ "inputShared" , "result" ] ) ,
100+ ) ;
101+ try {
102+ const { proof } = await proveAsParty ( {
103+ circuit : params . circuit ,
104+ partyIndex : this . partyIndex ,
105+ input0Shared : order . inputShared ,
106+ input1Shared : otherOrder . inputShared ,
107+ } ) ;
108+ const proofHex = ethers . hexlify ( proof ) ;
109+ order . result . resolve ( proofHex ) ;
110+ otherOrder . result . resolve ( proofHex ) ;
111+ this . #storage. delete ( order . id ) ;
112+ this . #storage. delete ( otherOrder . id ) ;
113+ } catch ( error ) {
114+ order . result . reject ( error ) ;
115+ otherOrder . result . reject ( error ) ;
116+ }
117+ } , options ) ;
113118 }
114119}
115120
0 commit comments