public StoredTransactionOutput getTransactionOutput(Sha256Hash hash, long index)
     throws BlockStoreException {
   maybeConnect();
   PreparedStatement s = null;
   try {
     s =
         conn.get()
             .prepareStatement(
                 "SELECT height, value, scriptBytes FROM openOutputs "
                     + "WHERE hash = ? AND index = ?");
     s.setBytes(1, hash.getBytes());
     // index is actually an unsigned int
     s.setInt(2, (int) index);
     ResultSet results = s.executeQuery();
     if (!results.next()) {
       return null;
     }
     // Parse it.
     int height = results.getInt(1);
     BigInteger value = new BigInteger(results.getBytes(2));
     // Tell the StoredTransactionOutput that we are a coinbase, as that is encoded in height
     StoredTransactionOutput txout =
         new StoredTransactionOutput(hash, index, value, height, true, results.getBytes(3));
     return txout;
   } catch (SQLException ex) {
     throw new BlockStoreException(ex);
   } finally {
     if (s != null)
       try {
         s.close();
       } catch (SQLException e) {
         throw new BlockStoreException("Failed to close PreparedStatement");
       }
   }
 }
Ejemplo n.º 2
0
 protected void bitcoinSerializeToStream(OutputStream stream) throws IOException {
   // Version, for some reason.
   Utils.uint32ToByteStreamLE(NetworkParameters.PROTOCOL_VERSION, stream);
   // Then a vector of block hashes. This is actually a "block locator", a set of block
   // identifiers that spans the entire chain with exponentially increasing gaps between
   // them, until we end up at the genesis block. See CBlockLocator::Set()
   stream.write(new VarInt(locator.size()).encode());
   for (Sha256Hash hash : locator) {
     // Have to reverse as wire format is little endian.
     stream.write(Utils.reverseBytes(hash.getBytes()));
   }
   // Next, a block ID to stop at.
   stream.write(Utils.reverseBytes(stopHash.getBytes()));
 }
Ejemplo n.º 3
0
 private static Sha256Hash calcHash(int height, int pos, List<Sha256Hash> hashes) {
   if (height == 0) {
     // Hash at height 0 is just the regular tx hash itself.
     return hashes.get(pos);
   }
   int h = height - 1;
   int p = pos * 2;
   Sha256Hash left = calcHash(h, p, hashes);
   // Calculate right hash if not beyond the end of the array - copy left hash otherwise.
   Sha256Hash right;
   if (p + 1 < getTreeWidth(hashes.size(), h)) {
     right = calcHash(h, p + 1, hashes);
   } else {
     right = left;
   }
   return combineLeftRight(left.getBytes(), right.getBytes());
 }
