Beispiel #1
0
 public byte[] getBlockHashByNumber(long blockNumber) {
   Block chainBlock = getChainBlockByNumber(blockNumber);
   return chainBlock == null
       ? null
       : chainBlock
           .getHash(); // FIXME: can be improved by accessing the hash directly in the index
 }
  /**
   * For each block we are looking for our transactions and clearing them The actual receiver
   * balance is confirmed upon block arrival
   */
  public void onBlock(Block block, List<TransactionReceipt> receipts) {
    int cleared = 0;
    for (Transaction tx : block.getTransactionsList()) {
      ByteArrayWrapper txHash = new ByteArrayWrapper(tx.getHash());
      Transaction ptx = pendingTxs.get(txHash);
      if (ptx != null) {
        logger.info(
            " - Pending transaction cleared 0x"
                + Hex.toHexString(tx.getHash()).substring(0, 8)
                + " in block "
                + block.getShortDescr());

        pendingTxs.remove(txHash);
        cleared++;
      }
    }
    BigInteger receiverBalance = ethereum.getRepository().getBalance(receiverAddress);
    BigInteger receiverBalancePending = pendingState.getRepository().getBalance(receiverAddress);
    logger.info("" + cleared + " transactions cleared in the block " + block.getShortDescr());
    logger.info(
        "Receiver pending/current balance: "
            + receiverBalancePending
            + " / "
            + receiverBalance
            + " ("
            + pendingTxs.size()
            + " pending txs)");
  }
Beispiel #3
0
  @Override
  public List<BlockHeader> getListHeadersEndWith(byte[] hash, long qty) {

    List<Block> blocks = getListBlocksEndWith(hash, qty);
    List<BlockHeader> headers = new ArrayList<>(blocks.size());

    for (Block b : blocks) {
      headers.add(b.getHeader());
    }

    return headers;
  }
Beispiel #4
0
  @Override
  public List<byte[]> getListHashesEndWith(byte[] hash, long number) {

    List<Block> blocks = getListBlocksEndWith(hash, number);
    List<byte[]> hashes = new ArrayList<>(blocks.size());

    for (Block b : blocks) {
      hashes.add(b.getHash());
    }

    return hashes;
  }
Beispiel #5
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 #6
0
  private List<Block> getListBlocksEndWithInner(byte[] hash, long qty) {

    Block block = this.blocks.get(hash);

    if (block == null) return new ArrayList<>();

    List<Block> blocks = new ArrayList<>((int) qty);

    for (int i = 0; i < qty; ++i) {
      blocks.add(block);
      block = this.blocks.get(block.getParentHash());
      if (block == null) break;
    }

    return blocks;
  }
  @Override
  public Block createForkBlock(Block parent) {
    try {
      List<Transaction> txes = new ArrayList<>();
      Map<ByteArrayWrapper, Long> nonces = new HashMap<>();
      Repository repoSnapshot =
          getBlockchain().getRepository().getSnapshotTo(parent.getStateRoot());
      for (PendingTx tx : submittedTxes) {
        ByteArrayWrapper senderW = new ByteArrayWrapper(tx.sender.getAddress());
        Long nonce = nonces.get(senderW);
        if (nonce == null) {
          BigInteger bcNonce = repoSnapshot.getNonce(tx.sender.getAddress());
          nonce = bcNonce.longValue();
        }
        nonces.put(senderW, nonce + 1);

        byte[] toAddress =
            tx.targetContract != null ? tx.targetContract.getAddress() : tx.toAddress;

        Transaction transaction =
            new Transaction(
                ByteUtil.longToBytesNoLeadZeroes(nonce),
                ByteUtil.longToBytesNoLeadZeroes(gasPrice),
                ByteUtil.longToBytesNoLeadZeroes(gasLimit),
                toAddress,
                ByteUtil.bigIntegerToBytes(tx.value),
                tx.data);
        transaction.sign(tx.sender.getPrivKeyBytes());
        if (tx.createdContract != null) {
          tx.createdContract.setAddress(transaction.getContractAddress());
        }
        txes.add(transaction);
      }
      Block b = getBlockchain().createNewBlock(parent, txes, Collections.EMPTY_LIST);
      Ethash.getForBlock(b.getNumber()).mineLight(b).get();
      ImportResult importResult = getBlockchain().tryToConnect(b);
      if (importResult != ImportResult.IMPORTED_BEST
          && importResult != ImportResult.IMPORTED_NOT_BEST) {
        throw new RuntimeException(
            "Invalid block import result " + importResult + " for block " + b);
      }
      submittedTxes.clear();
      return b;
    } catch (InterruptedException | ExecutionException e) {
      throw new RuntimeException(e);
    }
  }
Beispiel #8
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);
  }
    @Override
    public Object[] callConstFunction(Block callBlock, String functionName, Object... args) {

      Transaction tx =
          CallTransaction.createCallTransaction(
              0,
              0,
              100000000000000L,
              Hex.toHexString(getAddress()),
              0,
              contract.getByName(functionName),
              args);
      tx.sign(new byte[32]);

      Repository repository =
          getBlockchain().getRepository().getSnapshotTo(callBlock.getStateRoot()).startTracking();

      try {
        org.ethereum.core.TransactionExecutor executor =
            new org.ethereum.core.TransactionExecutor(
                    tx,
                    callBlock.getCoinbase(),
                    repository,
                    getBlockchain().getBlockStore(),
                    getBlockchain().getProgramInvokeFactory(),
                    callBlock)
                .setLocalCall(true);

        executor.init();
        executor.execute();
        executor.go();
        executor.finalization();

        return contract.getByName(functionName).decodeResult(executor.getResult().getHReturn());
      } finally {
        repository.rollback();
      }
    }
Beispiel #10
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;
    }
  }