Skip to content

Commit

Permalink
Merge pull request #2941 from rsksmart/allow_proposed_fed_to_call_add…
Browse files Browse the repository at this point in the history
…_signature

Allow proposed fed to call add signature
  • Loading branch information
marcos-iov authored Jan 23, 2025
2 parents 2545809 + 80a901b commit bb95d83
Show file tree
Hide file tree
Showing 7 changed files with 349 additions and 44 deletions.
35 changes: 32 additions & 3 deletions rskj-core/src/main/java/co/rsk/peg/Bridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -1475,14 +1475,43 @@ public long getEstimatedFeesForNextPegOutEvent(Object[] args) throws IOException

public static BridgeMethods.BridgeMethodExecutor activeAndRetiringFederationOnly(BridgeMethods.BridgeMethodExecutor decoratee, String funcName) {
return (self, args) -> {
boolean isFromActiveFed = BridgeUtils.isFromFederateMember(self.rskTx, self.bridgeSupport.getActiveFederation(), self.signatureCache);

Federation retiringFederation = self.bridgeSupport.getRetiringFederation();
boolean isFromRetiringFed = retiringFederation != null && BridgeUtils.isFromFederateMember(self.rskTx, retiringFederation, self.signatureCache);

if (!BridgeUtils.isFromFederateMember(self.rskTx, self.bridgeSupport.getActiveFederation(), self.signatureCache)
&& (retiringFederation == null || !BridgeUtils.isFromFederateMember(self.rskTx, retiringFederation, self.signatureCache))) {
String errorMessage = String.format("Sender is not part of the active or retiring federations, so he is not enabled to call the function '%s'",funcName);
if (!isFromActiveFed && !isFromRetiringFed) {
String errorMessage = String.format(
"The sender is not a member of the active or retiring federations and is therefore not authorized to invoke the function: '%s'",
funcName
);
logger.warn(errorMessage);
throw new VMException(errorMessage);
}

return decoratee.execute(self, args);
};
}

public static BridgeMethods.BridgeMethodExecutor activeRetiringAndProposedFederationOnly(BridgeMethods.BridgeMethodExecutor decoratee, String funcName) {
return (self, args) -> {
boolean isFromActiveFed = BridgeUtils.isFromFederateMember(self.rskTx, self.bridgeSupport.getActiveFederation(), self.signatureCache);

Federation retiringFederation = self.bridgeSupport.getRetiringFederation();
boolean isFromRetiringFed = retiringFederation != null && BridgeUtils.isFromFederateMember(self.rskTx, retiringFederation, self.signatureCache);

Optional<Federation> proposedFederation = self.bridgeSupport.getProposedFederation();
boolean isFromProposedFed = proposedFederation.isPresent() && BridgeUtils.isFromFederateMember(self.rskTx, proposedFederation.get(), self.signatureCache);

if (!isFromActiveFed && !isFromRetiringFed && !isFromProposedFed) {
String errorMessage = String.format(
"The sender is not a member of the active, retiring, or proposed federations and is therefore not authorized to call the function: '%s'",
funcName
);
logger.warn(errorMessage);
throw new VMException(errorMessage);
}

return decoratee.execute(self, args);
};
}
Expand Down
2 changes: 1 addition & 1 deletion rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public enum BridgeMethods {
new String[]{}
),
fixedCost(70000L),
Bridge.activeAndRetiringFederationOnly((BridgeMethodExecutorVoid) Bridge::addSignature, "addSignature"),
Bridge.activeRetiringAndProposedFederationOnly((BridgeMethodExecutorVoid) Bridge::addSignature, "addSignature"),
fixedPermission(false)
),
COMMIT_FEDERATION(
Expand Down
5 changes: 4 additions & 1 deletion rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java
Original file line number Diff line number Diff line change
Expand Up @@ -2277,12 +2277,15 @@ public Federation getActiveFederation() {
return federationSupport.getActiveFederation();
}


@Nullable
public Federation getRetiringFederation() {
return federationSupport.getRetiringFederation();
}

public Optional<Federation> getProposedFederation() {
return federationSupport.getProposedFederation();
}

public Address getActiveFederationAddress() {
return federationSupport.getActiveFederationAddress();
}
Expand Down
6 changes: 6 additions & 0 deletions rskj-core/src/test/java/co/rsk/RskTestUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ public static Block createRskBlock() {
return createRskBlock(defaultBlockNumber, defaultBlockTimestamp.toEpochMilli());
}

public static Block createRskBlock(long blockNumber) {
final Instant defaultBlockTimestamp = ZonedDateTime.parse("2020-01-20T12:00:08.400Z").toInstant();

return createRskBlock(blockNumber, defaultBlockTimestamp.toEpochMilli());
}

public static Block createRskBlock(long blockNumber, long blockTimestamp) {
BlockHeader blockHeader = new BlockHeaderBuilder(mock(ActivationConfig.class))
.setNumber(blockNumber)
Expand Down
22 changes: 20 additions & 2 deletions rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,25 @@ void getPendingFederatorPublicKeyOfType() {
}

@Test
void getProposedFederationAddress_whenBridgeSupportReturnsEmpty_shouldReturnEmpty() {
void getProposedFederation_whenFederationSupportReturnsProposedFederation_shouldReturnProposedFed() {
when(federationSupport.getProposedFederation()).thenReturn(Optional.of(federation));

Optional<Federation> proposedFed = bridgeSupport.getProposedFederation();
assertTrue(proposedFed.isPresent());
assertThat(proposedFed.get(), is(federation));
}

@Test
void getProposedFederation_whenNoProposedFederation_shouldReturnEmpty() {
// Act
var actualProposedFederation = bridgeSupport.getProposedFederation();

// Assert
assertFalse(actualProposedFederation.isPresent());
}

@Test
void getProposedFederationAddress_whenNoProposedFederationAddress_shouldReturnEmpty() {
// Act
var actualProposedFederationAddress = bridgeSupport.getProposedFederationAddress();

Expand All @@ -524,7 +542,7 @@ void getProposedFederationAddress_whenBridgeSupportReturnsEmpty_shouldReturnEmpt
}

@Test
void getProposedFederationAddress_whenProposedFederationExists_shouldReturnAddress() {
void getProposedFederationAddress_whenFederationSupportReturnsAddress_shouldReturnAddress() {
// Arrange
var expectedAddress = federation.getAddress();
when(federationSupport.getProposedFederationAddress()).thenReturn(Optional.of(expectedAddress));
Expand Down
2 changes: 1 addition & 1 deletion rskj-core/src/test/java/co/rsk/peg/BridgeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ void registerBtcTransaction_beforeRskip199_rejectsExternalCalls() throws VMExcep
bridge.execute(data);
fail();
} catch (VMException e) {
assertEquals("Exception executing bridge: Sender is not part of the active or retiring federations, so he is not enabled to call the function 'registerBtcTransaction'", e.getMessage());
assertEquals("Exception executing bridge: The sender is not a member of the active or retiring federations and is therefore not authorized to invoke the function: 'registerBtcTransaction'", e.getMessage());
}

verify(bridgeSupportMock, never()).registerBtcTransaction(
Expand Down
Loading

0 comments on commit bb95d83

Please sign in to comment.