Ejemplo n.º 4
0
  @Override
  public void neoscoinSerializeToStream(OutputStream stream) throws IOException {
    uint32ToByteStreamLE(transactionCount, stream);

    stream.write(new VarInt(hashes.size()).encode());
    for (Sha256Hash hash : hashes) stream.write(reverseBytes(hash.getBytes()));

    stream.write(new VarInt(matchedChildBits.length).encode());
    stream.write(matchedChildBits);
  }
 /**
  * Build a 'getblocks' message
  *
  * @param peer Destination peer
  * @param blockList Block hash list
  * @param stopBlock Stop block hash (Sha256Hash.ZERO_HASH to get all blocks)
  * @return 'getblocks' message
  */
 public static Message buildGetBlocksMessage(
     Peer peer, List<Sha256Hash> blockList, Sha256Hash stopBlock) {
   //
   // Build the message payload
   //
   // The protocol version will be set to the lesser of our version and the peer version
   //
   SerializedBuffer msgBuffer = new SerializedBuffer(blockList.size() * 32 + 40);
   msgBuffer
       .putInt(Math.min(peer.getVersion(), NetParams.PROTOCOL_VERSION))
       .putVarInt(blockList.size());
   for (Sha256Hash hash : blockList) {
     msgBuffer.putBytes(Helper.reverseBytes(hash.getBytes()));
   }
   msgBuffer.putBytes(Helper.reverseBytes(stopBlock.getBytes()));
   //
   // Build the message
   //
   ByteBuffer buffer = MessageHeader.buildMessage("getblocks", msgBuffer);
   return new Message(buffer, peer, MessageHeader.MessageCommand.GETBLOCKS);
 }
  public static byte[] hashForSignature(
      Transaction tx, int inputIndex, byte[] connectedScript, byte sigHashType) {
    byte[] serializedSig = serializeForSignature(tx, inputIndex, connectedScript, sigHashType);

    Sha256Hash hash = Sha256Hash.twiceOf(serializedSig);
    String hashHex = Utils.HEX.encode(hash.getBytes());
    // check hash against the reference implementation inside of bitcoinj
    byte[] referenceImplementation =
        tx.hashForSignature(inputIndex, connectedScript, sigHashType).getBytes();
    String referenceImplementationHex = Utils.HEX.encode(referenceImplementation);
    if (!hashHex.equals(referenceImplementationHex)) {
      logger.error("bitcoins: " + hashHex);
      logger.error("bitcoinj: " + referenceImplementationHex);
      throw new RuntimeException(
          "Difference between BitcoinJSignatureSerialization & Actual Bitcoinj\n"
              + "bitcoin-s: "
              + hashHex
              + "\n"
              + "bitcoin-j: "
              + referenceImplementationHex);
    }
    return hash.getBytes();
  }
Ejemplo n.º 7
0
 @Override
 void bitcoinSerializeToStream(OutputStream stream) throws IOException {
   Utils.uint32ToByteStreamLE(height, stream);
   stream.write(chainHead.getBytes());
   stream.write(new VarInt(hits.length).encode());
   stream.write(hits);
   stream.write(new VarInt(outputs.size()).encode());
   for (TransactionOutput output : outputs) {
     // TODO: Allow these to be specified, if one day we care about sending this message ourselves
     // (currently it's just used for unit testing).
     Utils.uint32ToByteStreamLE(0L, stream); // Version
     Utils.uint32ToByteStreamLE(0L, stream); // Height
     output.bitcoinSerializeToStream(stream);
   }
 }
Ejemplo n.º 8
0
 // default for testing
 void writeHeader(OutputStream stream) throws IOException {
   // try for cached write first
   if (headerBytesValid && bytes != null && bytes.length >= offset + HEADER_SIZE) {
     stream.write(bytes, offset, HEADER_SIZE);
     return;
   }
   // fall back to manual write
   maybeParseHeader();
   Utils.uint32ToByteStreamLE(version, stream);
   stream.write(Utils.reverseBytes(prevBlockHash.getBytes()));
   stream.write(Utils.reverseBytes(getMerkleRoot().getBytes()));
   Utils.uint32ToByteStreamLE(time, stream);
   Utils.uint32ToByteStreamLE(difficultyTarget, stream);
   Utils.uint32ToByteStreamLE(nonce, stream);
 }
  public StoredBlock get(Sha256Hash hash, boolean wasUndoableOnly) throws BlockStoreException {
    // Optimize for chain head
    if (chainHeadHash != null && chainHeadHash.equals(hash)) return chainHeadBlock;
    if (verifiedChainHeadHash != null && verifiedChainHeadHash.equals(hash))
      return verifiedChainHeadBlock;
    maybeConnect();
    PreparedStatement s = null;
    try {
      s =
          conn.get()
              .prepareStatement(
                  "SELECT chainWork, height, header, wasUndoable FROM headers WHERE hash = ?");
      // We skip the first 4 bytes because (on prodnet) the minimum target has 4 0-bytes
      byte[] hashBytes = new byte[28];
      System.arraycopy(hash.getBytes(), 3, hashBytes, 0, 28);
      s.setBytes(1, hashBytes);
      ResultSet results = s.executeQuery();
      if (!results.next()) {
        return null;
      }
      // Parse it.

      if (wasUndoableOnly && !results.getBoolean(4)) return null;

      BigInteger chainWork = new BigInteger(results.getBytes(1));
      int height = results.getInt(2);
      Block b = new Block(params, results.getBytes(3));
      b.verifyHeader();
      StoredBlock stored = new StoredBlock(b, chainWork, height);
      return stored;
    } catch (SQLException ex) {
      throw new BlockStoreException(ex);
    } catch (ProtocolException e) {
      // Corrupted database.
      throw new BlockStoreException(e);
    } catch (VerificationException e) {
      // Should not be able to happen unless the database contains bad
      // blocks.
      throw new BlockStoreException(e);
    } finally {
      if (s != null)
        try {
          s.close();
        } catch (SQLException e) {
          throw new BlockStoreException("Failed to close PreparedStatement");
        }
    }
  }
 public void setChainHead(StoredBlock chainHead) throws BlockStoreException {
   Sha256Hash hash = chainHead.getHeader().getHash();
   this.chainHeadHash = hash;
   this.chainHeadBlock = chainHead;
   maybeConnect();
   try {
     PreparedStatement s =
         conn.get().prepareStatement("UPDATE settings SET value = ? WHERE name = ?");
     s.setString(2, CHAIN_HEAD_SETTING);
     s.setBytes(1, hash.getBytes());
     s.executeUpdate();
     s.close();
   } catch (SQLException ex) {
     throw new BlockStoreException(ex);
   }
 }
