/** Insert the given arbitrary data into the filter */ public synchronized void insert(byte[] object) { for (int i = 0; i < hashFuncs; i++) Utils.setBitLE(data, murmurHash3(data, nTweak, i, object)); }
/** Insert the given arbitrary data into the filter */ public synchronized void insert(byte[] object) { for (int i = 0; i < hashFuncs; i++) Utils.setBitLE(data, murmurHash3(data, nTweak, i, object)); }
/** Insert the given arbitrary data into the filter */ public synchronized void insert(byte[] object) { for (int i = 0; i < hashFuncs; i++) Utils.setBitLE(data, murmurHash3(data, nTweak, i, object)); }
/** Insert the given arbitrary data into the filter */ public synchronized void insert(byte[] object) { for (int i = 0; i < hashFuncs; i++) Utils.setBitLE(data, murmurHash3(data, nTweak, i, object)); }
/** * Provide an array of output objects, with nulls indicating that the output was missing. The bitset will * be calculated from this. */ public UTXOsMessage(NetworkParameters params, List<TransactionOutput> outputs, long[] heights, Sha256Hash chainHead, long height) { super(params); hits = new byte[(int) Math.ceil(outputs.size() / 8.0)]; for (int i = 0; i < outputs.size(); i++) { if (outputs.get(i) != null) Utils.setBitLE(hits, i); } this.outputs = new ArrayList<>(outputs.size()); for (TransactionOutput output : outputs) { if (output != null) this.outputs.add(output); } this.chainHead = chainHead; this.height = height; this.heights = Arrays.copyOf(heights, heights.length); }
/** * Provide an array of output objects, with nulls indicating that the output was missing. The bitset will * be calculated from this. */ public UTXOsMessage(NetworkParameters params, List<TransactionOutput> outputs, long[] heights, Sha256Hash chainHead, long height) { super(params); hits = new byte[(int) Math.ceil(outputs.size() / 8.0)]; for (int i = 0; i < outputs.size(); i++) { if (outputs.get(i) != null) Utils.setBitLE(hits, i); } this.outputs = new ArrayList<TransactionOutput>(outputs.size()); for (TransactionOutput output : outputs) { if (output != null) this.outputs.add(output); } this.chainHead = chainHead; this.height = height; this.heights = Arrays.copyOf(heights, heights.length); }
/** * Provide an array of output objects, with nulls indicating that the output was missing. The bitset will * be calculated from this. */ public UTXOsMessage(NetworkParameters params, List<TransactionOutput> outputs, long[] heights, Sha256Hash chainHead, long height) { super(params); hits = new byte[(int) Math.ceil(outputs.size() / 8.0)]; for (int i = 0; i < outputs.size(); i++) { if (outputs.get(i) != null) Utils.setBitLE(hits, i); } this.outputs = new ArrayList<>(outputs.size()); for (TransactionOutput output : outputs) { if (output != null) this.outputs.add(output); } this.chainHead = chainHead; this.height = height; this.heights = Arrays.copyOf(heights, heights.length); }
/** * Provide an array of output objects, with nulls indicating that the output was missing. The bitset will * be calculated from this. */ public UTXOsMessage(NetworkParameters params, List<TransactionOutput> outputs, long[] heights, Sha256Hash chainHead, long height) { super(params); hits = new byte[(int) Math.ceil(outputs.size() / 8.0)]; for (int i = 0; i < outputs.size(); i++) { if (outputs.get(i) != null) Utils.setBitLE(hits, i); } this.outputs = new ArrayList<TransactionOutput>(outputs.size()); for (TransactionOutput output : outputs) { if (output != null) this.outputs.add(output); } this.chainHead = chainHead; this.height = height; this.heights = Arrays.copyOf(heights, heights.length); }
/** * Calculates a PMT given the list of leaf hashes and which leaves need to be included. The relevant interior hashes * are calculated and a new PMT returned. */ public static PartialMerkleTree buildFromLeaves(NetworkParameters params, byte[] includeBits, List<Sha256Hash> allLeafHashes) { // Calculate height of the tree. int height = 0; while (getTreeWidth(allLeafHashes.size(), height) > 1) height++; List<Boolean> bitList = new ArrayList<Boolean>(); List<Sha256Hash> hashes = new ArrayList<Sha256Hash>(); traverseAndBuild(height, 0, allLeafHashes, includeBits, bitList, hashes); byte[] bits = new byte[(int)Math.ceil(bitList.size() / 8.0)]; for (int i = 0; i < bitList.size(); i++) if (bitList.get(i)) Utils.setBitLE(bits, i); return new PartialMerkleTree(params, bits, hashes, allLeafHashes.size()); }
/** * Calculates a PMT given the list of leaf hashes and which leaves need to be included. The relevant interior hashes * are calculated and a new PMT returned. */ public static PartialMerkleTree buildFromLeaves(NetworkParameters params, byte[] includeBits, List<Sha256Hash> allLeafHashes) { // Calculate height of the tree. int height = 0; while (getTreeWidth(allLeafHashes.size(), height) > 1) height++; List<Boolean> bitList = new ArrayList<>(); List<Sha256Hash> hashes = new ArrayList<>(); traverseAndBuild(height, 0, allLeafHashes, includeBits, bitList, hashes); byte[] bits = new byte[(int)Math.ceil(bitList.size() / 8.0)]; for (int i = 0; i < bitList.size(); i++) if (bitList.get(i)) Utils.setBitLE(bits, i); return new PartialMerkleTree(params, bits, hashes, allLeafHashes.size()); }
/** * Calculates a PMT given the list of leaf hashes and which leaves need to be included. The relevant interior hashes * are calculated and a new PMT returned. */ public static PartialMerkleTree buildFromLeaves(NetworkParameters params, byte[] includeBits, List<Sha256Hash> allLeafHashes) { // Calculate height of the tree. int height = 0; while (getTreeWidth(allLeafHashes.size(), height) > 1) height++; List<Boolean> bitList = new ArrayList<Boolean>(); List<Sha256Hash> hashes = new ArrayList<Sha256Hash>(); traverseAndBuild(height, 0, allLeafHashes, includeBits, bitList, hashes); byte[] bits = new byte[(int)Math.ceil(bitList.size() / 8.0)]; for (int i = 0; i < bitList.size(); i++) if (bitList.get(i)) Utils.setBitLE(bits, i); return new PartialMerkleTree(params, bits, hashes, allLeafHashes.size()); }
/** * Calculates a PMT given the list of leaf hashes and which leaves need to be included. The relevant interior hashes * are calculated and a new PMT returned. */ public static PartialMerkleTree buildFromLeaves(NetworkParameters params, byte[] includeBits, List<Sha256Hash> allLeafHashes) { // Calculate height of the tree. int height = 0; while (getTreeWidth(allLeafHashes.size(), height) > 1) height++; List<Boolean> bitList = new ArrayList<>(); List<Sha256Hash> hashes = new ArrayList<>(); traverseAndBuild(height, 0, allLeafHashes, includeBits, bitList, hashes); byte[] bits = new byte[(int)Math.ceil(bitList.size() / 8.0)]; for (int i = 0; i < bitList.size(); i++) if (bitList.get(i)) Utils.setBitLE(bits, i); return new PartialMerkleTree(params, bits, hashes, allLeafHashes.size()); }
/** * Creates a new FilteredBlock from the given Block, using this filter to select transactions. Matches can cause the * filter to be updated with the matched element, this ensures that when a filter is applied to a block, spends of * matched transactions are also matched. However it means this filter can be mutated by the operation. The returned * filtered block already has the matched transactions associated with it. */ public synchronized FilteredBlock applyAndUpdate(Block block) { List<Transaction> txns = block.getTransactions(); List<Sha256Hash> txHashes = new ArrayList<Sha256Hash>(txns.size()); List<Transaction> matched = Lists.newArrayList(); byte[] bits = new byte[(int) Math.ceil(txns.size() / 8.0)]; for (int i = 0; i < txns.size(); i++) { Transaction tx = txns.get(i); txHashes.add(tx.getHash()); if (applyAndUpdate(tx)) { Utils.setBitLE(bits, i); matched.add(tx); } } PartialMerkleTree pmt = PartialMerkleTree.buildFromLeaves(block.getParams(), bits, txHashes); FilteredBlock filteredBlock = new FilteredBlock(block.getParams(), block.cloneAsHeader(), pmt); for (Transaction transaction : matched) filteredBlock.provideTransaction(transaction); return filteredBlock; }
/** * Creates a new FilteredBlock from the given Block, using this filter to select transactions. Matches can cause the * filter to be updated with the matched element, this ensures that when a filter is applied to a block, spends of * matched transactions are also matched. However it means this filter can be mutated by the operation. The returned * filtered block already has the matched transactions associated with it. */ public synchronized FilteredBlock applyAndUpdate(Block block) { List<Transaction> txns = block.getTransactions(); List<Sha256Hash> txHashes = new ArrayList<>(txns.size()); List<Transaction> matched = Lists.newArrayList(); byte[] bits = new byte[(int) Math.ceil(txns.size() / 8.0)]; for (int i = 0; i < txns.size(); i++) { Transaction tx = txns.get(i); txHashes.add(tx.getHash()); if (applyAndUpdate(tx)) { Utils.setBitLE(bits, i); matched.add(tx); } } PartialMerkleTree pmt = PartialMerkleTree.buildFromLeaves(block.getParams(), bits, txHashes); FilteredBlock filteredBlock = new FilteredBlock(block.getParams(), block.cloneAsHeader(), pmt); for (Transaction transaction : matched) filteredBlock.provideTransaction(transaction); return filteredBlock; }
/** * Creates a new FilteredBlock from the given Block, using this filter to select transactions. Matches can cause the * filter to be updated with the matched element, this ensures that when a filter is applied to a block, spends of * matched transactions are also matched. However it means this filter can be mutated by the operation. The returned * filtered block already has the matched transactions associated with it. */ public synchronized FilteredBlock applyAndUpdate(Block block) { List<Transaction> txns = block.getTransactions(); List<Sha256Hash> txHashes = new ArrayList<Sha256Hash>(txns.size()); List<Transaction> matched = Lists.newArrayList(); byte[] bits = new byte[(int) Math.ceil(txns.size() / 8.0)]; for (int i = 0; i < txns.size(); i++) { Transaction tx = txns.get(i); txHashes.add(tx.getHash()); if (applyAndUpdate(tx)) { Utils.setBitLE(bits, i); matched.add(tx); } } PartialMerkleTree pmt = PartialMerkleTree.buildFromLeaves(block.getParams(), bits, txHashes); FilteredBlock filteredBlock = new FilteredBlock(block.getParams(), block.cloneAsHeader(), pmt); for (Transaction transaction : matched) filteredBlock.provideTransaction(transaction); return filteredBlock; }
/** * Creates a new FilteredBlock from the given Block, using this filter to select transactions. Matches can cause the * filter to be updated with the matched element, this ensures that when a filter is applied to a block, spends of * matched transactions are also matched. However it means this filter can be mutated by the operation. The returned * filtered block already has the matched transactions associated with it. */ public synchronized FilteredBlock applyAndUpdate(Block block) { List<Transaction> txns = block.getTransactions(); List<Sha256Hash> txHashes = new ArrayList<>(txns.size()); List<Transaction> matched = Lists.newArrayList(); byte[] bits = new byte[(int) Math.ceil(txns.size() / 8.0)]; for (int i = 0; i < txns.size(); i++) { Transaction tx = txns.get(i); txHashes.add(tx.getHash()); if (applyAndUpdate(tx)) { Utils.setBitLE(bits, i); matched.add(tx); } } PartialMerkleTree pmt = PartialMerkleTree.buildFromLeaves(block.getParams(), bits, txHashes); FilteredBlock filteredBlock = new FilteredBlock(block.getParams(), block.cloneAsHeader(), pmt); for (Transaction transaction : matched) filteredBlock.provideTransaction(transaction); return filteredBlock; }
@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); }