Skip to content

Commit

Permalink
Merge pull request #2838 from rsksmart/update_state_svp
Browse files Browse the repository at this point in the history
Create updateSvpState method
  • Loading branch information
marcos-iov authored Nov 13, 2024
2 parents 7a04c05 + 4083234 commit 3858201
Show file tree
Hide file tree
Showing 2 changed files with 397 additions and 358 deletions.
109 changes: 78 additions & 31 deletions rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java
Original file line number Diff line number Diff line change
Expand Up @@ -1010,20 +1010,70 @@ public void updateCollections(Transaction rskTx) throws IOException {
processConfirmedPegouts(rskTx);

updateFederationCreationBlockHeights();

updateSvpState(rskTx);
}

private void logUpdateCollections(Transaction rskTx) {
RskAddress sender = rskTx.getSender(signatureCache);
eventLogger.logUpdateCollections(sender);
}

protected void processSVPFailure(Federation proposedFederation) {
private void updateSvpState(Transaction rskTx) {
Optional<Federation> proposedFederationOpt = federationSupport.getProposedFederation();
if (proposedFederationOpt.isEmpty()) {
logger.trace("[updateSvpState] Proposed federation does not exist, so there's no svp going on.");
return;
}

// if the proposed federation exists and the validation period ended,
// we can conclude that the svp failed
Federation proposedFederation = proposedFederationOpt.get();
if (!validationPeriodIsOngoing(proposedFederation)) {
logger.info(
"[updateSvpState] Proposed federation validation failed at block {}. SVP failure will be processed",
rskExecutionBlock.getNumber()
);
processSvpFailure(proposedFederation);
return;
}

Keccak256 rskTxHash = rskTx.getHash();

if (shouldCreateAndProcessSvpFundTransaction()) {
logger.info(
"[updateSvpState] No svp values were found, so fund tx creation will be processed."
);
processSvpFundTransactionUnsigned(rskTxHash, proposedFederation);
}

// if the fund tx signed is present, then the fund transaction change was registered,
// meaning we can create the spend tx.
Optional<BtcTransaction> svpFundTxSigned = provider.getSvpFundTxSigned();
if (svpFundTxSigned.isPresent()) {
logger.info(
"[updateSvpState] Fund tx signed was found, so spend tx creation will be processed."
);
processSvpSpendTransactionUnsigned(rskTxHash, proposedFederation, svpFundTxSigned.get());
}
}

private boolean shouldCreateAndProcessSvpFundTransaction() {
// the fund tx will be created when the svp starts,
// so we must ensure all svp values are clear to proceed with its creation
Optional<Sha256Hash> svpFundTxHashUnsigned = provider.getSvpFundTxHashUnsigned();
Optional<BtcTransaction> svpFundTxSigned = provider.getSvpFundTxSigned();
Optional<Sha256Hash> svpSpendTxHashUnsigned = provider.getSvpSpendTxHashUnsigned(); // spendTxHash will be removed the last, after spendTxWFS, so is enough checking just this value

return svpFundTxHashUnsigned.isEmpty()
&& svpFundTxSigned.isEmpty()
&& svpSpendTxHashUnsigned.isEmpty();
}

private void processSvpFailure(Federation proposedFederation) {
eventLogger.logCommitFederationFailure(rskExecutionBlock, proposedFederation);
logger.warn(
"[processSVPFailure] Proposed federation validation failed at block {}, so federation election will be allowed again.",
rskExecutionBlock.getNumber()
);

logger.info("[processSVPFailure] Federation election will be allowed again.");
allowFederationElectionAgain();
}

Expand All @@ -1045,21 +1095,24 @@ private boolean validationPeriodIsOngoing(Federation proposedFederation) {
return rskExecutionBlock.getNumber() < validationPeriodEndBlock;
}

protected void processSvpFundTransactionUnsigned(Transaction rskTx) throws IOException, InsufficientMoneyException {
Optional<Federation> proposedFederationOpt = federationSupport.getProposedFederation();
if (proposedFederationOpt.isEmpty()) {
String message = "Proposed federation should be present when processing SVP fund transaction.";
logger.warn(message);
throw new IllegalStateException(message);
}
Federation proposedFederation = proposedFederationOpt.get();

private void processSvpFundTransactionUnsigned(Keccak256 rskTxHash, Federation proposedFederation) {
Coin spendableValueFromProposedFederation = bridgeConstants.getSpendableValueFromProposedFederation();
BtcTransaction svpFundTransactionUnsigned = createSvpFundTransaction(proposedFederation, spendableValueFromProposedFederation);

provider.setSvpFundTxHashUnsigned(svpFundTransactionUnsigned.getHash());
PegoutsWaitingForConfirmations pegoutsWaitingForConfirmations = provider.getPegoutsWaitingForConfirmations();
settleReleaseRequest(pegoutsWaitingForConfirmations, svpFundTransactionUnsigned, rskTx.getHash(), spendableValueFromProposedFederation);
try {
BtcTransaction svpFundTransactionUnsigned = createSvpFundTransaction(proposedFederation, spendableValueFromProposedFederation);
provider.setSvpFundTxHashUnsigned(svpFundTransactionUnsigned.getHash());
PegoutsWaitingForConfirmations pegoutsWaitingForConfirmations = provider.getPegoutsWaitingForConfirmations();
settleReleaseRequest(pegoutsWaitingForConfirmations, svpFundTransactionUnsigned, rskTxHash, spendableValueFromProposedFederation);
} catch (InsufficientMoneyException e) {
logger.error(
"[processSvpFundTransactionUnsigned] Insufficient funds for creating the fund transaction. Error message: {}",
e.getMessage()
);
} catch (IOException e) {
logger.error(
"[processSvpFundTransactionUnsigned] IOException getting the pegouts waiting for confirmations. Error message: {}",
e.getMessage()
);
}
}

private BtcTransaction createSvpFundTransaction(Federation proposedFederation, Coin spendableValueFromProposedFederation) throws InsufficientMoneyException {
Expand Down Expand Up @@ -1092,19 +1145,13 @@ private SendRequest createSvpFundTransactionSendRequest(BtcTransaction transacti
return sendRequest;
}

protected void processSvpSpendTransactionUnsigned(Transaction rskTx) {
federationSupport.getProposedFederation()
.ifPresent(proposedFederation -> provider.getSvpFundTxSigned()
.ifPresent(svpFundTxSigned -> {
BtcTransaction svpSpendTransactionUnsigned = createSvpSpendTransaction(svpFundTxSigned, proposedFederation);

Keccak256 rskTxHash = rskTx.getHash();
updateSvpSpendTransactionValues(rskTxHash, svpSpendTransactionUnsigned);
private void processSvpSpendTransactionUnsigned(Keccak256 rskTxHash, Federation proposedFederation, BtcTransaction svpFundTxSigned) {
BtcTransaction svpSpendTransactionUnsigned = createSvpSpendTransaction(svpFundTxSigned, proposedFederation);
updateSvpSpendTransactionValues(rskTxHash, svpSpendTransactionUnsigned);

Coin amountSentToActiveFed = svpSpendTransactionUnsigned.getOutput(0).getValue();
logReleaseRequested(rskTxHash, svpSpendTransactionUnsigned, amountSentToActiveFed);
logPegoutTransactionCreated(svpSpendTransactionUnsigned);
}));
Coin amountSentToActiveFed = svpSpendTransactionUnsigned.getOutput(0).getValue();
logReleaseRequested(rskTxHash, svpSpendTransactionUnsigned, amountSentToActiveFed);
logPegoutTransactionCreated(svpSpendTransactionUnsigned);
}

private BtcTransaction createSvpSpendTransaction(BtcTransaction svpFundTxSigned, Federation proposedFederation) {
Expand Down
Loading

0 comments on commit 3858201

Please sign in to comment.