Skip to content

Commit

Permalink
Add getRetiredPools() instead of getRewardAddressesOfRetiredPools to …
Browse files Browse the repository at this point in the history
…track exact deposit amount
  • Loading branch information
satran004 committed Nov 6, 2024
1 parent a41effe commit dae4ab9
Show file tree
Hide file tree
Showing 15 changed files with 112 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
package org.cardanofoundation.rewards.calculation;

import org.cardanofoundation.rewards.calculation.config.NetworkConfig;
import org.cardanofoundation.rewards.calculation.domain.RetiredPool;

import java.math.BigInteger;
import static org.cardanofoundation.rewards.calculation.util.BigNumberUtils.multiply;
import java.util.Set;

public class DepositsCalculation {

public static BigInteger calculateDepositsInEpoch(BigInteger depositsInPreviousEpoch,
BigInteger transactionDepositsInEpoch,
int retiredPoolsInEpoch,
NetworkConfig networkConfig) {
Set<RetiredPool> retiredPoolsInEpoch) {
BigInteger deposits = BigInteger.ZERO;
deposits = deposits.add(transactionDepositsInEpoch);
deposits = deposits.subtract(
multiply(retiredPoolsInEpoch, networkConfig.getPoolDepositInLovelace()));

//add deposits of retired pools
var refundAmount = retiredPoolsInEpoch.stream()
.reduce(BigInteger.ZERO, (sum, retiredPool) -> sum.add(retiredPool.getDepositAmount()), BigInteger::add);

deposits = deposits.subtract(refundAmount);
return depositsInPreviousEpoch.add(deposits);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static org.cardanofoundation.rewards.calculation.PoolRewardsCalculation.calculatePoolRewardInEpoch;
Expand All @@ -22,7 +23,7 @@ public static EpochCalculationResult calculateEpochRewardPots(final int epoch,
final BigInteger reserveInPreviousEpoch,
final BigInteger treasuryInPreviousEpoch,
final ProtocolParameters protocolParameters, final Epoch epochInfo,
final HashSet<String> rewardAddressesOfRetiredPools,
final Set<RetiredPool> retiredPools,
final HashSet<String> deregisteredAccounts,
final List<MirCertificate> mirCertificates,
final List<String> poolsThatProducedBlocksInEpoch,
Expand Down Expand Up @@ -82,6 +83,9 @@ public static EpochCalculationResult calculateEpochRewardPots(final int epoch,
// The sum of all the refunds attached to unregistered reward accounts are added to the
// treasury (see: Pool Reap Transition, p.53, figure 40, shelley-ledger.pdf)
BigInteger unclaimedRefunds = BigInteger.ZERO;
var rewardAddressesOfRetiredPools = retiredPools.stream()
.map(retiredPool -> retiredPool.getRewardAddress()).collect(Collectors.toSet());

if (rewardAddressesOfRetiredPools.size() > 0) {
List<String> deregisteredOwnerAccounts = deregisteredAccountsOnEpochBoundary.stream()
.filter(rewardAddressesOfRetiredPools::contains).toList();
Expand All @@ -91,13 +95,13 @@ public static EpochCalculationResult calculateEpochRewardPots(final int epoch,
/* Check if the reward address of the retired pool has been unregistered before
or if the reward address has been unregistered after the randomness stabilization window
or if the reward address has not been registered at all */
for (String rewardAddress : rewardAddressesOfRetiredPools) {
if (deregisteredOwnerAccounts.contains(rewardAddress) ||
!ownerAccountsRegisteredInThePast.contains(rewardAddress)) {
for (var retiredPool : retiredPools) {
if (deregisteredOwnerAccounts.contains(retiredPool.getRewardAddress()) ||
!ownerAccountsRegisteredInThePast.contains(retiredPool.getRewardAddress())) {
// If the reward address has been unregistered, the deposit can not be returned
// and will be added to the treasury instead (Pool Reap see: shelley-ledger.pdf p.53)
treasuryForCurrentEpoch = treasuryForCurrentEpoch.add(networkConfig.getPoolDepositInLovelace());
unclaimedRefunds = unclaimedRefunds.add(networkConfig.getPoolDepositInLovelace());
treasuryForCurrentEpoch = treasuryForCurrentEpoch.add(retiredPool.getDepositAmount());
unclaimedRefunds = unclaimedRefunds.add(retiredPool.getDepositAmount());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.math.MathContext;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static org.cardanofoundation.rewards.calculation.util.BigNumberUtils.*;
Expand All @@ -17,7 +18,7 @@ public class TreasuryCalculation {

public static TreasuryCalculationResult calculateTreasuryInEpoch(int epoch, ProtocolParameters protocolParameters,
AdaPots adaPotsForPreviousEpoch, Epoch epochInfo,
HashSet<String> rewardAddressesOfRetiredPools,
Set<RetiredPool> retiredPools,
List<MirCertificate> mirCertificates,
final HashSet<String> deregisteredAccounts,
final HashSet<String> registeredAccountsUntilNow,
Expand Down Expand Up @@ -60,14 +61,15 @@ public static TreasuryCalculationResult calculateTreasuryInEpoch(int epoch, Prot
final BigInteger treasuryCut = multiplyAndFloor(totalRewardPot, treasuryGrowthRate);
BigInteger treasuryForCurrentEpoch = treasuryInPreviousEpoch.add(treasuryCut);

var rewardAddressesOfRetiredPools = retiredPools.stream().map(RetiredPool::getRewardAddress).collect(Collectors.toSet());
BigInteger unclaimedRefunds = BigInteger.ZERO;
if (rewardAddressesOfRetiredPools.size() > 0) {
HashSet<String> deregisteredRewardAccounts = deregisteredAccounts.stream()
.filter(rewardAddressesOfRetiredPools::contains).collect(Collectors.toCollection(HashSet::new));
List<String> ownerAccountsRegisteredInThePast = registeredAccountsUntilNow.stream()
.filter(rewardAddressesOfRetiredPools::contains).toList();

unclaimedRefunds = calculateUnclaimedRefundsForRetiredPools(rewardAddressesOfRetiredPools, deregisteredRewardAccounts, ownerAccountsRegisteredInThePast, networkConfig);
unclaimedRefunds = calculateUnclaimedRefundsForRetiredPools(retiredPools, deregisteredRewardAccounts, ownerAccountsRegisteredInThePast, networkConfig);
treasuryForCurrentEpoch = treasuryForCurrentEpoch.add(unclaimedRefunds);
}

Expand Down Expand Up @@ -141,21 +143,21 @@ private static BigDecimal calculateEta(int totalBlocksInEpochByPools, BigDecimal
pool's registered reward account, provided the reward account is still registered." -
https://github.com/input-output-hk/cardano-ledger/blob/9e2f8151e3b9a0dde9faeb29a7dd2456e854427c/eras/shelley/formal-spec/epoch.tex#L546C9-L547C87
*/
public static BigInteger calculateUnclaimedRefundsForRetiredPools(HashSet<String> rewardAddressesOfRetiredPools,
public static BigInteger calculateUnclaimedRefundsForRetiredPools(Set<RetiredPool> retiredPools,
HashSet<String> deregisteredRewardAccounts,
List<String> ownerAccountsRegisteredInThePast,
NetworkConfig networkConfig) {
BigInteger unclaimedRefunds = BigInteger.ZERO;
if (rewardAddressesOfRetiredPools.size() > 0) {
if (retiredPools.size() > 0) {
/* Check if the reward address of the retired pool has been unregistered before
or if the reward address has been unregistered after the randomness stabilization window
or if the reward address has not been registered at all */
for (String rewardAddress : rewardAddressesOfRetiredPools) {
if (deregisteredRewardAccounts.contains(rewardAddress) ||
!ownerAccountsRegisteredInThePast.contains(rewardAddress)) {
for (var retiredPool : retiredPools) {
if (deregisteredRewardAccounts.contains(retiredPool.getRewardAddress()) ||
!ownerAccountsRegisteredInThePast.contains(retiredPool.getRewardAddress())) {
// If the reward address has been unregistered, the deposit can not be returned
// and will be added to the treasury instead (Pool Reap see: shelley-ledger.pdf p.53)
unclaimedRefunds = unclaimedRefunds.add(networkConfig.getPoolDepositInLovelace());
unclaimedRefunds = unclaimedRefunds.add(retiredPool.getDepositAmount());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.cardanofoundation.rewards.calculation.domain;

import lombok.*;

import java.math.BigInteger;
import java.util.Objects;

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RetiredPool {
private String poolId;
private String rewardAddress;
private BigInteger depositAmount;

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RetiredPool that = (RetiredPool) o;
return Objects.equals(poolId, that.poolId) && Objects.equals(rewardAddress, that.rewardAddress);
}

@Override
public int hashCode() {
return Objects.hash(poolId, rewardAddress);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package org.cardanofoundation.rewards.validation;

import org.cardanofoundation.rewards.calculation.config.NetworkConfig;
import org.cardanofoundation.rewards.calculation.domain.RetiredPool;
import org.cardanofoundation.rewards.validation.data.provider.DataProvider;
import org.cardanofoundation.rewards.calculation.domain.AdaPots;
import java.math.BigInteger;
import java.util.HashSet;
import java.util.Set;

import static org.cardanofoundation.rewards.calculation.DepositsCalculation.calculateDepositsInEpoch;

Expand All @@ -14,14 +16,14 @@ public static BigInteger computeDepositsInEpoch(int epoch, DataProvider dataProv
AdaPots adaPots = dataProvider.getAdaPotsForEpoch(epoch);
BigInteger depositsInPreviousEpoch = adaPots.getDeposits();
BigInteger transactionDepositsInEpoch = BigInteger.ZERO;
HashSet<String> retiredPoolsInEpoch = new HashSet<>();
Set<RetiredPool> retiredPoolsInEpoch = new HashSet<>();

if (epoch > 207) {
if (epoch >= networkConfig.getShelleyStartEpoch()) {
transactionDepositsInEpoch = dataProvider.getTransactionDepositsInEpoch(epoch);
retiredPoolsInEpoch = dataProvider.getRewardAddressesOfRetiredPoolsInEpoch(epoch + 1);
retiredPoolsInEpoch = dataProvider.getRetiredPoolsInEpoch(epoch + 1);
}

return calculateDepositsInEpoch(depositsInPreviousEpoch,
transactionDepositsInEpoch, retiredPoolsInEpoch.size(), networkConfig);
transactionDepositsInEpoch, retiredPoolsInEpoch);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public static EpochCalculationResult calculateEpochRewardPots(int epoch, DataPro

epochCalculationResult = EpochCalculation.calculateEpochRewardPots(
epoch, epochValidationInput.getReservesOfPreviousEpoch(),
epochValidationInput.getTreasuryOfPreviousEpoch(), protocolParameters, epochInfo, epochValidationInput.getRewardAddressesOfRetiredPoolsInEpoch(),
epochValidationInput.getTreasuryOfPreviousEpoch(), protocolParameters, epochInfo, epochValidationInput.getRetiredPools(),
epochValidationInput.getDeregisteredAccounts(),
new ArrayList<>(epochValidationInput.getMirCertificates()),
new ArrayList<>(poolIds),
Expand All @@ -121,7 +121,10 @@ public static EpochCalculationResult calculateEpochRewardPots(int epoch, DataPro
AdaPots adaPotsForPreviousEpoch = dataProvider.getAdaPotsForEpoch(epoch - 1);
ProtocolParameters protocolParameters = dataProvider.getProtocolParametersForEpoch(epoch - 2);
Epoch epochInfo = dataProvider.getEpochInfo(epoch - 2, networkConfig);
HashSet<String> rewardAddressesOfRetiredPoolsInEpoch = dataProvider.getRewardAddressesOfRetiredPoolsInEpoch(epoch);

Set<RetiredPool> retiredPoolsInEpoch = dataProvider.getRetiredPoolsInEpoch(epoch);
Set<String> rewardAddressesOfRetiredPoolsInEpoch = retiredPoolsInEpoch.stream().map(RetiredPool::getRewardAddress).collect(Collectors.toSet());

List<MirCertificate> mirCertificates = dataProvider.getMirCertificatesInEpoch(epoch - 1);
List<PoolBlock> blocksMadeByPoolsInEpoch = dataProvider.getBlocksMadeByPoolsInEpoch(epoch - 2);
List<String> poolIds = blocksMadeByPoolsInEpoch.stream().map(PoolBlock::getPoolId).distinct().toList();
Expand Down Expand Up @@ -167,7 +170,7 @@ public static EpochCalculationResult calculateEpochRewardPots(int epoch, DataPro

start = System.currentTimeMillis();
epochCalculationResult = EpochCalculation.calculateEpochRewardPots(
epoch, adaPotsForPreviousEpoch.getReserves(), adaPotsForPreviousEpoch.getTreasury(), protocolParameters, epochInfo, rewardAddressesOfRetiredPoolsInEpoch, deregisteredAccounts,
epoch, adaPotsForPreviousEpoch.getReserves(), adaPotsForPreviousEpoch.getTreasury(), protocolParameters, epochInfo, retiredPoolsInEpoch, deregisteredAccounts,
mirCertificates, poolIds, poolStates, lateDeregisteredAccounts,
registeredAccountsSinceLastEpoch, registeredAccountsUntilNow, sharedPoolRewardAddressesWithoutReward,
deregisteredAccountsOnEpochBoundary, networkConfig);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.math.BigInteger;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class TreasuryValidation {
Expand Down Expand Up @@ -49,15 +50,16 @@ public static TreasuryValidationResult calculateTreasuryForEpoch(int epoch, Data
}

treasuryCalculationResult = TreasuryCalculation.calculateTreasuryInEpoch(epoch, protocolParameters, adaPotsForPreviousEpoch, epochInfo,
epochValidationInput.getRewardAddressesOfRetiredPoolsInEpoch(),
epochValidationInput.getRetiredPools(),
epochValidationInput.getMirCertificates().stream().toList(),
epochValidationInput.getDeregisteredAccountsOnEpochBoundary(),
epochValidationInput.getRegisteredAccountsUntilNow(), BigInteger.ZERO, networkConfig);
} else {
AdaPots adaPotsForPreviousEpoch = dataProvider.getAdaPotsForEpoch(epoch - 1);
ProtocolParameters protocolParameters = dataProvider.getProtocolParametersForEpoch(epoch - 2);
Epoch epochInfo = dataProvider.getEpochInfo(epoch - 2, networkConfig);
HashSet<String> rewardAddressesOfRetiredPoolsInEpoch = dataProvider.getRewardAddressesOfRetiredPoolsInEpoch(epoch);
Set<RetiredPool> retiredPools = dataProvider.getRetiredPoolsInEpoch(epoch);
Set<String> rewardAddressesOfRetiredPoolsInEpoch = retiredPools.stream().map(RetiredPool::getRewardAddress).collect(Collectors.toSet());
List<MirCertificate> mirCertificates = dataProvider.getMirCertificatesInEpoch(epoch - 1);
List<PoolBlock> blocksMadeByPoolsInEpoch = dataProvider.getBlocksMadeByPoolsInEpoch(epoch - 2);
List<PoolState> poolHistories = dataProvider.getHistoryOfAllPoolsInEpoch(epoch - 2, blocksMadeByPoolsInEpoch);
Expand All @@ -66,7 +68,7 @@ public static TreasuryValidationResult calculateTreasuryForEpoch(int epoch, Data
HashSet<String> poolRewardAddresses = poolHistories.stream().map(PoolState::getRewardAddress).collect(Collectors.toCollection(HashSet::new));
poolRewardAddresses.addAll(rewardAddressesOfRetiredPoolsInEpoch);
HashSet<String> registeredAccountsUntilNow = dataProvider.getRegisteredAccountsUntilNow(epoch, poolRewardAddresses, networkConfig.getRandomnessStabilisationWindow());
treasuryCalculationResult = TreasuryCalculation.calculateTreasuryInEpoch(epoch, protocolParameters, adaPotsForPreviousEpoch, epochInfo, rewardAddressesOfRetiredPoolsInEpoch, mirCertificates, deregisteredAccountsOnEpochBoundary, registeredAccountsUntilNow, BigInteger.ZERO, networkConfig);
treasuryCalculationResult = TreasuryCalculation.calculateTreasuryInEpoch(epoch, protocolParameters, adaPotsForPreviousEpoch, epochInfo, retiredPools, mirCertificates, deregisteredAccountsOnEpochBoundary, registeredAccountsUntilNow, BigInteger.ZERO, networkConfig);
}

TreasuryValidationResult treasuryValidationResult = TreasuryValidationResult.fromTreasuryCalculationResult(treasuryCalculationResult);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.math.BigInteger;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
Expand Down Expand Up @@ -85,7 +86,10 @@ public void fetch(int epoch, boolean override, boolean skipValidationData, Netwo
HashSet<String> deregisteredAccounts;
HashSet<String> deregisteredAccountsOnEpochBoundary;
HashSet<String> lateDeregisteredAccounts = new HashSet<>();
HashSet<String> rewardAddressesOfRetiredPoolsInEpoch = dbSyncDataProvider.getRewardAddressesOfRetiredPoolsInEpoch(epoch);
Set<RetiredPool> retiredPools = new HashSet<>();
retiredPools = dbSyncDataProvider.getRetiredPoolsInEpoch(epoch);
Set<String> rewardAddressesOfRetiredPoolsInEpoch = retiredPools.stream().map(RetiredPool::getRewardAddress).collect(Collectors.toSet());

if (epoch - 2 < networkConfig.getVasilHardforkEpoch()) {
deregisteredAccounts = dbSyncDataProvider.getDeregisteredAccountsInEpoch(epoch - 1, networkConfig.getRandomnessStabilisationWindow());
deregisteredAccountsOnEpochBoundary = dbSyncDataProvider.getDeregisteredAccountsInEpoch(epoch - 1, networkConfig.getExpectedSlotsPerEpoch());
Expand Down Expand Up @@ -145,7 +149,7 @@ public void fetch(int epoch, boolean override, boolean skipValidationData, Netwo
.blockCount(blockCount)
.activeStake(activeStake)
.nonOBFTBlockCount(nonOBFTBlockCount)
.rewardAddressesOfRetiredPoolsInEpoch(rewardAddressesOfRetiredPoolsInEpoch)
.retiredPools(retiredPools)
.deregisteredAccounts(deregisteredAccounts)
.lateDeregisteredAccounts(lateDeregisteredAccounts)
.registeredAccountsSinceLastEpoch(registeredAccountsSinceLastEpoch)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.math.BigInteger;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public interface DataProvider {

Expand All @@ -19,7 +20,7 @@ public interface DataProvider {
public List<PoolState> getHistoryOfAllPoolsInEpoch(int epoch, List<PoolBlock> blocksMadeByPoolsInEpoch);
public PoolState getPoolHistory(String poolId, int epoch);

public HashSet<String> getRewardAddressesOfRetiredPoolsInEpoch(int epoch);
public Set<RetiredPool> getRetiredPoolsInEpoch(int epoch);

public List<MirCertificate> getMirCertificatesInEpoch(int epoch);

Expand Down
Loading

0 comments on commit dae4ab9

Please sign in to comment.