Skip to content

Commit

Permalink
- Rename CANNOT_BE_PROCESSED entry to CANNOT_BE_REFUNDED since now re…
Browse files Browse the repository at this point in the history
…jected pegin should be marked as processed

- Update BridgeSupportRegisterBtcTransactionTest to assert rejected pegin are marked as processed since RSKIP459
- Add tests asserting rejected pegin are marked as processed once RSKIP459 is active
  • Loading branch information
nathanieliov authored and marcos-iov committed Jan 13, 2025
1 parent cc7f787 commit 4037ab7
Showing 7 changed files with 708 additions and 47 deletions.
49 changes: 26 additions & 23 deletions rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java
Original file line number Diff line number Diff line change
@@ -503,42 +503,45 @@ protected void registerPegIn(
);

PeginProcessAction peginProcessAction = peginEvaluationResult.getPeginProcessAction();

if (peginProcessAction == PeginProcessAction.CAN_BE_REGISTERED){
logger.debug("[{}] Peg-in is valid, going to register", METHOD_NAME);
executePegIn(btcTx, peginInformation, totalAmount);
return;
}

// If the peg-in cannot be registered means it should be rejected
Optional<RejectedPeginReason> rejectedPeginReasonOptional = peginEvaluationResult.getRejectedPeginReason();
if (rejectedPeginReasonOptional.isEmpty()) {
// This flow should never be reached. There should always be a rejected pegin reason.
String message = "Invalid state. No rejected reason was returned for an invalid pegin.";
logger.error("[{}] {}", METHOD_NAME, message);
throw new IllegalStateException(message);
}
RejectedPeginReason rejectedPeginReason = rejectedPeginReasonOptional.get();
logger.debug("[{}] Rejected peg-in, reason {}", METHOD_NAME, rejectedPeginReason);
eventLogger.logRejectedPegin(btcTx, rejectedPeginReason);

switch (peginProcessAction) {
case CAN_BE_REGISTERED -> {
logger.debug("[{}] Peg-in is valid, going to register", METHOD_NAME);
executePegIn(btcTx, peginInformation, totalAmount);
}
case CAN_BE_REFUNDED -> {
case CAN_BE_REFUNDED:
logger.debug("[{}] Refunding to address {} ", METHOD_NAME,
peginInformation.getBtcRefundAddress());
generateRejectionRelease(btcTx, peginInformation.getBtcRefundAddress(), rskTxHash,
totalAmount);
markTxAsProcessed(btcTx);
}
default -> {
Optional<RejectedPeginReason> rejectedPeginReasonOptional = peginEvaluationResult.getRejectedPeginReason();
if (rejectedPeginReasonOptional.isEmpty()) {
// This flow should never be reached. There should always be a rejected pegin reason.
String message = "Invalid state. No rejected reason was returned from evaluatePegin method";
logger.error("[{}] {}", METHOD_NAME, message);
throw new IllegalStateException(message);
}
RejectedPeginReason rejectedPeginReason = rejectedPeginReasonOptional.get();
logger.debug("[{}] Rejected peg-in, reason {}", METHOD_NAME, rejectedPeginReason);
eventLogger.logRejectedPegin(btcTx, rejectedPeginReason);
logger.debug("[{}] Unprocessable transaction {}.", METHOD_NAME, btcTx.getHash());
handleUnprocessableBtcTx(btcTx, peginInformation.getProtocolVersion(),
rejectedPeginReason);

break;
case CANNOT_BE_REFUNDED:
logger.debug("[{}] Nonrefundable transaction {}.", METHOD_NAME, btcTx.getHash());
handleNonRefundablePegin(btcTx, peginInformation.getProtocolVersion(), rejectedPeginReason);
// Since RSKIP459, rejected peg-ins should be marked as processed
if (activations.isActive(RSKIP459)) {
markTxAsProcessed(btcTx);
}
}
break;
}
}

