Beispiel #1
0
  @Override
  public BigInteger getTotalDifficultyForHash(byte[] hash) {
    Block block = this.getBlockByHash(hash);
    if (block == null) return ZERO;

    Long level = block.getNumber();
    List<BlockInfo> blockInfos = index.get(level.intValue());
    for (BlockInfo blockInfo : blockInfos)
      if (areEqual(blockInfo.getHash(), hash)) {
        return blockInfo.cummDifficulty;
      }

    return ZERO;
  }
Beispiel #2
0
  public void printChain() {

    Long number = getMaxNumber();

    for (int i = 0; i < number; ++i) {
      List<BlockInfo> levelInfos = index.get(i);

      if (levelInfos != null) {
        System.out.print(i);
        for (BlockInfo blockInfo : levelInfos) {
          if (blockInfo.isMainChain())
            System.out.print(" [" + shortHash(blockInfo.getHash()) + "] ");
          else System.out.print(" " + shortHash(blockInfo.getHash()) + " ");
        }
        System.out.println();
      }
    }
  }
Beispiel #3
0
  private void addInternalBlock(Block block, BigInteger cummDifficulty, boolean mainChain) {

    List<BlockInfo> blockInfos =
        block.getNumber() >= index.size()
            ? new ArrayList<BlockInfo>()
            : index.get((int) block.getNumber());

    BlockInfo blockInfo = new BlockInfo();
    blockInfo.setCummDifficulty(cummDifficulty);
    blockInfo.setHash(block.getHash());
    blockInfo.setMainChain(
        mainChain); // FIXME:maybe here I should force reset main chain for all uncles on that level

    blockInfos.add(blockInfo);
    index.set((int) block.getNumber(), blockInfos);

    blocks.put(block.getHash(), block);
  }
Beispiel #4
0
  @Override
  public Block getChainBlockByNumber(long number) {
    if (number >= index.size()) {
      return null;
    }

    List<BlockInfo> blockInfos = index.get((int) number);

    for (BlockInfo blockInfo : blockInfos) {

      if (blockInfo.isMainChain()) {

        byte[] hash = blockInfo.getHash();
        return blocks.get(hash);
      }
    }

    return null;
  }
Beispiel #5
0
  public List<Block> getBlocksByNumber(long number) {

    List<Block> result = new ArrayList<>();

    if (number >= index.size()) {
      return result;
    }

    List<BlockInfo> blockInfos = index.get((int) number);

    for (BlockInfo blockInfo : blockInfos) {

      byte[] hash = blockInfo.getHash();
      Block block = blocks.get(hash);

      result.add(block);
    }
    return result;
  }
Beispiel #6
0
  public List<byte[]> getListHashesStartWith(long number, long maxBlocks) {

    List<byte[]> result = new ArrayList<>();

    int i;
    for (i = 0; i < maxBlocks; ++i) {
      List<BlockInfo> blockInfos = index.get((int) number);
      if (blockInfos == null) break;

      for (BlockInfo blockInfo : blockInfos)
        if (blockInfo.isMainChain()) {
          result.add(blockInfo.getHash());
          break;
        }

      ++number;
    }
    maxBlocks -= i;

    return result;
  }
Beispiel #7
0
  @Override
  public BigInteger getTotalDifficulty() {
    long maxNumber = getMaxNumber();

    List<BlockInfo> blockInfos = index.get((int) maxNumber);
    for (BlockInfo blockInfo : blockInfos) {
      if (blockInfo.isMainChain()) {
        return blockInfo.getCummDifficulty();
      }
    }

    while (true) {
      --maxNumber;
      List<BlockInfo> infos = getBlockInfoForLevel(maxNumber);

      for (BlockInfo blockInfo : infos) {
        if (blockInfo.isMainChain()) {
          return blockInfo.getCummDifficulty();
        }
      }
    }
  }
Beispiel #8
0
  private static BlockInfo getBlockInfoForHash(List<BlockInfo> blocks, byte[] hash) {

    for (BlockInfo blockInfo : blocks) if (areEqual(hash, blockInfo.getHash())) return blockInfo;

    return null;
  }
Beispiel #9
0
  @Override
  public void reBranch(Block forkBlock) {

    Block bestBlock = getBestBlock();

    long maxLevel = Math.max(bestBlock.getNumber(), forkBlock.getNumber());

    // 1. First ensure that you are one the save level
    long currentLevel = maxLevel;
    Block forkLine = forkBlock;
    if (forkBlock.getNumber() > bestBlock.getNumber()) {

      while (currentLevel > bestBlock.getNumber()) {
        List<BlockInfo> blocks = getBlockInfoForLevel(currentLevel);
        BlockInfo blockInfo = getBlockInfoForHash(blocks, forkLine.getHash());
        if (blockInfo != null) {
          blockInfo.setMainChain(true);
          setBlockInfoForLevel(currentLevel, blocks);
        }
        forkLine = getBlockByHash(forkLine.getParentHash());
        --currentLevel;
      }
    }

    Block bestLine = bestBlock;
    if (bestBlock.getNumber() > forkBlock.getNumber()) {

      while (currentLevel > forkBlock.getNumber()) {

        List<BlockInfo> blocks = getBlockInfoForLevel(currentLevel);
        BlockInfo blockInfo = getBlockInfoForHash(blocks, bestLine.getHash());
        if (blockInfo != null) {
          blockInfo.setMainChain(false);
          setBlockInfoForLevel(currentLevel, blocks);
        }
        bestLine = getBlockByHash(bestLine.getParentHash());
        --currentLevel;
      }
    }

    // 2. Loop back on each level until common block
    while (!bestLine.isEqual(forkLine)) {

      List<BlockInfo> levelBlocks = getBlockInfoForLevel(currentLevel);
      BlockInfo bestInfo = getBlockInfoForHash(levelBlocks, bestLine.getHash());
      if (bestInfo != null) {
        bestInfo.setMainChain(false);
        setBlockInfoForLevel(currentLevel, levelBlocks);
      }

      BlockInfo forkInfo = getBlockInfoForHash(levelBlocks, forkLine.getHash());
      if (forkInfo != null) {
        forkInfo.setMainChain(true);
        setBlockInfoForLevel(currentLevel, levelBlocks);
      }

      bestLine = getBlockByHash(bestLine.getParentHash());
      forkLine = getBlockByHash(forkLine.getParentHash());

      --currentLevel;
    }
  }