/** * Gets a list of leaf hashes which are contained in the partial merkle tree in this filtered block * * @throws ProtocolException If the partial merkle block is invalid or the merkle root of the partial merkle block doesnt match the block header */ public AbstractMap.SimpleEntry<List<Sha256Hash>, List<Integer>> getTransactionHashesAndIndexes() throws VerificationException { if (cachedTransactionHashes != null && cachedTransactionPositions != null) return new AbstractMap.SimpleEntry<List<Sha256Hash>, List<Integer>>(Collections.unmodifiableList(cachedTransactionHashes), Collections.unmodifiableList(cachedTransactionPositions)); List<Sha256Hash> hashesMatched = new LinkedList<>(); List<Integer> positions = new LinkedList<>(); if (header.getMerkleRoot().equals(merkleTree.getTxnHashAndMerkleRoot(hashesMatched, positions))) { cachedTransactionHashes = hashesMatched; cachedTransactionPositions = positions; return new AbstractMap.SimpleEntry<>(Collections.unmodifiableList(cachedTransactionHashes), Collections.unmodifiableList(cachedTransactionPositions)); } else throw new VerificationException("Merkle root of block header does not match merkle root of partial merkle tree."); }
/** * Gets a list of leaf hashes which are contained in the partial merkle tree in this filtered block * * @throws ProtocolException If the partial merkle block is invalid or the merkle root of the partial merkle block doesnt match the block header */ public List<Sha256Hash> getTransactionHashes() throws VerificationException { if (cachedTransactionHashes != null) return Collections.unmodifiableList(cachedTransactionHashes); List<Sha256Hash> hashesMatched = new LinkedList<>(); if (header.getMerkleRoot().equals(merkleTree.getTxnHashAndMerkleRoot(hashesMatched))) { cachedTransactionHashes = hashesMatched; return Collections.unmodifiableList(cachedTransactionHashes); } else throw new VerificationException("Merkle root of block header does not match merkle root of partial merkle tree."); }
/** * Gets a list of leaf hashes which are contained in the partial merkle tree in this filtered block * * @throws ProtocolException If the partial merkle block is invalid or the merkle root of the partial merkle block doesnt match the block header */ public List<Sha256Hash> getTransactionHashes() throws VerificationException { if (cachedTransactionHashes != null) return Collections.unmodifiableList(cachedTransactionHashes); List<Sha256Hash> hashesMatched = new LinkedList<>(); List<Integer> positions = new LinkedList<>(); if (header.getMerkleRoot().equals(merkleTree.getTxnHashAndMerkleRoot(hashesMatched, positions))) { cachedTransactionHashes = hashesMatched; cachedTransactionPositions = positions; return Collections.unmodifiableList(cachedTransactionHashes); } else throw new VerificationException("Merkle root of block header does not match merkle root of partial merkle tree."); }
/** * Gets a list of leaf hashes which are contained in the partial merkle tree in this filtered block * * @throws ProtocolException If the partial merkle block is invalid or the merkle root of the partial merkle block doesnt match the block header */ public List<Sha256Hash> getTransactionHashes() throws VerificationException { if (cachedTransactionHashes != null) return Collections.unmodifiableList(cachedTransactionHashes); List<Sha256Hash> hashesMatched = new LinkedList<Sha256Hash>(); if (header.getMerkleRoot().equals(merkleTree.getTxnHashAndMerkleRoot(hashesMatched))) { cachedTransactionHashes = hashesMatched; return Collections.unmodifiableList(cachedTransactionHashes); } else throw new VerificationException("Merkle root of block header does not match merkle root of partial merkle tree."); }
/** * Gets a list of leaf hashes which are contained in the partial merkle tree in this filtered block * * @throws ProtocolException If the partial merkle block is invalid or the merkle root of the partial merkle block doesnt match the block header */ public List<Sha256Hash> getTransactionHashes() throws VerificationException { if (cachedTransactionHashes != null) return Collections.unmodifiableList(cachedTransactionHashes); List<Sha256Hash> hashesMatched = new LinkedList<Sha256Hash>(); if (header.getMerkleRoot().equals(merkleTree.getTxnHashAndMerkleRoot(hashesMatched))) { cachedTransactionHashes = hashesMatched; return Collections.unmodifiableList(cachedTransactionHashes); } else throw new VerificationException("Merkle root of block header does not match merkle root of partial merkle tree."); }
@Test(expected = VerificationException.class) public void merkleTreeMalleability() throws Exception { List<Sha256Hash> hashes = Lists.newArrayList(); for (byte i = 1; i <= 10; i++) hashes.add(numAsHash(i)); hashes.add(numAsHash(9)); hashes.add(numAsHash(10)); byte[] includeBits = new byte[2]; Utils.setBitLE(includeBits, 9); Utils.setBitLE(includeBits, 10); PartialMerkleTree pmt = PartialMerkleTree.buildFromLeaves(PARAMS, includeBits, hashes); List<Sha256Hash> matchedHashes = Lists.newArrayList(); pmt.getTxnHashAndMerkleRoot(matchedHashes); }