private void handleUnprocessableBtcTx(
private void handleNonRefundablePegin(
BtcTransaction btcTx,
int protocolVersion,
RejectedPeginReason rejectedPeginReason
6 changes: 3 additions & 3 deletions rskj-core/src/main/java/co/rsk/peg/PegUtils.java
Original file line number Diff line number Diff line change
@@ -182,7 +182,7 @@ static PeginEvaluationResult evaluatePegin(

if(!allUTXOsToFedAreAboveMinimumPeginValue(btcTx, fedWallet, minimumPeginTxValue, activations)) {
logger.debug("[evaluatePegin] Peg-in contains at least one utxo below the minimum value");
return new PeginEvaluationResult(PeginProcessAction.CANNOT_BE_PROCESSED, INVALID_AMOUNT);
return new PeginEvaluationResult(PeginProcessAction.CANNOT_BE_REFUNDED, INVALID_AMOUNT);
}

try {
@@ -197,7 +197,7 @@ static PeginEvaluationResult evaluatePegin(

PeginProcessAction peginProcessAction = hasRefundAddress ?
PeginProcessAction.CAN_BE_REFUNDED :
PeginProcessAction.CANNOT_BE_PROCESSED;
PeginProcessAction.CANNOT_BE_REFUNDED;

return new PeginEvaluationResult(peginProcessAction, PEGIN_V1_INVALID_PAYLOAD);
}
@@ -225,7 +225,7 @@ private static PeginEvaluationResult evaluateLegacyPeginSender(TxSenderAddressTy
case P2SHP2WSH:
return new PeginEvaluationResult(PeginProcessAction.CAN_BE_REFUNDED, LEGACY_PEGIN_MULTISIG_SENDER);
default:
return new PeginEvaluationResult(PeginProcessAction.CANNOT_BE_PROCESSED, LEGACY_PEGIN_UNDETERMINED_SENDER);
return new PeginEvaluationResult(PeginProcessAction.CANNOT_BE_REFUNDED, LEGACY_PEGIN_UNDETERMINED_SENDER);
}
}

Original file line number Diff line number Diff line change
@@ -3,5 +3,5 @@
public enum PeginProcessAction {
CAN_BE_REGISTERED,
CAN_BE_REFUNDED,
CANNOT_BE_PROCESSED
CANNOT_BE_REFUNDED
}
Original file line number Diff line number Diff line change
@@ -44,6 +44,7 @@
import java.util.stream.Stream;
import org.bouncycastle.util.encoders.Hex;
import org.ethereum.config.blockchain.upgrades.*;
import org.ethereum.config.blockchain.upgrades.ActivationConfig.ForBlock;
import org.ethereum.core.*;
import org.ethereum.crypto.ECKey;
import org.ethereum.vm.PrecompiledContracts;
@@ -108,11 +109,13 @@ private void assertInvalidPeginIsIgnored() throws IOException {
}

// After peg-out tx index gets in use
private void assertInvalidPeginIsRejectedWithInvalidAmountReason(BtcTransaction btcTransaction) throws IOException {
private void assertInvalidPeginIsRejectedWithInvalidAmountReason(BtcTransaction btcTransaction, ActivationConfig.ForBlock activations) throws IOException {
verify(bridgeEventLogger, times(1)).logRejectedPegin(btcTransaction, INVALID_AMOUNT);
verify(bridgeEventLogger, times(1)).logUnrefundablePegin(btcTransaction, UnrefundablePeginReason.INVALID_AMOUNT);
verify(bridgeEventLogger, never()).logPeginBtc(any(), any(), any(), anyInt());
verify(provider, never()).setHeightBtcTxhashAlreadyProcessed(any(), anyLong());

var shouldMarkTxAsProcessed = activations == lovell700Activations? times(1) : never();
verify(provider, shouldMarkTxAsProcessed).setHeightBtcTxhashAlreadyProcessed(any(), anyLong());
assertTrue(activeFederationUtxos.isEmpty());
assertTrue(retiringFederationUtxos.isEmpty());
}
@@ -194,7 +197,13 @@ private void assertLegacyUndeterminedSenderPeginIsRejectedAsPeginV1InvalidPayloa
}

// After arrowhead600Activations is activated
private void assertLegacyUndeterminedSenderPeginIsRejected(BtcTransaction btcTransaction) throws IOException {
private void assertLegacyUndeterminedSenderPeginIsRejected(BtcTransaction btcTransaction,
ForBlock activations) throws IOException {

// tx should be marked as processed since RSKIP459 is active
var shouldMarkTxAsProcessed = activations == lovell700Activations? times(1) : never();
verify(provider, shouldMarkTxAsProcessed).setHeightBtcTxhashAlreadyProcessed(any(), anyLong());

verify(bridgeEventLogger, times(1)).logRejectedPegin(
btcTransaction, RejectedPeginReason.LEGACY_PEGIN_UNDETERMINED_SENDER
);
@@ -205,14 +214,18 @@ private void assertLegacyUndeterminedSenderPeginIsRejected(BtcTransaction btcTra

verify(bridgeEventLogger, never()).logPeginBtc(any(), any(), any(), anyInt());
verify(bridgeEventLogger, never()).logReleaseBtcRequested(any(), any(), any());
verify(provider, never()).setHeightBtcTxhashAlreadyProcessed(any(), anyLong());

Assertions.assertTrue(activeFederationUtxos.isEmpty());
Assertions.assertTrue(retiringFederationUtxos.isEmpty());
Assertions.assertTrue(pegoutsWaitingForConfirmations.getEntries().isEmpty());
}

private void assertInvalidPeginV1UndeterminedSenderIsRejected(BtcTransaction btcTransaction) throws IOException {
private void assertInvalidPeginV1UndeterminedSenderIsRejected(BtcTransaction btcTransaction,
ForBlock activations) throws IOException {

var shouldMarkTxAsProcessed = activations == lovell700Activations? times(1) : never();
verify(provider, shouldMarkTxAsProcessed).setHeightBtcTxhashAlreadyProcessed(any(), anyLong());

verify(bridgeEventLogger, times(1)).logRejectedPegin(
btcTransaction, PEGIN_V1_INVALID_PAYLOAD
);
@@ -224,7 +237,6 @@ private void assertInvalidPeginV1UndeterminedSenderIsRejected(BtcTransaction btc
verify(bridgeEventLogger, never()).logPeginBtc(any(), any(), any(), anyInt());
verify(bridgeEventLogger, never()).logReleaseBtcRequested(any(), any(), any());
verify(bridgeEventLogger, never()).logPegoutTransactionCreated(any(), any());
verify(provider, never()).setHeightBtcTxhashAlreadyProcessed(any(), anyLong());

assertTrue(activeFederationUtxos.isEmpty());
assertTrue(retiringFederationUtxos.isEmpty());
@@ -932,7 +944,7 @@ void pegin_to_active_fed_below_minimum(

// assert
if (shouldUsePegoutTxIndex) {
assertInvalidPeginIsRejectedWithInvalidAmountReason(btcTransaction);
assertInvalidPeginIsRejectedWithInvalidAmountReason(btcTransaction, activations);
} else {
assertInvalidPeginIsIgnored();
}
@@ -970,7 +982,7 @@ void pegin_to_active_fed_below_and_above_minimum(

// assert
if (shouldUsePegoutTxIndex) {
assertInvalidPeginIsRejectedWithInvalidAmountReason(btcTransaction);
assertInvalidPeginIsRejectedWithInvalidAmountReason(btcTransaction, activations);
} else {
assertInvalidPeginIsIgnored();
}
@@ -1012,7 +1024,7 @@ void pegin_multiple_outputs_to_active_fed_sum_amount_equal_to_minimum_pegin(

// assert
if (shouldUsePegoutTxIndex) {
assertInvalidPeginIsRejectedWithInvalidAmountReason(btcTransaction);
assertInvalidPeginIsRejectedWithInvalidAmountReason(btcTransaction, activations);
} else {
assertInvalidPeginIsIgnored();
}
@@ -1085,7 +1097,7 @@ void pegin_to_active_fed_below_minimum_and_retiring_above_minimum(

// assert
if (shouldUsePegoutTxIndex) {
assertInvalidPeginIsRejectedWithInvalidAmountReason(btcTransaction);
assertInvalidPeginIsRejectedWithInvalidAmountReason(btcTransaction, activations);
} else {
assertInvalidPeginIsIgnored();
}
@@ -1405,7 +1417,7 @@ void pegin_v1_to_active_fed_with_invalid_payload_and_unknown_sender_cannot_be_pr
if (activations == fingerrootActivations){
assertLegacyUndeterminedSenderPeginIsRejectedAsPeginV1InvalidPayloadBeforeRSKIP379(btcTransaction);
} else {
assertInvalidPeginV1UndeterminedSenderIsRejected(btcTransaction);
assertInvalidPeginV1UndeterminedSenderIsRejected(btcTransaction, activations);
}
}

@@ -1494,7 +1506,7 @@ void pegin_to_retiring_fed_cannot_be_processed(
if (activations == fingerrootActivations){
assertLegacyUndeterminedSenderPeginIsRejectedAsPeginV1InvalidPayloadBeforeRSKIP379(btcTransaction);
} else {
assertLegacyUndeterminedSenderPeginIsRejected(btcTransaction);
assertLegacyUndeterminedSenderPeginIsRejected(btcTransaction, activations);
}
}

@@ -1543,12 +1555,11 @@ void pegin_legacy_from_segwit_to_active_fed_cannot_be_processed(
);

// assert

// SINCE RSKIP379 ONLY TRANSACTIONS THAT REALLY ARE PROCESSED, REFUNDS OR REGISTER WILL BE MARK AS PROCESSED.
if (activations == fingerrootActivations){
// BEFORE RSKIP379 REJECTED PEGIN WERE MARKED AS PROCESSED.
assertLegacyUndeterminedSenderPeginIsRejectedAsPeginV1InvalidPayloadBeforeRSKIP379(btcTransaction);
} else {
assertLegacyUndeterminedSenderPeginIsRejected(btcTransaction);
assertLegacyUndeterminedSenderPeginIsRejected(btcTransaction, activations);
}
}

Loading

0 comments on commit 4037ab7

Please sign in to comment.