1 | package org.cardanofoundation.explorer.api.service.impl; | |
2 | ||
3 | import java.math.BigInteger; | |
4 | import java.sql.Timestamp; | |
5 | import java.time.LocalDate; | |
6 | import java.time.LocalDateTime; | |
7 | import java.util.*; | |
8 | import java.util.function.Function; | |
9 | import java.util.stream.Collectors; | |
10 | ||
11 | import lombok.RequiredArgsConstructor; | |
12 | import lombok.extern.log4j.Log4j2; | |
13 | ||
14 | import org.springframework.data.domain.Page; | |
15 | import org.springframework.data.domain.PageImpl; | |
16 | import org.springframework.data.domain.Pageable; | |
17 | import org.springframework.stereotype.Service; | |
18 | ||
19 | import org.cardanofoundation.conversions.CardanoConverters; | |
20 | import org.cardanofoundation.explorer.api.common.enumeration.AnalyticType; | |
21 | import org.cardanofoundation.explorer.api.common.enumeration.StakeAddressStatus; | |
22 | import org.cardanofoundation.explorer.api.exception.BusinessCode; | |
23 | import org.cardanofoundation.explorer.api.exception.FetchRewardException; | |
24 | import org.cardanofoundation.explorer.api.exception.NoContentException; | |
25 | import org.cardanofoundation.explorer.api.model.response.BaseFilterResponse; | |
26 | import org.cardanofoundation.explorer.api.model.response.StakeAnalyticResponse; | |
27 | import org.cardanofoundation.explorer.api.model.response.address.*; | |
28 | import org.cardanofoundation.explorer.api.model.response.stake.*; | |
29 | import org.cardanofoundation.explorer.api.projection.*; | |
30 | import org.cardanofoundation.explorer.api.repository.ledgersync.DelegationRepository; | |
31 | import org.cardanofoundation.explorer.api.repository.ledgersync.EpochRepository; | |
32 | import org.cardanofoundation.explorer.api.repository.ledgersync.PoolInfoRepository; | |
33 | import org.cardanofoundation.explorer.api.repository.ledgersync.PoolUpdateRepository; | |
34 | import org.cardanofoundation.explorer.api.repository.ledgersync.ReserveRepository; | |
35 | import org.cardanofoundation.explorer.api.repository.ledgersync.RewardRepository; | |
36 | import org.cardanofoundation.explorer.api.repository.ledgersync.StakeAddressRepository; | |
37 | import org.cardanofoundation.explorer.api.repository.ledgersync.StakeDeRegistrationRepository; | |
38 | import org.cardanofoundation.explorer.api.repository.ledgersync.StakeRegistrationRepository; | |
39 | import org.cardanofoundation.explorer.api.repository.ledgersync.TreasuryRepository; | |
40 | import org.cardanofoundation.explorer.api.repository.ledgersync.TxRepository; | |
41 | import org.cardanofoundation.explorer.api.repository.ledgersync.WithdrawalRepository; | |
42 | import org.cardanofoundation.explorer.api.repository.ledgersyncagg.AddressRepository; | |
43 | import org.cardanofoundation.explorer.api.repository.ledgersyncagg.AddressTxAmountRepository; | |
44 | import org.cardanofoundation.explorer.api.repository.ledgersyncagg.AggregateAddressTxBalanceRepository; | |
45 | import org.cardanofoundation.explorer.api.repository.ledgersyncagg.StakeAddressBalanceRepository; | |
46 | import org.cardanofoundation.explorer.api.repository.ledgersyncagg.StakeTxBalanceRepository; | |
47 | import org.cardanofoundation.explorer.api.service.FetchRewardDataService; | |
48 | import org.cardanofoundation.explorer.api.service.StakeKeyService; | |
49 | import org.cardanofoundation.explorer.api.util.AddressUtils; | |
50 | import org.cardanofoundation.explorer.api.util.DateUtils; | |
51 | import org.cardanofoundation.explorer.common.entity.enumeration.RewardType; | |
52 | import org.cardanofoundation.explorer.common.entity.ledgersync.StakeAddress; | |
53 | import org.cardanofoundation.explorer.common.entity.ledgersync.StakeDeregistration; | |
54 | import org.cardanofoundation.explorer.common.entity.ledgersync.StakeRegistration; | |
55 | import org.cardanofoundation.explorer.common.entity.ledgersyncsagg.StakeAddressBalance; | |
56 | import org.cardanofoundation.explorer.common.exception.BusinessException; | |
57 | ||
58 | @Service | |
59 | @RequiredArgsConstructor | |
60 | @Log4j2 | |
61 | public class StakeKeyServiceImpl implements StakeKeyService { | |
62 | ||
63 | private final AddressRepository addressRepository; | |
64 | ||
65 | private final DelegationRepository delegationRepository; | |
66 | ||
67 | private final StakeRegistrationRepository stakeRegistrationRepository; | |
68 | ||
69 | private final StakeDeRegistrationRepository stakeDeRegistrationRepository; | |
70 | private final StakeAddressRepository stakeAddressRepository; | |
71 | private final RewardRepository rewardRepository; | |
72 | private final WithdrawalRepository withdrawalRepository; | |
73 | private final TreasuryRepository treasuryRepository; | |
74 | private final ReserveRepository reserveRepository; | |
75 | private final PoolUpdateRepository poolUpdateRepository; | |
76 | private final EpochRepository epochRepository; | |
77 | private final TxRepository txRepository; | |
78 | private final StakeTxBalanceRepository stakeTxBalanceRepository; | |
79 | ||
80 | private final PoolInfoRepository poolInfoRepository; | |
81 | ||
82 | private final FetchRewardDataService fetchRewardDataService; | |
83 | private final AggregateAddressTxBalanceRepository aggregateAddressTxBalanceRepository; | |
84 | private final AddressTxAmountRepository addressTxAmountRepository; | |
85 | private final StakeAddressBalanceRepository stakeAddressBalanceRepository; | |
86 | private final CardanoConverters cardanoConverters; | |
87 | ||
88 | @Override | |
89 | public BaseFilterResponse<StakeTxResponse> getDataForStakeKeyRegistration(Pageable pageable) { | |
90 | ||
91 | Page<StakeRegistration> stakeRegistrationPage = stakeRegistrationRepository.findAll(pageable); | |
92 | Page<StakeTxResponse> stakeTxResponsePage = stakeRegistrationPage.map(StakeTxResponse::new); | |
93 |
1
1. getDataForStakeKeyRegistration : removed call to org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getDetailInfoStakeTxResponse → KILLED |
getDetailInfoStakeTxResponse(stakeTxResponsePage); |
94 |
1
1. getDataForStakeKeyRegistration : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getDataForStakeKeyRegistration → KILLED |
return new BaseFilterResponse<>(stakeTxResponsePage); |
95 | } | |
96 | ||
97 | @Override | |
98 | public BaseFilterResponse<StakeTxResponse> getDataForStakeKeyDeRegistration(Pageable pageable) { | |
99 | ||
100 | Page<StakeDeregistration> stakeDeregistrationPage = | |
101 | stakeDeRegistrationRepository.findAll(pageable); | |
102 | Page<StakeTxResponse> stakeTxResponsePage = stakeDeregistrationPage.map(StakeTxResponse::new); | |
103 |
1
1. getDataForStakeKeyDeRegistration : removed call to org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getDetailInfoStakeTxResponse → KILLED |
getDetailInfoStakeTxResponse(stakeTxResponsePage); |
104 |
1
1. getDataForStakeKeyDeRegistration : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getDataForStakeKeyDeRegistration → KILLED |
return new BaseFilterResponse<>(stakeTxResponsePage); |
105 | } | |
106 | ||
107 | private void getDetailInfoStakeTxResponse(Page<StakeTxResponse> stakeTxResponsePage) { | |
108 | Set<Long> txIds = | |
109 | stakeTxResponsePage.stream().map(StakeTxResponse::getTxId).collect(Collectors.toSet()); | |
110 | List<TxIOProjection> txList = txRepository.findTxIn(txIds); | |
111 | Map<Long, TxIOProjection> txMap = | |
112 | txList.stream().collect(Collectors.toMap(TxIOProjection::getId, Function.identity())); | |
113 | ||
114 | Set<Long> stakeAddressIds = | |
115 | stakeTxResponsePage.stream() | |
116 | .map(StakeTxResponse::getStakeAddressId) | |
117 | .collect(Collectors.toSet()); | |
118 | List<StakeAddress> stakeAddressList = stakeAddressRepository.findAllById(stakeAddressIds); | |
119 | Map<Long, StakeAddress> stakeAddressMap = | |
120 | stakeAddressList.stream() | |
121 | .collect(Collectors.toMap(StakeAddress::getId, Function.identity())); | |
122 | ||
123 |
1
1. getDetailInfoStakeTxResponse : removed call to org/springframework/data/domain/Page::forEach → KILLED |
stakeTxResponsePage.forEach( |
124 | item -> { | |
125 | TxIOProjection txIOProjection = txMap.get(item.getTxId()); | |
126 | StakeAddress stakeAddress = stakeAddressMap.get(item.getStakeAddressId()); | |
127 |
1
1. lambda$getDetailInfoStakeTxResponse$0 : removed call to org/cardanofoundation/explorer/api/model/response/stake/StakeTxResponse::setTxHash → SURVIVED |
item.setTxHash(txIOProjection.getHash()); |
128 |
1
1. lambda$getDetailInfoStakeTxResponse$0 : removed call to org/cardanofoundation/explorer/api/model/response/stake/StakeTxResponse::setEpoch → KILLED |
item.setEpoch(txIOProjection.getEpochNo()); |
129 |
1
1. lambda$getDetailInfoStakeTxResponse$0 : removed call to org/cardanofoundation/explorer/api/model/response/stake/StakeTxResponse::setBlock → SURVIVED |
item.setBlock(txIOProjection.getBlockNo()); |
130 |
1
1. lambda$getDetailInfoStakeTxResponse$0 : removed call to org/cardanofoundation/explorer/api/model/response/stake/StakeTxResponse::setEpochSlotNo → SURVIVED |
item.setEpochSlotNo(txIOProjection.getEpochSlotNo()); |
131 |
1
1. lambda$getDetailInfoStakeTxResponse$0 : removed call to org/cardanofoundation/explorer/api/model/response/stake/StakeTxResponse::setTxTime → SURVIVED |
item.setTxTime(Timestamp.valueOf(txIOProjection.getTime())); |
132 |
1
1. lambda$getDetailInfoStakeTxResponse$0 : removed call to org/cardanofoundation/explorer/api/model/response/stake/StakeTxResponse::setSlotNo → SURVIVED |
item.setSlotNo(txIOProjection.getSlot()); |
133 |
1
1. lambda$getDetailInfoStakeTxResponse$0 : removed call to org/cardanofoundation/explorer/api/model/response/stake/StakeTxResponse::setStakeKey → KILLED |
item.setStakeKey(stakeAddress.getView()); |
134 | }); | |
135 | } | |
136 | ||
137 | @Override | |
138 | public StakeAddressResponse getStakeByAddress(String address) { | |
139 | try { | |
140 | String stakeAddress = AddressUtils.checkStakeAddress(address); | |
141 |
1
1. getStakeByAddress : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getStakeByAddress → KILLED |
return getStake(stakeAddress); |
142 | } catch (Exception e) { | |
143 | throw new BusinessException(BusinessCode.STAKE_ADDRESS_NOT_FOUND); | |
144 | } | |
145 | } | |
146 | ||
147 | @Override | |
148 | public StakeAddressResponse getStake(String stake) { | |
149 | StakeAddressResponse stakeAddressResponse = new StakeAddressResponse(); | |
150 | StakeAddress stakeAddress = | |
151 | stakeAddressRepository | |
152 | .findByView(stake) | |
153 |
1
1. lambda$getStake$1 : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::lambda$getStake$1 → NO_COVERAGE |
.orElseThrow(() -> new BusinessException(BusinessCode.STAKE_ADDRESS_NOT_FOUND)); |
154 | ||
155 | StakeAddressBalanceProjection stakeAddressBalanceProjection = | |
156 | stakeAddressBalanceRepository.findLatestBalanceByStakeAddress(stakeAddress.getView()); | |
157 | ||
158 | StakeAddressBalance stakeAddressBalance = | |
159 | StakeAddressBalance.builder() | |
160 | .address(stakeAddress.getView()) | |
161 | .quantity( | |
162 |
1
1. getStake : negated conditional → KILLED |
stakeAddressBalanceProjection == null |
163 | ? BigInteger.ZERO | |
164 | : stakeAddressBalanceProjection.getBalance()) | |
165 | .build(); | |
166 | ||
167 |
1
1. getStake : negated conditional → KILLED |
if (!fetchRewardDataService.checkRewardAvailable(stake)) { |
168 | boolean fetchRewardResponse = fetchRewardDataService.fetchReward(stake); | |
169 |
1
1. getStake : negated conditional → KILLED |
if (!fetchRewardResponse) { |
170 | throw new FetchRewardException(BusinessCode.FETCH_REWARD_ERROR); | |
171 | } | |
172 | } | |
173 |
1
1. getStake : removed call to org/cardanofoundation/explorer/api/model/response/address/StakeAddressResponse::setStakeAddress → KILLED |
stakeAddressResponse.setStakeAddress(stake); |
174 |
1
1. getStake : negated conditional → KILLED |
if (Boolean.TRUE.equals(fetchRewardDataService.useKoios())) { |
175 | BigInteger stakeRewardWithdrawn = | |
176 | withdrawalRepository.getRewardWithdrawnByStakeAddress(stake).orElse(BigInteger.ZERO); | |
177 | BigInteger stakeAvailableReward = | |
178 | rewardRepository.getAvailableRewardByStakeAddress(stake).orElse(BigInteger.ZERO); | |
179 |
1
1. getStake : removed call to org/cardanofoundation/explorer/api/model/response/address/StakeAddressResponse::setRewardWithdrawn → KILLED |
stakeAddressResponse.setRewardWithdrawn(stakeRewardWithdrawn); |
180 |
1
1. getStake : removed call to org/cardanofoundation/explorer/api/model/response/address/StakeAddressResponse::setRewardAvailable → KILLED |
stakeAddressResponse.setRewardAvailable(stakeAvailableReward.subtract(stakeRewardWithdrawn)); |
181 |
1
1. getStake : removed call to org/cardanofoundation/explorer/api/model/response/address/StakeAddressResponse::setTotalStake → SURVIVED |
stakeAddressResponse.setTotalStake( |
182 | stakeAddressBalance | |
183 | .getQuantity() | |
184 | .add(stakeAvailableReward) | |
185 | .subtract(stakeRewardWithdrawn)); | |
186 | } | |
187 | ||
188 |
1
1. getStake : negated conditional → KILLED |
if (stakeAddressResponse.getRewardAvailable() == null) { |
189 |
1
1. getStake : removed call to org/cardanofoundation/explorer/api/model/response/address/StakeAddressResponse::setTotalStake → KILLED |
stakeAddressResponse.setTotalStake(stakeAddressBalance.getQuantity()); |
190 | } else { | |
191 |
1
1. getStake : removed call to org/cardanofoundation/explorer/api/model/response/address/StakeAddressResponse::setTotalStake → SURVIVED |
stakeAddressResponse.setTotalStake( |
192 | stakeAddressBalance.getQuantity().add(stakeAddressResponse.getRewardAvailable())); | |
193 | } | |
194 | ||
195 | StakeDelegationProjection poolData = | |
196 | delegationRepository.findPoolDataByAddress(stakeAddress).orElse(null); | |
197 |
1
1. getStake : negated conditional → KILLED |
if (poolData != null) { |
198 | DelegationPoolResponse poolResponse = | |
199 | DelegationPoolResponse.builder() | |
200 | .poolId(poolData.getPoolId()) | |
201 | .poolName(poolData.getPoolData()) | |
202 | .tickerName(poolData.getTickerName()) | |
203 | .logoUrl(poolData.getLogoUrl()) | |
204 | .iconUrl(poolData.getIconUrl()) | |
205 | .build(); | |
206 |
1
1. getStake : removed call to org/cardanofoundation/explorer/api/model/response/address/StakeAddressResponse::setPool → SURVIVED |
stakeAddressResponse.setPool(poolResponse); |
207 | } | |
208 | Long txIdRegister = stakeRegistrationRepository.findMaxTxIdByStake(stakeAddress).orElse(0L); | |
209 | Long txIdDeregister = stakeDeRegistrationRepository.findMaxTxIdByStake(stakeAddress).orElse(0L); | |
210 |
2
1. getStake : changed conditional boundary → KILLED 2. getStake : negated conditional → KILLED |
if (txIdRegister.compareTo(txIdDeregister) > 0) { |
211 |
1
1. getStake : removed call to org/cardanofoundation/explorer/api/model/response/address/StakeAddressResponse::setStatus → NO_COVERAGE |
stakeAddressResponse.setStatus(StakeAddressStatus.ACTIVE); |
212 | } else { | |
213 |
1
1. getStake : removed call to org/cardanofoundation/explorer/api/model/response/address/StakeAddressResponse::setStatus → KILLED |
stakeAddressResponse.setStatus(StakeAddressStatus.DEACTIVATED); |
214 | } | |
215 |
1
1. getStake : removed call to org/cardanofoundation/explorer/api/model/response/address/StakeAddressResponse::setRewardPools → SURVIVED |
stakeAddressResponse.setRewardPools(poolUpdateRepository.findPoolByRewardAccount(stakeAddress)); |
216 |
1
1. getStake : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getStake → KILLED |
return stakeAddressResponse; |
217 | } | |
218 | ||
219 | @Override | |
220 | public BaseFilterResponse<StakeDelegationProjection> getDelegationHistories( | |
221 | String stakeKey, Pageable pageable) { | |
222 | Page<StakeDelegationProjection> delegations = | |
223 | delegationRepository.findDelegationByAddress(stakeKey, pageable); | |
224 |
1
1. getDelegationHistories : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getDelegationHistories → KILLED |
return new BaseFilterResponse<>(delegations); |
225 | } | |
226 | ||
227 | @Override | |
228 | public BaseFilterResponse<StakeHistoryProjection> getStakeHistories( | |
229 | String stakeKey, Pageable pageable) { | |
230 | StakeAddress stakeAddress = | |
231 | stakeAddressRepository | |
232 | .findByView(stakeKey) | |
233 |
1
1. lambda$getStakeHistories$2 : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::lambda$getStakeHistories$2 → KILLED |
.orElseThrow(() -> new NoContentException(BusinessCode.STAKE_ADDRESS_NOT_FOUND)); |
234 | List<StakeHistoryProjection> stakeHistoryList = | |
235 | stakeRegistrationRepository.getStakeRegistrationsByAddress(stakeAddress); | |
236 | stakeHistoryList.addAll( | |
237 | stakeDeRegistrationRepository.getStakeDeRegistrationsByAddress(stakeAddress)); | |
238 |
1
1. getStakeHistories : removed call to java/util/List::sort → KILLED |
stakeHistoryList.sort( |
239 | (o1, o2) -> { | |
240 |
1
1. lambda$getStakeHistories$3 : negated conditional → SURVIVED |
if (o1.getBlockNo().equals(o2.getBlockNo())) { |
241 |
2
1. lambda$getStakeHistories$3 : replaced int return with 0 for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::lambda$getStakeHistories$3 → NO_COVERAGE 2. lambda$getStakeHistories$3 : Replaced integer subtraction with addition → NO_COVERAGE |
return o2.getBlockIndex() - o1.getBlockIndex(); |
242 | } else { | |
243 |
1
1. lambda$getStakeHistories$3 : replaced int return with 0 for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::lambda$getStakeHistories$3 → KILLED |
return o2.getBlockNo().compareTo(o1.getBlockNo()); |
244 | } | |
245 | }); | |
246 | final int start = (int) pageable.getOffset(); | |
247 |
1
1. getStakeHistories : Replaced integer addition with subtraction → KILLED |
final int end = Math.min((start + pageable.getPageSize()), stakeHistoryList.size()); |
248 |
2
1. getStakeHistories : changed conditional boundary → SURVIVED 2. getStakeHistories : negated conditional → KILLED |
if (start >= stakeHistoryList.size()) { |
249 |
1
1. getStakeHistories : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getStakeHistories → NO_COVERAGE |
return new BaseFilterResponse<>(new PageImpl<>(List.of())); |
250 | } | |
251 | Page<StakeHistoryProjection> page = | |
252 | new PageImpl<>(stakeHistoryList.subList(start, end), pageable, stakeHistoryList.size()); | |
253 |
1
1. getStakeHistories : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getStakeHistories → KILLED |
return new BaseFilterResponse<>(page); |
254 | } | |
255 | ||
256 | @Override | |
257 | public BaseFilterResponse<StakeWithdrawalProjection> getWithdrawalHistories( | |
258 | String stakeKey, Pageable pageable) { | |
259 | Page<StakeWithdrawalProjection> withdrawalHistories = | |
260 | withdrawalRepository.getWithdrawalByAddress(stakeKey, pageable); | |
261 | ||
262 |
2
1. getWithdrawalHistories : negated conditional → NO_COVERAGE 2. getWithdrawalHistories : negated conditional → KILLED |
if (withdrawalHistories.isEmpty() && Boolean.FALSE.equals(fetchRewardDataService.useKoios())) { |
263 |
1
1. getWithdrawalHistories : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getWithdrawalHistories → NO_COVERAGE |
return new BaseFilterResponse<>(); |
264 | } | |
265 | ||
266 |
1
1. getWithdrawalHistories : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getWithdrawalHistories → KILLED |
return new BaseFilterResponse<>(withdrawalHistories); |
267 | } | |
268 | ||
269 | @Override | |
270 | public BaseFilterResponse<StakeInstantaneousRewardsProjection> getInstantaneousRewards( | |
271 | String stakeKey, Pageable pageable) { | |
272 | List<StakeInstantaneousRewardsProjection> instantaneousRewards = | |
273 | treasuryRepository.getTreasuryByAddress(stakeKey); | |
274 | instantaneousRewards.addAll(reserveRepository.getReserveByAddress(stakeKey)); | |
275 |
1
1. getInstantaneousRewards : removed call to java/util/List::sort → KILLED |
instantaneousRewards.sort( |
276 | (o1, o2) -> { | |
277 |
1
1. lambda$getInstantaneousRewards$4 : negated conditional → SURVIVED |
if (o1.getBlockNo().equals(o2.getBlockNo())) { |
278 |
2
1. lambda$getInstantaneousRewards$4 : Replaced integer subtraction with addition → NO_COVERAGE 2. lambda$getInstantaneousRewards$4 : replaced int return with 0 for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::lambda$getInstantaneousRewards$4 → NO_COVERAGE |
return o2.getBlockIndex() - o1.getBlockIndex(); |
279 | } else { | |
280 |
1
1. lambda$getInstantaneousRewards$4 : replaced int return with 0 for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::lambda$getInstantaneousRewards$4 → KILLED |
return o2.getBlockNo().compareTo(o1.getBlockNo()); |
281 | } | |
282 | }); | |
283 | final int start = (int) pageable.getOffset(); | |
284 |
1
1. getInstantaneousRewards : Replaced integer addition with subtraction → KILLED |
final int end = Math.min((start + pageable.getPageSize()), instantaneousRewards.size()); |
285 |
2
1. getInstantaneousRewards : changed conditional boundary → SURVIVED 2. getInstantaneousRewards : negated conditional → KILLED |
if (start >= instantaneousRewards.size()) { |
286 |
1
1. getInstantaneousRewards : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getInstantaneousRewards → NO_COVERAGE |
return new BaseFilterResponse<>(new PageImpl<>(List.of())); |
287 | } | |
288 | Page<StakeInstantaneousRewardsProjection> page = | |
289 | new PageImpl<>( | |
290 | instantaneousRewards.subList(start, end), pageable, instantaneousRewards.size()); | |
291 |
1
1. getInstantaneousRewards : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getInstantaneousRewards → KILLED |
return new BaseFilterResponse<>(page); |
292 | } | |
293 | ||
294 | @Override | |
295 | public BaseFilterResponse<AddressFilterResponse> getAddresses( | |
296 | String stakeKey, Pageable pageable) { | |
297 | Page<AddressFilterResponse> responsePage = | |
298 | addressRepository | |
299 | .findByStakeAddress(stakeKey, pageable) | |
300 | .map( | |
301 | addressResponse -> { | |
302 | AddressFilterResponse response = new AddressFilterResponse(); | |
303 |
1
1. lambda$getAddresses$5 : removed call to org/cardanofoundation/explorer/api/model/response/address/AddressFilterResponse::setAddress → KILLED |
response.setAddress(addressResponse.getAddress()); |
304 |
1
1. lambda$getAddresses$5 : removed call to org/cardanofoundation/explorer/api/model/response/address/AddressFilterResponse::setBalance → KILLED |
response.setBalance(addressResponse.getBalance()); |
305 |
1
1. lambda$getAddresses$5 : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::lambda$getAddresses$5 → KILLED |
return response; |
306 | }); | |
307 | ||
308 |
1
1. getAddresses : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getAddresses → KILLED |
return new BaseFilterResponse<>(responsePage); |
309 | } | |
310 | ||
311 | @Override | |
312 | public StakeAnalyticResponse getStakeAnalytics() { | |
313 | StakeAnalyticResponse response = new StakeAnalyticResponse(); | |
314 | Integer currentEpoch = epochRepository.findCurrentEpochNo().orElse(0); | |
315 | Boolean useKoios = fetchRewardDataService.useKoios(); | |
316 | BigInteger activeStake = null; | |
317 | BigInteger liveStake = null; | |
318 |
1
1. getStakeAnalytics : negated conditional → KILLED |
if (Boolean.TRUE.equals(useKoios)) { |
319 | activeStake = poolInfoRepository.getTotalActiveStake(currentEpoch); | |
320 | liveStake = poolInfoRepository.getTotalLiveStake(currentEpoch); | |
321 | } | |
322 |
1
1. getStakeAnalytics : removed call to org/cardanofoundation/explorer/api/model/response/StakeAnalyticResponse::setActiveStake → KILLED |
response.setActiveStake(activeStake); |
323 |
1
1. getStakeAnalytics : removed call to org/cardanofoundation/explorer/api/model/response/StakeAnalyticResponse::setLiveStake → KILLED |
response.setLiveStake(liveStake); |
324 |
1
1. getStakeAnalytics : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getStakeAnalytics → KILLED |
return response; |
325 | } | |
326 | ||
327 | @Override | |
328 | public AddressChartBalanceResponse getStakeBalanceAnalytics(String stakeKey, AnalyticType type) { | |
329 | StakeAddress addr = | |
330 | stakeAddressRepository | |
331 | .findByView(stakeKey) | |
332 |
1
1. lambda$getStakeBalanceAnalytics$6 : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::lambda$getStakeBalanceAnalytics$6 → NO_COVERAGE |
.orElseThrow(() -> new NoContentException(BusinessCode.STAKE_ADDRESS_NOT_FOUND)); |
333 | ||
334 | List<LocalDateTime> dates = DateUtils.getListDateAnalytic(type); | |
335 | AddressChartBalanceResponse response = new AddressChartBalanceResponse(); | |
336 | List<AddressChartBalanceData> data = new ArrayList<>(); | |
337 | ||
338 |
1
1. getStakeBalanceAnalytics : negated conditional → KILLED |
if (AnalyticType.ONE_DAY.equals(type)) { |
339 | var fromBalance = | |
340 | addressTxAmountRepository | |
341 | .sumBalanceByStakeAddressAndSlotBefore( | |
342 | addr.getView(), cardanoConverters.time().toSlot(dates.get(0))) | |
343 | .orElse(BigInteger.ZERO); | |
344 | ||
345 |
1
1. getStakeBalanceAnalytics : removed call to org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getHighestAndLowestBalance → KILLED |
getHighestAndLowestBalance(addr, fromBalance, dates, response); |
346 | // init data for chart | |
347 | data.add(new AddressChartBalanceData(dates.get(0), fromBalance)); | |
348 |
2
1. getStakeBalanceAnalytics : negated conditional → KILLED 2. getStakeBalanceAnalytics : changed conditional boundary → KILLED |
for (int i = 1; i < dates.size(); i++) { |
349 | Optional<BigInteger> balance = | |
350 | addressTxAmountRepository.getBalanceByStakeAddressAndSlotBetween( | |
351 | addr.getView(), | |
352 |
1
1. getStakeBalanceAnalytics : Replaced integer subtraction with addition → KILLED |
cardanoConverters.time().toSlot(dates.get((i - 1))), |
353 | cardanoConverters.time().toSlot(dates.get(i))); | |
354 |
1
1. getStakeBalanceAnalytics : negated conditional → KILLED |
if (balance.isPresent()) { |
355 | fromBalance = fromBalance.add(balance.get()); | |
356 | } | |
357 | data.add(new AddressChartBalanceData(dates.get(i), fromBalance)); | |
358 | } | |
359 |
1
1. getStakeBalanceAnalytics : removed call to org/cardanofoundation/explorer/api/model/response/address/AddressChartBalanceResponse::setData → SURVIVED |
response.setData(data); |
360 | } else { | |
361 | // Remove last date because we will get data of today | |
362 | dates.remove(0); | |
363 | var fromBalance = | |
364 | addressTxAmountRepository | |
365 | .sumBalanceByStakeAddressAndSlotBefore( | |
366 | addr.getView(), cardanoConverters.time().toSlot(dates.get(0))) | |
367 | .orElse(BigInteger.ZERO); | |
368 |
1
1. getStakeBalanceAnalytics : removed call to org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getHighestAndLowestBalance → KILLED |
getHighestAndLowestBalance(addr, fromBalance, dates, response); |
369 | List<AggregateAddressBalanceProjection> aggregateAddressTxBalances = | |
370 | aggregateAddressTxBalanceRepository.findAllByStakeAddressIdAndDayBetween( | |
371 | addr.getView(), | |
372 | dates.get(0).toLocalDate(), | |
373 |
1
1. getStakeBalanceAnalytics : Replaced integer subtraction with addition → KILLED |
dates.get(dates.size() - 1).toLocalDate()); |
374 | // Data in aggregate_address_tx_balance save at end of day, but we will display start of day | |
375 | // So we need to add 1 day to display correct data | |
376 | Map<LocalDate, BigInteger> mapBalance = | |
377 | aggregateAddressTxBalances.stream() | |
378 | .collect( | |
379 | Collectors.toMap( | |
380 |
1
1. lambda$getStakeBalanceAnalytics$7 : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::lambda$getStakeBalanceAnalytics$7 → SURVIVED |
balance -> balance.getDay().plusDays(1), |
381 | AggregateAddressBalanceProjection::getBalance)); | |
382 | for (LocalDateTime date : dates) { | |
383 |
1
1. getStakeBalanceAnalytics : negated conditional → KILLED |
if (mapBalance.containsKey(date.toLocalDate())) { |
384 | fromBalance = fromBalance.add(mapBalance.get(date.toLocalDate())); | |
385 | } | |
386 | data.add(new AddressChartBalanceData(date, fromBalance)); | |
387 | } | |
388 |
1
1. getStakeBalanceAnalytics : removed call to org/cardanofoundation/explorer/api/model/response/address/AddressChartBalanceResponse::setData → SURVIVED |
response.setData(data); |
389 | } | |
390 |
1
1. getStakeBalanceAnalytics : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getStakeBalanceAnalytics → KILLED |
return response; |
391 | } | |
392 | ||
393 | /** | |
394 | * Get highest and lowest balance of stake address | |
395 | * | |
396 | * @param addr stake address | |
397 | * @param fromBalance balance of stake address at start date | |
398 | * @param dates list date | |
399 | * @param response chart response | |
400 | */ | |
401 | private void getHighestAndLowestBalance( | |
402 | StakeAddress addr, | |
403 | BigInteger fromBalance, | |
404 | List<LocalDateTime> dates, | |
405 | AddressChartBalanceResponse response) { | |
406 | var minMaxBalance = | |
407 | stakeTxBalanceRepository.findMinMaxBalanceByStakeAddress( | |
408 | addr.getView(), | |
409 | fromBalance, | |
410 | cardanoConverters.time().toSlot(dates.get(0)), | |
411 |
1
1. getHighestAndLowestBalance : Replaced integer subtraction with addition → KILLED |
cardanoConverters.time().toSlot(dates.get(dates.size() - 1))); |
412 |
2
1. getHighestAndLowestBalance : changed conditional boundary → SURVIVED 2. getHighestAndLowestBalance : negated conditional → SURVIVED |
if (minMaxBalance.getMaxVal().compareTo(fromBalance) > 0) { |
413 |
1
1. getHighestAndLowestBalance : removed call to org/cardanofoundation/explorer/api/model/response/address/AddressChartBalanceResponse::setHighestBalance → SURVIVED |
response.setHighestBalance(minMaxBalance.getMaxVal()); |
414 | } else { | |
415 |
1
1. getHighestAndLowestBalance : removed call to org/cardanofoundation/explorer/api/model/response/address/AddressChartBalanceResponse::setHighestBalance → NO_COVERAGE |
response.setHighestBalance(fromBalance); |
416 | } | |
417 |
2
1. getHighestAndLowestBalance : changed conditional boundary → SURVIVED 2. getHighestAndLowestBalance : negated conditional → KILLED |
if (minMaxBalance.getMinVal().compareTo(fromBalance) < 0) { |
418 |
1
1. getHighestAndLowestBalance : removed call to org/cardanofoundation/explorer/api/model/response/address/AddressChartBalanceResponse::setLowestBalance → NO_COVERAGE |
response.setLowestBalance(minMaxBalance.getMinVal()); |
419 | } else { | |
420 |
1
1. getHighestAndLowestBalance : removed call to org/cardanofoundation/explorer/api/model/response/address/AddressChartBalanceResponse::setLowestBalance → KILLED |
response.setLowestBalance(fromBalance); |
421 | } | |
422 | Long targetSlot = | |
423 | stakeTxBalanceRepository.findMaxSlotByStakeAddress(addr.getView()).orElse(Long.MAX_VALUE); | |
424 | ||
425 |
1
1. getHighestAndLowestBalance : negated conditional → SURVIVED |
if (!targetSlot.equals(Long.MAX_VALUE)) { |
426 | List<StakeTxProjection> stakeTxList = | |
427 | addressTxAmountRepository.findTxAndAmountByStakeAndSlotAfter(addr.getView(), targetSlot); | |
428 | for (StakeTxProjection stakeTx : stakeTxList) { | |
429 | if (response | |
430 | .getHighestBalance() | |
431 | .add(stakeTx.getAmount()) | |
432 |
2
1. getHighestAndLowestBalance : negated conditional → NO_COVERAGE 2. getHighestAndLowestBalance : changed conditional boundary → NO_COVERAGE |
.compareTo(response.getHighestBalance()) |
433 | > 0) { | |
434 |
1
1. getHighestAndLowestBalance : removed call to org/cardanofoundation/explorer/api/model/response/address/AddressChartBalanceResponse::setHighestBalance → NO_COVERAGE |
response.setHighestBalance(response.getHighestBalance().add(stakeTx.getAmount())); |
435 | } | |
436 | if (response | |
437 | .getLowestBalance() | |
438 | .add(stakeTx.getAmount()) | |
439 |
2
1. getHighestAndLowestBalance : negated conditional → NO_COVERAGE 2. getHighestAndLowestBalance : changed conditional boundary → NO_COVERAGE |
.compareTo(response.getLowestBalance()) |
440 | < 0) { | |
441 |
1
1. getHighestAndLowestBalance : removed call to org/cardanofoundation/explorer/api/model/response/address/AddressChartBalanceResponse::setLowestBalance → NO_COVERAGE |
response.setLowestBalance(response.getLowestBalance().add(stakeTx.getAmount())); |
442 | } | |
443 | } | |
444 | } | |
445 | } | |
446 | ||
447 | @Override | |
448 | public List<StakeAnalyticRewardResponse> getStakeRewardAnalytics(String stakeKey) { | |
449 |
1
1. getStakeRewardAnalytics : negated conditional → KILLED |
if (Boolean.FALSE.equals(fetchRewardDataService.useKoios())) { |
450 |
1
1. getStakeRewardAnalytics : replaced return value with Collections.emptyList for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getStakeRewardAnalytics → KILLED |
return null; |
451 | } | |
452 | ||
453 |
1
1. getStakeRewardAnalytics : negated conditional → KILLED |
if (!fetchRewardDataService.checkRewardAvailable(stakeKey)) { |
454 | boolean fetchRewardResponse = fetchRewardDataService.fetchReward(stakeKey); | |
455 |
1
1. getStakeRewardAnalytics : negated conditional → KILLED |
if (!fetchRewardResponse) { |
456 | throw new FetchRewardException(BusinessCode.FETCH_REWARD_ERROR); | |
457 | } | |
458 | } | |
459 | List<StakeAnalyticRewardResponse> responses = rewardRepository.findRewardByStake(stakeKey); | |
460 | Map<Integer, BigInteger> rewardMap = | |
461 | responses.stream() | |
462 | .collect( | |
463 | Collectors.toMap( | |
464 | StakeAnalyticRewardResponse::getEpoch, StakeAnalyticRewardResponse::getValue)); | |
465 | responses = new ArrayList<>(); | |
466 |
1
1. lambda$getStakeRewardAnalytics$8 : replaced int return with 0 for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::lambda$getStakeRewardAnalytics$8 → NO_COVERAGE |
int startEpoch = rewardMap.keySet().stream().mapToInt(v -> v).min().orElse(0); |
467 |
1
1. getStakeRewardAnalytics : Replaced integer subtraction with addition → NO_COVERAGE |
int currentEpoch = epochRepository.findCurrentEpochNo().orElse(2) - 2; |
468 |
2
1. getStakeRewardAnalytics : negated conditional → NO_COVERAGE 2. getStakeRewardAnalytics : changed conditional boundary → NO_COVERAGE |
for (int epoch = startEpoch; epoch <= currentEpoch; epoch++) { |
469 | StakeAnalyticRewardResponse response; | |
470 | response = | |
471 | new StakeAnalyticRewardResponse(epoch, rewardMap.getOrDefault(epoch, BigInteger.ZERO)); | |
472 | responses.add(response); | |
473 | } | |
474 |
1
1. getStakeRewardAnalytics : replaced return value with Collections.emptyList for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getStakeRewardAnalytics → NO_COVERAGE |
return responses; |
475 | } | |
476 | ||
477 | @Override | |
478 | public StakeAddressRewardDistribution getStakeAddressRewardDistributionInfo(String stakeKey) { | |
479 | StakeAddressRewardDistribution stakeAddressRewardDistribution = | |
480 | new StakeAddressRewardDistribution(); | |
481 |
1
1. getStakeAddressRewardDistributionInfo : removed call to org/cardanofoundation/explorer/api/model/response/address/StakeAddressRewardDistribution::setStakeAddress → KILLED |
stakeAddressRewardDistribution.setStakeAddress(stakeKey); |
482 |
1
1. getStakeAddressRewardDistributionInfo : negated conditional → KILLED |
if (Boolean.FALSE.equals(fetchRewardDataService.useKoios())) { |
483 |
1
1. getStakeAddressRewardDistributionInfo : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getStakeAddressRewardDistributionInfo → KILLED |
return stakeAddressRewardDistribution; |
484 | } | |
485 | ||
486 |
1
1. getStakeAddressRewardDistributionInfo : negated conditional → KILLED |
if (!fetchRewardDataService.checkRewardAvailable(stakeKey)) { |
487 | boolean fetchRewardResponse = fetchRewardDataService.fetchReward(stakeKey); | |
488 |
1
1. getStakeAddressRewardDistributionInfo : negated conditional → KILLED |
if (!fetchRewardResponse) { |
489 | throw new FetchRewardException(BusinessCode.FETCH_REWARD_ERROR); | |
490 | } | |
491 | } | |
492 | BigInteger stakeAvailableReward = | |
493 | rewardRepository.getAvailableRewardByStakeAddress(stakeKey).orElse(BigInteger.ZERO); | |
494 |
1
1. getStakeAddressRewardDistributionInfo : removed call to org/cardanofoundation/explorer/api/model/response/address/StakeAddressRewardDistribution::setRewardAvailable → KILLED |
stakeAddressRewardDistribution.setRewardAvailable(stakeAvailableReward); |
495 | Set<RewardType> rewardTypeOfStakeKey = rewardRepository.getAllRewardTypeOfAStakeKey(stakeKey); | |
496 |
1
1. getStakeAddressRewardDistributionInfo : negated conditional → KILLED |
if (rewardTypeOfStakeKey.contains(RewardType.MEMBER)) { |
497 |
1
1. getStakeAddressRewardDistributionInfo : removed call to org/cardanofoundation/explorer/api/model/response/address/StakeAddressRewardDistribution::setHasMemberReward → KILLED |
stakeAddressRewardDistribution.setHasMemberReward(true); |
498 | } | |
499 |
1
1. getStakeAddressRewardDistributionInfo : negated conditional → KILLED |
if (rewardTypeOfStakeKey.contains(RewardType.LEADER)) { |
500 |
1
1. getStakeAddressRewardDistributionInfo : removed call to org/cardanofoundation/explorer/api/model/response/address/StakeAddressRewardDistribution::setHasLeaderReward → NO_COVERAGE |
stakeAddressRewardDistribution.setHasLeaderReward(true); |
501 | } | |
502 |
1
1. getStakeAddressRewardDistributionInfo : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/StakeKeyServiceImpl::getStakeAddressRewardDistributionInfo → KILLED |
return stakeAddressRewardDistribution; |
503 | } | |
504 | } | |
Mutations | ||
93 |
1.1 |
|
94 |
1.1 |
|
103 |
1.1 |
|
104 |
1.1 |
|
123 |
1.1 |
|
127 |
1.1 |
|
128 |
1.1 |
|
129 |
1.1 |
|
130 |
1.1 |
|
131 |
1.1 |
|
132 |
1.1 |
|
133 |
1.1 |
|
141 |
1.1 |
|
153 |
1.1 |
|
162 |
1.1 |
|
167 |
1.1 |
|
169 |
1.1 |
|
173 |
1.1 |
|
174 |
1.1 |
|
179 |
1.1 |
|
180 |
1.1 |
|
181 |
1.1 |
|
188 |
1.1 |
|
189 |
1.1 |
|
191 |
1.1 |
|
197 |
1.1 |
|
206 |
1.1 |
|
210 |
1.1 2.2 |
|
211 |
1.1 |
|
213 |
1.1 |
|
215 |
1.1 |
|
216 |
1.1 |
|
224 |
1.1 |
|
233 |
1.1 |
|
238 |
1.1 |
|
240 |
1.1 |
|
241 |
1.1 2.2 |
|
243 |
1.1 |
|
247 |
1.1 |
|
248 |
1.1 2.2 |
|
249 |
1.1 |
|
253 |
1.1 |
|
262 |
1.1 2.2 |
|
263 |
1.1 |
|
266 |
1.1 |
|
275 |
1.1 |
|
277 |
1.1 |
|
278 |
1.1 2.2 |
|
280 |
1.1 |
|
284 |
1.1 |
|
285 |
1.1 2.2 |
|
286 |
1.1 |
|
291 |
1.1 |
|
303 |
1.1 |
|
304 |
1.1 |
|
305 |
1.1 |
|
308 |
1.1 |
|
318 |
1.1 |
|
322 |
1.1 |
|
323 |
1.1 |
|
324 |
1.1 |
|
332 |
1.1 |
|
338 |
1.1 |
|
345 |
1.1 |
|
348 |
1.1 2.2 |
|
352 |
1.1 |
|
354 |
1.1 |
|
359 |
1.1 |
|
368 |
1.1 |
|
373 |
1.1 |
|
380 |
1.1 |
|
383 |
1.1 |
|
388 |
1.1 |
|
390 |
1.1 |
|
411 |
1.1 |
|
412 |
1.1 2.2 |
|
413 |
1.1 |
|
415 |
1.1 |
|
417 |
1.1 2.2 |
|
418 |
1.1 |
|
420 |
1.1 |
|
425 |
1.1 |
|
432 |
1.1 2.2 |
|
434 |
1.1 |
|
439 |
1.1 2.2 |
|
441 |
1.1 |
|
449 |
1.1 |
|
450 |
1.1 |
|
453 |
1.1 |
|
455 |
1.1 |
|
466 |
1.1 |
|
467 |
1.1 |
|
468 |
1.1 2.2 |
|
474 |
1.1 |
|
481 |
1.1 |
|
482 |
1.1 |
|
483 |
1.1 |
|
486 |
1.1 |
|
488 |
1.1 |
|
494 |
1.1 |
|
496 |
1.1 |
|
497 |
1.1 |
|
499 |
1.1 |
|
500 |
1.1 |
|
502 |
1.1 |