1 | package org.cardanofoundation.explorer.api.service.impl; | |
2 | ||
3 | import java.math.BigInteger; | |
4 | import java.util.ArrayList; | |
5 | import java.util.List; | |
6 | import java.util.Map; | |
7 | import java.util.Objects; | |
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.*; | |
15 | import org.springframework.data.domain.Sort.Direction; | |
16 | import org.springframework.stereotype.Service; | |
17 | ||
18 | import org.apache.commons.lang3.StringUtils; | |
19 | ||
20 | import org.cardanofoundation.explorer.api.common.enumeration.BlockPropagationChartType; | |
21 | import org.cardanofoundation.explorer.api.exception.BusinessCode; | |
22 | import org.cardanofoundation.explorer.api.exception.NoContentException; | |
23 | import org.cardanofoundation.explorer.api.mapper.BlockMapper; | |
24 | import org.cardanofoundation.explorer.api.mapper.BlockPropagationMapper; | |
25 | import org.cardanofoundation.explorer.api.model.response.BaseFilterResponse; | |
26 | import org.cardanofoundation.explorer.api.model.response.BlockFilterResponse; | |
27 | import org.cardanofoundation.explorer.api.model.response.BlockPropagationResponse; | |
28 | import org.cardanofoundation.explorer.api.model.response.BlockResponse; | |
29 | import org.cardanofoundation.explorer.api.projection.PoolMintBlockProjection; | |
30 | import org.cardanofoundation.explorer.api.repository.explorer.BlockStatisticsDailyRepository; | |
31 | import org.cardanofoundation.explorer.api.repository.explorer.BlockStatisticsPerEpochRepository; | |
32 | import org.cardanofoundation.explorer.api.repository.ledgersync.BlockRepository; | |
33 | import org.cardanofoundation.explorer.api.repository.ledgersync.CustomBlockRepository; | |
34 | import org.cardanofoundation.explorer.api.repository.ledgersync.SlotLeaderRepository; | |
35 | import org.cardanofoundation.explorer.api.repository.ledgersync.TxRepository; | |
36 | import org.cardanofoundation.explorer.api.service.BlockService; | |
37 | import org.cardanofoundation.explorer.common.entity.ledgersync.BaseEntity; | |
38 | import org.cardanofoundation.explorer.common.entity.ledgersync.BaseEntity_; | |
39 | import org.cardanofoundation.explorer.common.entity.ledgersync.Block; | |
40 | import org.cardanofoundation.explorer.common.entity.ledgersync.Block_; | |
41 | import org.cardanofoundation.explorer.common.entity.ledgersync.SlotLeader; | |
42 | import org.cardanofoundation.explorer.common.entity.ledgersync.Tx; | |
43 | import org.cardanofoundation.explorer.common.exception.BusinessException; | |
44 | ||
45 | @Service | |
46 | @RequiredArgsConstructor | |
47 | @Log4j2 | |
48 | public class BlockServiceImpl implements BlockService { | |
49 | ||
50 | private final BlockRepository blockRepository; | |
51 | private final TxRepository txRepository; | |
52 | private final SlotLeaderRepository slotLeaderRepository; | |
53 | private final BlockMapper blockMapper; | |
54 | private final CustomBlockRepository customBlockRepository; | |
55 | private final BlockStatisticsPerEpochRepository blockStatisticsPerEpochRepository; | |
56 | private final BlockStatisticsDailyRepository blockStatisticsDailyRepository; | |
57 | private final BlockPropagationMapper blockPropagationMapper; | |
58 | ||
59 | @Override | |
60 | public BlockResponse getBlockDetailByBlockId(String blockId) { | |
61 | try { | |
62 | Long blockNo = Long.parseLong(blockId); | |
63 | Block block = | |
64 | blockRepository | |
65 | .findFirstByBlockNo(blockNo) | |
66 |
1
1. lambda$getBlockDetailByBlockId$0 : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::lambda$getBlockDetailByBlockId$0 → KILLED |
.orElseThrow(() -> new BusinessException(BusinessCode.BLOCK_NOT_FOUND)); |
67 |
1
1. getBlockDetailByBlockId : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::getBlockDetailByBlockId → KILLED |
return getBlockResponse(block); |
68 | } catch (NumberFormatException e) { | |
69 | Block block = | |
70 | blockRepository | |
71 | .findFirstByHash(blockId) | |
72 |
1
1. lambda$getBlockDetailByBlockId$1 : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::lambda$getBlockDetailByBlockId$1 → KILLED |
.orElseThrow(() -> new BusinessException(BusinessCode.BLOCK_NOT_FOUND)); |
73 |
1
1. getBlockDetailByBlockId : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::getBlockDetailByBlockId → KILLED |
return getBlockResponse(block); |
74 | } | |
75 | } | |
76 | ||
77 | /** | |
78 | * Get block response from entity, calculate totalOutputs and total fees | |
79 | * | |
80 | * @param block block entity | |
81 | * @return block response | |
82 | */ | |
83 | private BlockResponse getBlockResponse(Block block) { | |
84 | BlockResponse blockResponse = blockMapper.blockToBlockResponse(block); | |
85 | List<Tx> txList = txRepository.findAllByBlock(block); | |
86 | PoolMintBlockProjection poolMintBlockProjection = | |
87 | blockRepository.getPoolInfoThatMintedBlock(block.getBlockNo()); | |
88 |
1
1. getBlockResponse : removed call to org/cardanofoundation/explorer/api/model/response/BlockResponse::setTotalOutput → SURVIVED |
blockResponse.setTotalOutput( |
89 | txList.stream().map(Tx::getOutSum).reduce(BigInteger.ZERO, BigInteger::add)); | |
90 |
1
1. getBlockResponse : removed call to org/cardanofoundation/explorer/api/model/response/BlockResponse::setTotalFees → SURVIVED |
blockResponse.setTotalFees( |
91 | txList.stream().map(Tx::getFee).reduce(BigInteger.ZERO, BigInteger::add)); | |
92 | ||
93 |
1
1. getBlockResponse : negated conditional → KILLED |
if (!Objects.isNull(poolMintBlockProjection)) { |
94 |
1
1. getBlockResponse : removed call to org/cardanofoundation/explorer/api/model/response/BlockResponse::setPoolName → SURVIVED |
blockResponse.setPoolName(poolMintBlockProjection.getPoolName()); |
95 |
1
1. getBlockResponse : removed call to org/cardanofoundation/explorer/api/model/response/BlockResponse::setPoolView → KILLED |
blockResponse.setPoolView(poolMintBlockProjection.getPoolView()); |
96 |
1
1. getBlockResponse : removed call to org/cardanofoundation/explorer/api/model/response/BlockResponse::setPoolTicker → SURVIVED |
blockResponse.setPoolTicker(poolMintBlockProjection.getPoolTicker()); |
97 |
1
1. getBlockResponse : removed call to org/cardanofoundation/explorer/api/model/response/BlockResponse::setDescription → SURVIVED |
blockResponse.setDescription(poolMintBlockProjection.getDescription()); |
98 | } | |
99 | ||
100 | Integer currentBlockNo = | |
101 | blockRepository | |
102 | .findCurrentBlock() | |
103 |
1
1. lambda$getBlockResponse$2 : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::lambda$getBlockResponse$2 → KILLED |
.orElseThrow(() -> new BusinessException(BusinessCode.BLOCK_NOT_FOUND)); |
104 |
1
1. getBlockResponse : negated conditional → KILLED |
if (Objects.nonNull(block.getBlockNo())) { |
105 |
2
1. getBlockResponse : Replaced integer subtraction with addition → SURVIVED 2. getBlockResponse : removed call to org/cardanofoundation/explorer/api/model/response/BlockResponse::setConfirmation → SURVIVED |
blockResponse.setConfirmation(currentBlockNo - block.getBlockNo().intValue()); |
106 | } | |
107 |
1
1. getBlockResponse : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::getBlockResponse → KILLED |
return blockResponse; |
108 | } | |
109 | ||
110 | @Override | |
111 | public BaseFilterResponse<BlockFilterResponse> filterBlock(Pageable pageable) { | |
112 | long totalElements = blockRepository.countAllBlock(); | |
113 | Direction direction = null; | |
114 | String sortField = null; | |
115 |
1
1. filterBlock : negated conditional → KILLED |
if (pageable.getSort().isSorted()) { |
116 | direction = pageable.getSort().stream().findFirst().get().getDirection(); | |
117 | sortField = pageable.getSort().stream().findFirst().get().getProperty(); | |
118 | } | |
119 | Page<Block> blockPage; | |
120 | ||
121 |
2
1. filterBlock : negated conditional → KILLED 2. filterBlock : negated conditional → KILLED |
boolean sortFieldFlag = Block_.TIME.equals(sortField) || BaseEntity_.ID.equals(sortField); |
122 |
2
1. filterBlock : negated conditional → SURVIVED 2. filterBlock : negated conditional → NO_COVERAGE |
if (Direction.ASC.equals(direction) && Boolean.TRUE.equals(sortFieldFlag)) { |
123 | blockPage = getBlockFilterListByTimeAsc(pageable, totalElements); | |
124 |
2
1. filterBlock : negated conditional → SURVIVED 2. filterBlock : negated conditional → KILLED |
} else if ((Direction.DESC.equals(direction) && Boolean.TRUE.equals(sortFieldFlag)) |
125 |
1
1. filterBlock : negated conditional → KILLED |
|| Objects.isNull(direction) |
126 |
1
1. filterBlock : negated conditional → KILLED |
|| StringUtils.isEmpty(sortField)) { |
127 | blockPage = getBlockFilterListByTimeDesc(pageable, totalElements); | |
128 | } else { | |
129 | blockPage = blockRepository.findAllBlock(pageable); | |
130 | } | |
131 |
1
1. filterBlock : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::filterBlock → KILLED |
return mapperBlockToBlockFilterResponse(blockPage, false); |
132 | } | |
133 | ||
134 | /** | |
135 | * Get block filter response order by time|id asc. Main idea: Find the first block id by page and | |
136 | * genesis|ebb block count. Then find the block list by first block id and limit. | |
137 | * | |
138 | * @param pageable | |
139 | * @param totalElements | |
140 | * @return block filter response | |
141 | */ | |
142 | private Page<Block> getBlockFilterListByTimeAsc(Pageable pageable, long totalElements) { | |
143 |
1
1. getBlockFilterListByTimeAsc : Replaced long multiplication with division → NO_COVERAGE |
long firstBlockIndexOfPage = (long) pageable.getPageNumber() * pageable.getPageSize(); |
144 | long currentMaxBlockNo = blockRepository.findCurrentBlock().map(Long::valueOf).orElse(0L); | |
145 | long minBlockNo = blockRepository.findMinBlockNo(); | |
146 | // if current max block no is less than first block index of page, then call | |
147 | // getBlocksAscByAFewPageAhead | |
148 |
2
1. getBlockFilterListByTimeAsc : negated conditional → NO_COVERAGE 2. getBlockFilterListByTimeAsc : changed conditional boundary → NO_COVERAGE |
if (currentMaxBlockNo < firstBlockIndexOfPage) { |
149 |
1
1. getBlockFilterListByTimeAsc : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::getBlockFilterListByTimeAsc → NO_COVERAGE |
return getBlocksAscByAFewPageAhead( |
150 | pageable, totalElements, firstBlockIndexOfPage, currentMaxBlockNo); | |
151 | } | |
152 | // if blockNo start from 0, then the first block index of page should minus 1 | |
153 |
2
1. getBlockFilterListByTimeAsc : Replaced long subtraction with addition → NO_COVERAGE 2. getBlockFilterListByTimeAsc : negated conditional → NO_COVERAGE |
firstBlockIndexOfPage = firstBlockIndexOfPage - ((minBlockNo == 0) ? 1 : 0); |
154 | // get first block id by first block no of page | |
155 | long firstBlockId = | |
156 | blockRepository.findFirstByBlockNo(firstBlockIndexOfPage).map(Block::getId).orElse(0L); | |
157 | ||
158 | // get genesis|ebb block count in front of first block id | |
159 | long ebbBlkCntInFrontOf = | |
160 | blockRepository.countGenesisAndEbbBlockInfoByBlockIdLessThan(firstBlockId).orElse(0L); | |
161 | ||
162 | long actualFirstBlockId; | |
163 |
2
1. getBlockFilterListByTimeAsc : negated conditional → NO_COVERAGE 2. getBlockFilterListByTimeAsc : changed conditional boundary → NO_COVERAGE |
if (ebbBlkCntInFrontOf > 0) { |
164 |
2
1. getBlockFilterListByTimeAsc : Replaced long subtraction with addition → NO_COVERAGE 2. getBlockFilterListByTimeAsc : Replaced long addition with subtraction → NO_COVERAGE |
actualFirstBlockId = |
165 | blockRepository | |
166 | .findFirstByBlockNo(firstBlockIndexOfPage - ebbBlkCntInFrontOf + 1) | |
167 | .map(Block::getId) | |
168 | .orElse(0L); | |
169 | } else { | |
170 | actualFirstBlockId = firstBlockId; | |
171 | } | |
172 | ||
173 | List<Block> blockList = | |
174 | getBlocksByBlockIdAndLimit(pageable.getPageSize(), actualFirstBlockId, Direction.ASC); | |
175 | ||
176 |
1
1. getBlockFilterListByTimeAsc : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::getBlockFilterListByTimeAsc → NO_COVERAGE |
return new PageImpl<>(blockList, pageable, totalElements); |
177 | } | |
178 | ||
179 | /** | |
180 | * Get block filter response ASC, based on last block of a few page ahead. Main idea: Find the | |
181 | * last block of a few page ahead | |
182 | * | |
183 | * @param pageable | |
184 | * @param totalElements | |
185 | * @param firstBlockIndexOfPage | |
186 | * @param currentMaxBlockNo | |
187 | * @return | |
188 | */ | |
189 | private Page<Block> getBlocksAscByAFewPageAhead( | |
190 | Pageable pageable, long totalElements, long firstBlockIndexOfPage, long currentMaxBlockNo) { | |
191 |
1
1. getBlocksAscByAFewPageAhead : Replaced long subtraction with addition → NO_COVERAGE |
int numberOfAFewPageAhead = |
192 |
2
1. getBlocksAscByAFewPageAhead : Replaced integer division with multiplication → NO_COVERAGE 2. getBlocksAscByAFewPageAhead : Replaced integer addition with subtraction → NO_COVERAGE |
(int) (firstBlockIndexOfPage - currentMaxBlockNo) / pageable.getPageSize() + 1; |
193 | ||
194 | Block lastBlockFromAFewPageAhead = | |
195 | getBlockFilterListByTimeAsc( | |
196 | PageRequest.of( | |
197 |
1
1. getBlocksAscByAFewPageAhead : Replaced integer subtraction with addition → NO_COVERAGE |
pageable.getPageNumber() - numberOfAFewPageAhead, |
198 | pageable.getPageSize(), | |
199 | Direction.ASC, | |
200 | BaseEntity_.ID), | |
201 | totalElements) | |
202 | .getContent() | |
203 |
1
1. getBlocksAscByAFewPageAhead : Replaced integer subtraction with addition → NO_COVERAGE |
.get(pageable.getPageSize() - 1); |
204 | ||
205 | long nextBlockId = blockRepository.findNextBlockId(lastBlockFromAFewPageAhead.getId()); | |
206 | ||
207 | List<Block> blocksResponse = | |
208 | getBlocksByBlockIdAndLimit( | |
209 |
1
1. getBlocksAscByAFewPageAhead : Replaced integer multiplication with division → NO_COVERAGE |
numberOfAFewPageAhead * pageable.getPageSize(), nextBlockId, Direction.ASC); |
210 | ||
211 | blocksResponse = | |
212 | blocksResponse.subList( | |
213 |
2
1. getBlocksAscByAFewPageAhead : Replaced integer subtraction with addition → NO_COVERAGE 2. getBlocksAscByAFewPageAhead : Replaced integer multiplication with division → NO_COVERAGE |
Math.min(blocksResponse.size(), (numberOfAFewPageAhead - 1) * pageable.getPageSize()), |
214 |
1
1. getBlocksAscByAFewPageAhead : Replaced integer multiplication with division → NO_COVERAGE |
Math.min(blocksResponse.size(), numberOfAFewPageAhead * pageable.getPageSize())); |
215 | ||
216 |
1
1. getBlocksAscByAFewPageAhead : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::getBlocksAscByAFewPageAhead → NO_COVERAGE |
return new PageImpl<>(blocksResponse, pageable, totalElements); |
217 | } | |
218 | ||
219 | private List<Block> getBlocksByBlockIdAndLimit(int limit, long blockId, Direction direction) { | |
220 |
1
1. getBlocksByBlockIdAndLimit : replaced return value with Collections.emptyList for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::getBlocksByBlockIdAndLimit → NO_COVERAGE |
return customBlockRepository.findByBlockIdAndLimit(blockId, limit, direction); |
221 | } | |
222 | ||
223 | /** | |
224 | * Get block filter response order by time|id desc. Main idea: Find the first block id by page and | |
225 | * genesis|ebb block count. Then find the block list by first block id and limit. | |
226 | * | |
227 | * @param pageable | |
228 | * @param totalElements | |
229 | * @return | |
230 | */ | |
231 | private Page<Block> getBlockFilterListByTimeDesc(Pageable pageable, long totalElements) { | |
232 | long firstBlockIndexOfPage = | |
233 |
2
1. getBlockFilterListByTimeDesc : Replaced long subtraction with addition → NO_COVERAGE 2. getBlockFilterListByTimeDesc : Replaced long multiplication with division → NO_COVERAGE |
totalElements - (long) pageable.getPageNumber() * pageable.getPageSize(); |
234 | ||
235 | long currentMaxBlockNo = blockRepository.findCurrentBlock().map(Long::valueOf).orElse(0L); | |
236 |
2
1. getBlockFilterListByTimeDesc : negated conditional → NO_COVERAGE 2. getBlockFilterListByTimeDesc : changed conditional boundary → NO_COVERAGE |
if (firstBlockIndexOfPage > currentMaxBlockNo) { |
237 |
1
1. getBlockFilterListByTimeDesc : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::getBlockFilterListByTimeDesc → NO_COVERAGE |
return getBlocksDescByFirstFewPage(pageable, totalElements, currentMaxBlockNo); |
238 | } | |
239 | ||
240 | // get first block id by first block no of page | |
241 | long firstBlockId = | |
242 | blockRepository | |
243 | .findFirstByBlockNo( | |
244 |
2
1. getBlockFilterListByTimeDesc : Replaced long multiplication with division → NO_COVERAGE 2. getBlockFilterListByTimeDesc : Replaced long subtraction with addition → NO_COVERAGE |
currentMaxBlockNo - (long) pageable.getPageNumber() * pageable.getPageSize()) |
245 | .map(Block::getId) | |
246 | .orElse(0L); | |
247 | ||
248 | // get total genesis|ebb block count | |
249 | long totalGenesisAndEbbBlockCnt = | |
250 | blockRepository.countGenesisAndEbbBlockInfoByBlockIdGreaterThan(0L).orElse(0L); | |
251 | ||
252 | // get genesis|ebb block count behind first block id | |
253 | long ebbBlkCntBehind = | |
254 | blockRepository.countGenesisAndEbbBlockInfoByBlockIdGreaterThan(firstBlockId).orElse(0L); | |
255 | ||
256 | // get actualFirstBlockId | |
257 | long actualFirstBlockId; | |
258 |
2
1. getBlockFilterListByTimeDesc : changed conditional boundary → NO_COVERAGE 2. getBlockFilterListByTimeDesc : negated conditional → NO_COVERAGE |
if (ebbBlkCntBehind > 0) { |
259 |
2
1. getBlockFilterListByTimeDesc : Replaced long subtraction with addition → NO_COVERAGE 2. getBlockFilterListByTimeDesc : Replaced long subtraction with addition → NO_COVERAGE |
actualFirstBlockId = |
260 | blockRepository | |
261 | .findFirstByBlockNo( | |
262 | firstBlockIndexOfPage - (totalGenesisAndEbbBlockCnt - ebbBlkCntBehind)) | |
263 | .map(Block::getId) | |
264 | .orElse(0L); | |
265 | } else { | |
266 | actualFirstBlockId = firstBlockId; | |
267 | } | |
268 | ||
269 | List<Block> blockList = | |
270 | customBlockRepository.findByBlockIdAndLimit( | |
271 | actualFirstBlockId, pageable.getPageSize(), Direction.DESC); | |
272 | ||
273 |
1
1. getBlockFilterListByTimeDesc : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::getBlockFilterListByTimeDesc → NO_COVERAGE |
return new PageImpl<>(blockList, pageable, totalElements); |
274 | } | |
275 | ||
276 | /** | |
277 | * Get block filter response DESC, based on first block of first few pages. | |
278 | * | |
279 | * @param pageable | |
280 | * @param totalElements | |
281 | * @param currentMaxBlockNo | |
282 | * @return | |
283 | */ | |
284 | private PageImpl<Block> getBlocksDescByFirstFewPage( | |
285 | Pageable pageable, long totalElements, long currentMaxBlockNo) { | |
286 | long currentMaxBlockId = | |
287 | blockRepository.findFirstByBlockNo(currentMaxBlockNo).map(Block::getId).orElse(0L); | |
288 | ||
289 | List<Block> blocksResponse = | |
290 | getBlocksByBlockIdAndLimit( | |
291 |
2
1. getBlocksDescByFirstFewPage : Replaced integer addition with subtraction → NO_COVERAGE 2. getBlocksDescByFirstFewPage : Replaced integer multiplication with division → NO_COVERAGE |
(pageable.getPageNumber() + 1) * pageable.getPageSize(), |
292 | currentMaxBlockId, | |
293 | Direction.DESC); | |
294 | ||
295 | blocksResponse = | |
296 | blocksResponse.subList( | |
297 |
1
1. getBlocksDescByFirstFewPage : Replaced integer multiplication with division → NO_COVERAGE |
Math.min(blocksResponse.size(), pageable.getPageNumber() * pageable.getPageSize()), |
298 | Math.min( | |
299 |
2
1. getBlocksDescByFirstFewPage : Replaced integer addition with subtraction → NO_COVERAGE 2. getBlocksDescByFirstFewPage : Replaced integer multiplication with division → NO_COVERAGE |
blocksResponse.size(), (pageable.getPageNumber() + 1) * pageable.getPageSize())); |
300 | ||
301 |
1
1. getBlocksDescByFirstFewPage : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::getBlocksDescByFirstFewPage → NO_COVERAGE |
return new PageImpl<>(blocksResponse, pageable, totalElements); |
302 | } | |
303 | ||
304 | @Override | |
305 | public BaseFilterResponse<BlockFilterResponse> getBlockByEpoch(String no, Pageable pageable) { | |
306 | try { | |
307 | Integer epochNo = Integer.parseInt(no); | |
308 | Page<Block> blocks = blockRepository.findBlockByEpochNo(epochNo, pageable); | |
309 |
1
1. getBlockByEpoch : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::getBlockByEpoch → KILLED |
return mapperBlockToBlockFilterResponse(blocks, false); |
310 | } catch (NumberFormatException e) { | |
311 | throw new NoContentException(BusinessCode.EPOCH_NOT_FOUND); | |
312 | } | |
313 | } | |
314 | ||
315 | @Override | |
316 | public List<BlockPropagationResponse> getBlockPropagation( | |
317 | BlockPropagationChartType type, Pageable pageable) { | |
318 | // if type is null, will get block statistics per epoch as default | |
319 |
2
1. getBlockPropagation : negated conditional → NO_COVERAGE 2. getBlockPropagation : negated conditional → NO_COVERAGE |
if (type == null || type.equals(BlockPropagationChartType.EPOCH)) { |
320 |
1
1. getBlockPropagation : replaced return value with Collections.emptyList for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::getBlockPropagation → NO_COVERAGE |
return blockStatisticsPerEpochRepository.findBlockPropagation(pageable).stream() |
321 | .map(blockPropagationMapper::fromBlockPropagationProjection) | |
322 | .collect(Collectors.toList()); | |
323 | } else { | |
324 |
1
1. getBlockPropagation : replaced return value with Collections.emptyList for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::getBlockPropagation → NO_COVERAGE |
return blockStatisticsDailyRepository.findBlockPropagation(pageable).stream() |
325 | .map(blockPropagationMapper::fromBlockPropagationProjection) | |
326 | .collect(Collectors.toList()); | |
327 | } | |
328 | } | |
329 | ||
330 | /** | |
331 | * Mapping from block entity to block response dto | |
332 | * | |
333 | * @param blocks list block entity | |
334 | * @return list block information in this page | |
335 | */ | |
336 | private BaseFilterResponse<BlockFilterResponse> mapperBlockToBlockFilterResponse( | |
337 | Page<Block> blocks, boolean isGetAllBlock) { | |
338 | // get slot leader for block | |
339 | List<SlotLeader> slotLeaders = | |
340 | slotLeaderRepository.findByIdIn( | |
341 | blocks.getContent().stream().map(Block::getSlotLeaderId).collect(Collectors.toList())); | |
342 | Map<Long, SlotLeader> slotLeaderMap = | |
343 | slotLeaders.stream().collect(Collectors.toMap(BaseEntity::getId, Function.identity())); | |
344 | ||
345 | List<Tx> txList = txRepository.findByBlockIn(blocks.toList()); | |
346 | ||
347 | // create map with key: block_id, value : total output of block | |
348 | Map<Long, BigInteger> blockTotalOutputMap = | |
349 | txList.stream() | |
350 | .collect( | |
351 | Collectors.groupingBy( | |
352 |
1
1. lambda$mapperBlockToBlockFilterResponse$3 : replaced Long return value with 0L for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::lambda$mapperBlockToBlockFilterResponse$3 → SURVIVED |
tx -> tx.getBlock().getId(), |
353 | Collectors.reducing(BigInteger.ZERO, Tx::getOutSum, BigInteger::add))); | |
354 | // create map with key: block_id, value : total fee of block | |
355 | Map<Long, BigInteger> blockTotalFeeMap = | |
356 | txList.stream() | |
357 | .collect( | |
358 | Collectors.groupingBy( | |
359 |
1
1. lambda$mapperBlockToBlockFilterResponse$4 : replaced Long return value with 0L for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::lambda$mapperBlockToBlockFilterResponse$4 → SURVIVED |
tx -> tx.getBlock().getId(), |
360 | Collectors.reducing(BigInteger.ZERO, Tx::getFee, BigInteger::add))); | |
361 | ||
362 | List<BlockFilterResponse> blockFilterResponseList = new ArrayList<>(); | |
363 | ||
364 | for (Block block : blocks) { | |
365 |
1
1. mapperBlockToBlockFilterResponse : removed call to org/cardanofoundation/explorer/common/entity/ledgersync/Block::setSlotLeader → SURVIVED |
block.setSlotLeader(slotLeaderMap.get(block.getSlotLeaderId())); |
366 | BlockFilterResponse blockResponse = blockMapper.blockToBlockFilterResponse(block); | |
367 |
1
1. mapperBlockToBlockFilterResponse : negated conditional → SURVIVED |
if (!isGetAllBlock) { |
368 | var totalOutput = blockTotalOutputMap.get(block.getId()); | |
369 | var totalFees = blockTotalFeeMap.get(block.getId()); | |
370 |
1
1. mapperBlockToBlockFilterResponse : removed call to org/cardanofoundation/explorer/api/model/response/BlockFilterResponse::setTotalOutput → SURVIVED |
blockResponse.setTotalOutput(Objects.requireNonNullElse(totalOutput, BigInteger.ZERO)); |
371 |
1
1. mapperBlockToBlockFilterResponse : removed call to org/cardanofoundation/explorer/api/model/response/BlockFilterResponse::setTotalFees → SURVIVED |
blockResponse.setTotalFees(Objects.requireNonNullElse(totalFees, BigInteger.ZERO)); |
372 | } else { | |
373 |
1
1. mapperBlockToBlockFilterResponse : removed call to org/cardanofoundation/explorer/api/model/response/BlockFilterResponse::setTxCount → NO_COVERAGE |
blockResponse.setTxCount(null); |
374 | } | |
375 | blockFilterResponseList.add(blockResponse); | |
376 | } | |
377 |
1
1. mapperBlockToBlockFilterResponse : replaced return value with null for org/cardanofoundation/explorer/api/service/impl/BlockServiceImpl::mapperBlockToBlockFilterResponse → KILLED |
return new BaseFilterResponse<>(blocks, blockFilterResponseList); |
378 | } | |
379 | } | |
Mutations | ||
66 |
1.1 |
|
67 |
1.1 |
|
72 |
1.1 |
|
73 |
1.1 |
|
88 |
1.1 |
|
90 |
1.1 |
|
93 |
1.1 |
|
94 |
1.1 |
|
95 |
1.1 |
|
96 |
1.1 |
|
97 |
1.1 |
|
103 |
1.1 |
|
104 |
1.1 |
|
105 |
1.1 2.2 |
|
107 |
1.1 |
|
115 |
1.1 |
|
121 |
1.1 2.2 |
|
122 |
1.1 2.2 |
|
124 |
1.1 2.2 |
|
125 |
1.1 |
|
126 |
1.1 |
|
131 |
1.1 |
|
143 |
1.1 |
|
148 |
1.1 2.2 |
|
149 |
1.1 |
|
153 |
1.1 2.2 |
|
163 |
1.1 2.2 |
|
164 |
1.1 2.2 |
|
176 |
1.1 |
|
191 |
1.1 |
|
192 |
1.1 2.2 |
|
197 |
1.1 |
|
203 |
1.1 |
|
209 |
1.1 |
|
213 |
1.1 2.2 |
|
214 |
1.1 |
|
216 |
1.1 |
|
220 |
1.1 |
|
233 |
1.1 2.2 |
|
236 |
1.1 2.2 |
|
237 |
1.1 |
|
244 |
1.1 2.2 |
|
258 |
1.1 2.2 |
|
259 |
1.1 2.2 |
|
273 |
1.1 |
|
291 |
1.1 2.2 |
|
297 |
1.1 |
|
299 |
1.1 2.2 |
|
301 |
1.1 |
|
309 |
1.1 |
|
319 |
1.1 2.2 |
|
320 |
1.1 |
|
324 |
1.1 |
|
352 |
1.1 |
|
359 |
1.1 |
|
365 |
1.1 |
|
367 |
1.1 |
|
370 |
1.1 |
|
371 |
1.1 |
|
373 |
1.1 |
|
377 |
1.1 |