Coverage Summary for Class: BlockUtils (co.rsk.core.bc)

Class Class, % Method, % Line, %
BlockUtils 100% (1/1) 10% (1/10) 2.4% (1/41)


1 /* 2  * This file is part of RskJ 3  * Copyright (C) 2017 RSK Labs Ltd. 4  * 5  * This program is free software: you can redistribute it and/or modify 6  * it under the terms of the GNU Lesser General Public License as published by 7  * the Free Software Foundation, either version 3 of the License, or 8  * (at your option) any later version. 9  * 10  * This program is distributed in the hope that it will be useful, 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13  * GNU Lesser General Public License for more details. 14  * 15  * You should have received a copy of the GNU Lesser General Public License 16  * along with this program. If not, see <http://www.gnu.org/licenses/>. 17  */ 18  19 package co.rsk.core.bc; 20  21 import co.rsk.crypto.Keccak256; 22 import co.rsk.net.NetBlockStore; 23 import org.ethereum.core.Block; 24 import org.ethereum.core.BlockHeader; 25 import org.ethereum.core.Blockchain; 26 import org.ethereum.db.BlockInformation; 27  28 import java.util.*; 29 import java.util.stream.Collectors; 30  31 /** 32  * Created by ajlopez on 19/08/2016. 33  */ 34 public class BlockUtils { 35  private static final long MAX_BLOCK_PROCESS_TIME_NANOSECONDS = 60_000_000_000L; 36  37  private BlockUtils() { } 38  39  public static boolean tooMuchProcessTime(long nanoseconds) { 40  return nanoseconds > MAX_BLOCK_PROCESS_TIME_NANOSECONDS; 41  } 42  43  public static boolean blockInSomeBlockChain(Block block, Blockchain blockChain) { 44  return blockInSomeBlockChain(block.getHash(), block.getNumber(), blockChain); 45  } 46  47  private static boolean blockInSomeBlockChain(Keccak256 blockHash, long blockNumber, Blockchain blockChain) { 48  final List<BlockInformation> blockInformations = blockChain.getBlocksInformationByNumber(blockNumber); 49  return blockInformations.stream().anyMatch(bi -> Arrays.equals(blockHash.getBytes(), bi.getHash())); 50  } 51  52  public static Set<Keccak256> unknownDirectAncestorsHashes(Block block, Blockchain blockChain, NetBlockStore store) { 53  Set<Keccak256> hashes = Collections.singleton(block.getParentHash()); 54  return unknownAncestorsHashes(hashes, blockChain, store, false); 55  } 56  57  public static Set<Keccak256> unknownAncestorsHashes(Keccak256 blockHash, Blockchain blockChain, NetBlockStore store) { 58  Set<Keccak256> hashes = Collections.singleton(blockHash); 59  return unknownAncestorsHashes(hashes, blockChain, store, true); 60  } 61  62  public static Set<Keccak256> unknownAncestorsHashes(Set<Keccak256> hashesToProcess, Blockchain blockChain, NetBlockStore store, boolean withUncles) { 63  Set<Keccak256> unknown = new HashSet<>(); 64  Set<Keccak256> hashes = hashesToProcess; 65  66  while (!hashes.isEmpty()) { 67  hashes = getNextHashes(hashes, unknown, blockChain, store, withUncles); 68  } 69  70  return unknown; 71  } 72  73  private static Set<Keccak256> getNextHashes(Set<Keccak256> previousHashes, Set<Keccak256> unknown, Blockchain blockChain, NetBlockStore store, boolean withUncles) { 74  Set<Keccak256> nextHashes = new HashSet<>(); 75  for (Keccak256 hash : previousHashes) { 76  if (unknown.contains(hash)) { 77  continue; 78  } 79  80  Block block = blockChain.getBlockByHash(hash.getBytes()); 81  if (block == null) { 82  block = store.getBlockByHash(hash.getBytes()); 83  } 84  85  if (block == null) { 86  unknown.add(hash); 87  continue; 88  } 89  90  if (!block.isGenesis() && !blockInSomeBlockChain(block, blockChain)) { 91  nextHashes.add(block.getParentHash()); 92  93  if (withUncles) { 94  for (BlockHeader uncleHeader : block.getUncleList()) { 95  nextHashes.add(uncleHeader.getHash()); 96  } 97  } 98  } 99  } 100  return nextHashes; 101  } 102  103  public static void addBlockToList(List<Block> blocks, Block block) { 104  for (Block b : blocks) { 105  if (b.getHash().equals(block.getHash())) { 106  return; 107  } 108  } 109  110  blocks.add(block); 111  } 112  113  public static List<Block> sortBlocksByNumber(List<Block> blocks) { 114  return blocks.stream() 115  .sorted(Comparator.comparingLong(Block::getNumber)) 116  .collect(Collectors.toList()); 117  } 118  119 }