@@ -92,6 +92,10 @@ const execute = (description, newFederationConfig) => {
9292 const notAuthorized3PrivateKey = '8a7d07ad23a412558259e3857214d7b521589d0b37509839d7591e6f4026b4df' ;
9393
9494 const EXPECTED_UNSUCCESSFUL_RESULT = '-10' ;
95+ const PENDING_FEDERATION_ALREADY_EXISTS_ERROR_CODE = '-1' ;
96+ const PROPOSED_FEDERATION_ALREADY_EXISTS_ERROR_CODE = '-4' ;
97+ const EXISTING_FEDERATION_AWAITING_ACTIVATION_ERROR_CODE = '-2' ;
98+ const RETIRING_FEDERATION_ALREADY_EXISTS = '-3' ;
9599
96100 let fedChangeAuthorizer1Address ;
97101 let fedChangeAuthorizer2Address ;
@@ -232,6 +236,29 @@ const execute = (description, newFederationConfig) => {
232236 await addFederatorsPublicKeys ( ) ;
233237 } ) ;
234238
239+ it ( 'should not create a new pending federation when there is one already created' , async ( ) => {
240+
241+ const initialPendingFederationHash = await bridge . methods . getPendingFederationHash ( ) . call ( ) ;
242+
243+ const createFederationMethod = await bridge . methods . createFederation ( ) ;
244+
245+ const message = 'The `createFederation` method should not be callable when there is a pending federation.' ;
246+
247+ await rskUtils . sendTxWithCheck ( rskTxHelper , createFederationMethod , fedChangeAuthorizer1Address , result => {
248+ expect ( result ) . to . be . equal ( PENDING_FEDERATION_ALREADY_EXISTS_ERROR_CODE , message ) ;
249+ } ) ;
250+ await rskUtils . sendTxWithCheck ( rskTxHelper , createFederationMethod , fedChangeAuthorizer2Address , result => {
251+ expect ( result ) . to . be . equal ( PENDING_FEDERATION_ALREADY_EXISTS_ERROR_CODE , message ) ;
252+ } ) ;
253+ await rskUtils . sendTxWithCheck ( rskTxHelper , createFederationMethod , fedChangeAuthorizer3Address , result => {
254+ expect ( result ) . to . be . equal ( PENDING_FEDERATION_ALREADY_EXISTS_ERROR_CODE , message ) ;
255+ } ) ;
256+
257+ const finalPendingFederationHash = await bridge . methods . getPendingFederationHash ( ) . call ( ) ;
258+ expect ( initialPendingFederationHash ) . to . be . equal ( finalPendingFederationHash , 'The pending federation hash should not change when calling `createFederation` if there is a pending federation already.' ) ;
259+
260+ } ) ;
261+
235262 it ( 'should not be able to call `addFederatorPublicKeyMultikey` without authorization' , async ( ) => {
236263
237264 const initialPendingFederationHash = await bridge . methods . getPendingFederationHash ( ) . call ( ) ;
@@ -384,6 +411,30 @@ const execute = (description, newFederationConfig) => {
384411 expect ( proposedFederationPublicKeys ) . to . be . deep . equal ( newFederationPublicKeys , 'The proposed federation public keys should be the expected ones.' ) ;
385412
386413 } ) ;
414+
415+ it ( 'should not create a new pending federation when there is a proposed federation' , async ( ) => {
416+
417+ const initialPendingFederationHash = await bridge . methods . getPendingFederationHash ( ) . call ( ) ;
418+ expect ( initialPendingFederationHash , 'The pending federation hash should be null.' ) . to . be . null ;
419+
420+ const createFederationMethod = await bridge . methods . createFederation ( ) ;
421+
422+ const message = 'The `createFederation` method should not be callable when there is a proposed federation.' ;
423+
424+ await rskUtils . sendTxWithCheck ( rskTxHelper , createFederationMethod , fedChangeAuthorizer1Address , result => {
425+ expect ( result ) . to . be . equal ( PROPOSED_FEDERATION_ALREADY_EXISTS_ERROR_CODE , message ) ;
426+ } ) ;
427+ await rskUtils . sendTxWithCheck ( rskTxHelper , createFederationMethod , fedChangeAuthorizer2Address , result => {
428+ expect ( result ) . to . be . equal ( PROPOSED_FEDERATION_ALREADY_EXISTS_ERROR_CODE , message ) ;
429+ } ) ;
430+ await rskUtils . sendTxWithCheck ( rskTxHelper , createFederationMethod , fedChangeAuthorizer3Address , result => {
431+ expect ( result ) . to . be . equal ( PROPOSED_FEDERATION_ALREADY_EXISTS_ERROR_CODE , message ) ;
432+ } ) ;
433+
434+ const finalPendingFederationHash = await bridge . methods . getPendingFederationHash ( ) . call ( ) ;
435+ expect ( finalPendingFederationHash , 'The pending federation hash should be null.' ) . to . be . null ;
436+
437+ } ) ;
387438
388439 it ( 'should not have created svp fund transaction and there should not be any SVP values in storage yet' , async function ( ) {
389440
@@ -416,7 +467,7 @@ const execute = (description, newFederationConfig) => {
416467
417468 const pegoutCreationBlockNumber = Number ( svpFundTxWaitingForConfirmations . pegoutCreationBlockNumber ) ;
418469
419- const expectedPegoutCreationBlockNumber = commitFederationCreationBlockNumber + 1 ;
470+ const expectedPegoutCreationBlockNumber = commitFederationCreationBlockNumber + 4 ; // + 4 because a previous test mines 3 blocks, plus 1 for the expected pegout creation block number to be the next block.
420471 expect ( pegoutCreationBlockNumber ) . to . be . equal ( expectedPegoutCreationBlockNumber , 'The svp fund tx pegout creation block number should be the block that contains the first updateCollections call right after the commitFederation call.' ) ;
421472
422473 const rawSvpFundTransaction = svpFundTxWaitingForConfirmations . btcRawTx ;
@@ -498,7 +549,7 @@ const execute = (description, newFederationConfig) => {
498549
499550 it ( 'should register the SVP Spend transaction and finish the SVP process' , async function ( ) {
500551
501- const blockNumberBeforeUpdateCollections = await rskTxHelper . getBlockNumber ( ) ;
552+ const blockNumberBeforeUpdateCollections = await rskTxHelper . getBlockNumber ( ) - 3 ;
502553 const expectedCountOfSignatures = Math . floor ( newFederationPublicKeys . length / 2 ) + 1 ;
503554
504555 await waitForExpectedCountOfAddSignatureEventsToBeEmitted ( rskTxHelpers , blockNumberBeforeUpdateCollections , expectedCountOfSignatures ) ;
@@ -537,6 +588,30 @@ const execute = (description, newFederationConfig) => {
537588
538589 } ) ;
539590
591+ it ( 'should not create a new pending federation when there is a federation waiting for activation' , async ( ) => {
592+
593+ const initialPendingFederationHash = await bridge . methods . getPendingFederationHash ( ) . call ( ) ;
594+ expect ( initialPendingFederationHash , 'The pending federation hash should be null.' ) . to . be . null ;
595+
596+ const createFederationMethod = await bridge . methods . createFederation ( ) ;
597+
598+ const message = 'The `createFederation` method should not be callable when there is a federation waiting for activation.' ;
599+
600+ await rskUtils . sendTxWithCheck ( rskTxHelper , createFederationMethod , fedChangeAuthorizer1Address , result => {
601+ expect ( result ) . to . be . equal ( EXISTING_FEDERATION_AWAITING_ACTIVATION_ERROR_CODE , message ) ;
602+ } ) ;
603+ await rskUtils . sendTxWithCheck ( rskTxHelper , createFederationMethod , fedChangeAuthorizer2Address , result => {
604+ expect ( result ) . to . be . equal ( EXISTING_FEDERATION_AWAITING_ACTIVATION_ERROR_CODE , message ) ;
605+ } ) ;
606+ await rskUtils . sendTxWithCheck ( rskTxHelper , createFederationMethod , fedChangeAuthorizer3Address , result => {
607+ expect ( result ) . to . be . equal ( EXISTING_FEDERATION_AWAITING_ACTIVATION_ERROR_CODE , message ) ;
608+ } ) ;
609+
610+ const finalPendingFederationHash = await bridge . methods . getPendingFederationHash ( ) . call ( ) ;
611+ expect ( finalPendingFederationHash , 'The pending federation hash should be null.' ) . to . be . null ;
612+
613+ } ) ;
614+
540615 it ( 'should activate federation' , async ( ) => {
541616
542617 const federationActivationBlockNumber = commitFederationCreationBlockNumber + FEDERATION_ACTIVATION_AGE ;
@@ -665,6 +740,30 @@ const execute = (description, newFederationConfig) => {
665740
666741 } ) ;
667742
743+ it ( 'should not create a new pending federation when there is a retiring federation' , async ( ) => {
744+
745+ const initialPendingFederationHash = await bridge . methods . getPendingFederationHash ( ) . call ( ) ;
746+ expect ( initialPendingFederationHash , 'The pending federation hash should be null.' ) . to . be . null ;
747+
748+ const createFederationMethod = await bridge . methods . createFederation ( ) ;
749+
750+ const message = 'The `createFederation` method should not be callable when there is a retiring federation.' ;
751+
752+ await rskUtils . sendTxWithCheck ( rskTxHelper , createFederationMethod , fedChangeAuthorizer1Address , result => {
753+ expect ( result ) . to . be . equal ( RETIRING_FEDERATION_ALREADY_EXISTS , message ) ;
754+ } ) ;
755+ await rskUtils . sendTxWithCheck ( rskTxHelper , createFederationMethod , fedChangeAuthorizer2Address , result => {
756+ expect ( result ) . to . be . equal ( RETIRING_FEDERATION_ALREADY_EXISTS , message ) ;
757+ } ) ;
758+ await rskUtils . sendTxWithCheck ( rskTxHelper , createFederationMethod , fedChangeAuthorizer3Address , result => {
759+ expect ( result ) . to . be . equal ( RETIRING_FEDERATION_ALREADY_EXISTS , message ) ;
760+ } ) ;
761+
762+ const finalPendingFederationHash = await bridge . methods . getPendingFederationHash ( ) . call ( ) ;
763+ expect ( finalPendingFederationHash , 'The pending federation hash should be null.' ) . to . be . null ;
764+
765+ } ) ;
766+
668767 it ( 'should complete retiring the old federation' , async ( ) => {
669768
670769 await rskUtils . waitForSync ( rskTxHelpers ) ;
0 commit comments