@@ -123,6 +123,9 @@ describe('signTxRequest:', function () {
123123 } ,
124124 ] ,
125125 curve : 'secp256k1' ,
126+ config : {
127+ rejectCurves : new Set ( ) ,
128+ } ,
126129 } ) ;
127130 const constants = {
128131 mpc : {
@@ -238,6 +241,47 @@ describe('signTxRequest:', function () {
238241 nockPromises [ 1 ] . isDone ( ) . should . be . true ( ) ;
239242 nockPromises [ 2 ] . isDone ( ) . should . be . true ( ) ;
240243 } ) ;
244+
245+ it ( 'successfully signs a txRequest for a dkls hot wallet after receiving multiple 429 errors' , async function ( ) {
246+ const nockPromises = [
247+ await nockTxRequestResponseSignatureShareRoundOne ( bitgoParty , txRequest , bitgoGpgKey ) ,
248+ await nockTxRequestResponseSignatureShareRoundTwo ( bitgoParty , txRequest , bitgoGpgKey , 0 , 3 ) ,
249+ await nockTxRequestResponseSignatureShareRoundThree ( txRequest ) ,
250+ await nockSendTxRequest ( txRequest ) ,
251+ ] ;
252+ await Promise . all ( nockPromises ) ;
253+
254+ const userShare = fs . readFileSync ( shareFiles [ vector . party1 ] ) ;
255+ const userPrvBase64 = Buffer . from ( userShare ) . toString ( 'base64' ) ;
256+ await tssUtils . signTxRequest ( {
257+ txRequest,
258+ prv : userPrvBase64 ,
259+ reqId,
260+ } ) ;
261+ nockPromises [ 0 ] . isDone ( ) . should . be . true ( ) ;
262+ nockPromises [ 1 ] . isDone ( ) . should . be . true ( ) ;
263+ nockPromises [ 2 ] . isDone ( ) . should . be . true ( ) ;
264+ } ) ;
265+
266+ it ( 'fails to signs a txRequest for a dkls hot wallet after receiving over 3 429 errors' , async function ( ) {
267+ const nockPromises = [
268+ await nockTxRequestResponseSignatureShareRoundOne ( bitgoParty , txRequest , bitgoGpgKey ) ,
269+ await nockTxRequestResponseSignatureShareRoundTwo ( bitgoParty , txRequest , bitgoGpgKey , 0 , 4 ) ,
270+ ] ;
271+ await Promise . all ( nockPromises ) ;
272+
273+ const userShare = fs . readFileSync ( shareFiles [ vector . party1 ] ) ;
274+ const userPrvBase64 = Buffer . from ( userShare ) . toString ( 'base64' ) ;
275+ await tssUtils
276+ . signTxRequest ( {
277+ txRequest,
278+ prv : userPrvBase64 ,
279+ reqId,
280+ } )
281+ . should . be . rejectedWith ( 'Too many requests, slow down!' ) ;
282+ nockPromises [ 0 ] . isDone ( ) . should . be . true ( ) ;
283+ nockPromises [ 1 ] . isDone ( ) . should . be . false ( ) ;
284+ } ) ;
241285} ) ;
242286
243287export function getBitGoPartyGpgKeyPrv ( key : openpgp . SerializedKeyPair < string > ) : DklsTypes . PartyGpgKey {
@@ -336,11 +380,27 @@ async function nockTxRequestResponseSignatureShareRoundTwo(
336380 bitgoSession : DklsDsg . Dsg ,
337381 txRequest : TxRequest ,
338382 bitgoGpgKey : openpgp . SerializedKeyPair < string > ,
339- partyId : 0 | 1 = 0
383+ partyId : 0 | 1 = 0 ,
384+ rateLimitErrorCount = 0
340385) : Promise < nock . Scope > {
341386 const transactions = getRoute ( 'ecdsa' ) ;
342- return nock ( 'https://bitgo.fakeurl' )
343- . persist ( true )
387+ const scope = nock ( 'https://bitgo.fakeurl' ) ;
388+
389+ if ( rateLimitErrorCount > 0 ) {
390+ scope
391+ . post (
392+ `/api/v2/wallet/${ txRequest . walletId } /txrequests/${ txRequest . txRequestId + transactions } /sign` ,
393+ ( body ) => ( JSON . parse ( body . signatureShares [ 0 ] . share ) as MPCv2SignatureShareRound2Input ) . type === 'round2Input'
394+ )
395+ . times ( rateLimitErrorCount )
396+ . reply ( 429 , {
397+ error : 'Too many requests, slow down!' ,
398+ name : 'TooManyRequests' ,
399+ requestId : 'cm5qx01lh0013b2ek2sxl4w00' ,
400+ context : { } ,
401+ } ) ;
402+ }
403+ return scope
344404 . post (
345405 `/api/v2/wallet/${ txRequest . walletId } /txrequests/${ txRequest . txRequestId + transactions } /sign` ,
346406 ( body ) => ( JSON . parse ( body . signatureShares [ 0 ] . share ) as MPCv2SignatureShareRound2Input ) . type === 'round2Input'
0 commit comments