Ejemplo n.º 11
0
  @Override
  @Nullable
  public StoredBlock get(Sha256Hash hash) throws BlockStoreException {
    final MappedByteBuffer buffer = this.buffer;
    if (buffer == null) throw new BlockStoreException("Store closed");

    lock.lock();
    try {
      StoredBlock cacheHit = blockCache.get(hash);
      if (cacheHit != null) return cacheHit;
      if (notFoundCache.get(hash) != null) return null;

      // Starting from the current tip of the ring work backwards until we have either found the
      // block or
      // wrapped around.
      int cursor = getRingCursor(buffer);
      final int startingPoint = cursor;
      final int fileSize = getFileSize();
      final byte[] targetHashBytes = hash.getBytes();
      byte[] scratch = new byte[32];
      do {
        cursor -= RECORD_SIZE;
        if (cursor < FILE_PROLOGUE_BYTES) {
          // We hit the start, so wrap around.
          cursor = fileSize - RECORD_SIZE;
        }
        // Cursor is now at the start of the next record to check, so read the hash and compare it.
        buffer.position(cursor);
        buffer.get(scratch);
        if (Arrays.equals(scratch, targetHashBytes)) {
          // Found the target.
          StoredBlock storedBlock = StoredBlock.deserializeCompact(params, buffer);
          blockCache.put(hash, storedBlock);
          return storedBlock;
        }
      } while (cursor != startingPoint);
      // Not found.
      notFoundCache.put(hash, notFoundMarker);
      return null;
    } catch (ProtocolException e) {
      throw new RuntimeException(e); // Cannot happen.
    } finally {
      lock.unlock();
    }
  }
 public void setVerifiedChainHead(StoredBlock chainHead) throws BlockStoreException {
   Sha256Hash hash = chainHead.getHeader().getHash();
   this.verifiedChainHeadHash = hash;
   this.verifiedChainHeadBlock = chainHead;
   maybeConnect();
   try {
     PreparedStatement s =
         conn.get().prepareStatement("UPDATE settings SET value = ? WHERE name = ?");
     s.setString(2, VERIFIED_CHAIN_HEAD_SETTING);
     s.setBytes(1, hash.getBytes());
     s.executeUpdate();
     s.close();
   } catch (SQLException ex) {
     throw new BlockStoreException(ex);
   }
   if (this.chainHeadBlock.getHeight() < chainHead.getHeight()) setChainHead(chainHead);
   removeUndoableBlocksWhereHeightIsLessThan(chainHead.getHeight() - fullStoreDepth);
 }
Ejemplo n.º 13
0
  @Override
  public void put(StoredBlock block) throws BlockStoreException {
    final MappedByteBuffer buffer = this.buffer;
    if (buffer == null) throw new BlockStoreException("Store closed");

    lock.lock();
    try {
      int cursor = getRingCursor(buffer);
      if (cursor == getFileSize()) {
        // Wrapped around.
        cursor = FILE_PROLOGUE_BYTES;
      }
      buffer.position(cursor);
      Sha256Hash hash = block.getHeader().getHash();
      notFoundCache.remove(hash);
      buffer.put(hash.getBytes());
      block.serializeCompact(buffer);
      setRingCursor(buffer, buffer.position());
      blockCache.put(hash, block);
    } finally {
      lock.unlock();
    }
  }
 public boolean hasUnspentOutputs(Sha256Hash hash, int numOutputs) throws BlockStoreException {
   maybeConnect();
   PreparedStatement s = null;
   try {
     s = conn.get().prepareStatement("SELECT COUNT(*) FROM openOutputs WHERE hash = ?");
     s.setBytes(1, hash.getBytes());
     ResultSet results = s.executeQuery();
     if (!results.next()) {
       throw new BlockStoreException("Got no results from a COUNT(*) query");
     }
     int count = results.getInt(1);
     return count != 0;
   } catch (SQLException ex) {
     throw new BlockStoreException(ex);
   } finally {
     if (s != null)
       try {
         s.close();
       } catch (SQLException e) {
         throw new BlockStoreException("Failed to close PreparedStatement");
       }
   }
 }
  public StoredUndoableBlock getUndoBlock(Sha256Hash hash) throws BlockStoreException {
    maybeConnect();
    PreparedStatement s = null;
    try {
      s =
          conn.get()
              .prepareStatement(
                  "SELECT txOutChanges, transactions FROM undoableBlocks WHERE hash = ?");
      // We skip the first 4 bytes because (on prodnet) the minimum target has 4 0-bytes

      byte[] hashBytes = new byte[28];
      System.arraycopy(hash.getBytes(), 3, hashBytes, 0, 28);
      s.setBytes(1, hashBytes);
      ResultSet results = s.executeQuery();
      if (!results.next()) {
        return null;
      }
      // Parse it.
      byte[] txOutChanges = results.getBytes(1);
      byte[] transactions = results.getBytes(2);
      StoredUndoableBlock block;
      if (txOutChanges == null) {
        int offset = 0;
        int numTxn =
            ((transactions[offset++] & 0xFF) << 0)
                | ((transactions[offset++] & 0xFF) << 8)
                | ((transactions[offset++] & 0xFF) << 16)
                | ((transactions[offset++] & 0xFF) << 24);
        List<Transaction> transactionList = new LinkedList<Transaction>();
        for (int i = 0; i < numTxn; i++) {
          Transaction tx = new Transaction(params, transactions, offset);
          transactionList.add(tx);
          offset += tx.getMessageSize();
        }
        block = new StoredUndoableBlock(hash, transactionList);
      } else {
        TransactionOutputChanges outChangesObject =
            new TransactionOutputChanges(new ByteArrayInputStream(txOutChanges));
        block = new StoredUndoableBlock(hash, outChangesObject);
      }
      return block;
    } catch (SQLException ex) {
      throw new BlockStoreException(ex);
    } catch (NullPointerException e) {
      // Corrupted database.
      throw new BlockStoreException(e);
    } catch (ClassCastException e) {
      // Corrupted database.
      throw new BlockStoreException(e);
    } catch (ProtocolException e) {
      // Corrupted database.
      throw new BlockStoreException(e);
    } catch (IOException e) {
      // Corrupted database.
      throw new BlockStoreException(e);
    } finally {
      if (s != null)
        try {
          s.close();
        } catch (SQLException e) {
          throw new BlockStoreException("Failed to close PreparedStatement");
        }
    }
  }
Ejemplo n.º 16
0
 @Override
 public void bitcoinSerializeToStream(OutputStream stream) throws IOException {
   stream.write(Utils.reverseBytes(hash.getBytes()));
 }
 public static ByteString hashToByteString(Sha256Hash hash) {
   return ByteString.copyFrom(hash.getBytes());
 }