// Create from a CBlock, filtering transactions according to filter // Note that this will call IsRelevantAndUpdate on the filter for each transaction, // thus the filter will likely be modified. public MerkleBlock(Block block, BloomFilter filter) { header = block.Header; List<bool> vMatch = new List<bool>(); List<uint256> vHashes = new List<uint256>(); for(uint i = 0 ; i < block.Transactions.Count ; i++) { uint256 hash = block.Transactions[(int)i].GetHash(); vMatch.Add(filter.IsRelevantAndUpdate(block.Transactions[(int)i])); vHashes.Add(hash); } _PartialMerkleTree = new PartialMerkleTree(vHashes.ToArray(), vMatch.ToArray()); }
// Create from a CBlock, filtering transactions according to filter // Note that this will call IsRelevantAndUpdate on the filter for each transaction, // thus the filter will likely be modified. public MerkleBlock(Block block, BloomFilter filter) { header = block.Header; List<bool> vMatch = new List<bool>(); List<uint256> vHashes = new List<uint256>(); for(uint i = 0 ; i < block.Transactions.Length ; i++) { uint256 hash = block.Transactions[i].GetHash(); if(filter.IsRelevantAndUpdate(block.Transactions[i])) { vMatch.Add(true); vMatchedTxn.Add(Tuple.Create(i, hash)); } else vMatch.Add(false); vHashes.Add(hash); } txn = new PartialMerkleTree(vHashes.ToArray(), vMatch.ToArray()); }
public MerkleBlock Filter(BloomFilter filter) { return new MerkleBlock(this, filter); }
public void CanGetMerkleRoot() { using(var node = Node.ConnectToLocal(Network.TestNet, isRelay: false)) { var knownBlock = uint256.Parse("00000000db9a24016f87f98ddaf08d32383319431d27c37dee2c91898ef57066"); var knownTx = uint256.Parse("dabf4960a5c6d9affec746734cbd8ba68287126b8c4514de846a9702a813a449"); node.VersionHandshake(); using(var list = node.CreateListener() .Where(m => m.Message.Payload is MerkleBlockPayload || m.Message.Payload is TxPayload)) { BloomFilter filter = new BloomFilter(1, 0.005, 50, BloomFlags.UPDATE_NONE); filter.Insert(((BitcoinPubKeyAddress)BitcoinAddress.Create("mwdJkHRNJi1fEwHBx6ikWFFuo2rLBdri2h", Network.TestNet)).Hash.ToBytes()); node.SendMessageAsync(new FilterLoadPayload(filter)); node.SendMessageAsync(new GetDataPayload(new InventoryVector(InventoryType.MSG_FILTERED_BLOCK, knownBlock))); var merkle = list.ReceivePayload<MerkleBlockPayload>(); var tree = merkle.Object.PartialMerkleTree; Assert.True(tree.Check(uint256.Parse("89b905cdf2ab70c1acd9b538cf6738937ae28fca86c1514ebbf130962312e478"))); Assert.True(tree.GetMatchedTransactions().Count() > 1); Assert.True(tree.GetMatchedTransactions().Contains(knownTx)); List<Transaction> matched = new List<Transaction>(); for(int i = 0 ; i < tree.GetMatchedTransactions().Count() ; i++) { matched.Add(list.ReceivePayload<TxPayload>().Object); } Assert.True(matched.Count > 1); tree = tree.Trim(knownTx); Assert.True(tree.GetMatchedTransactions().Count() == 1); Assert.True(tree.GetMatchedTransactions().Contains(knownTx)); Action act = () => { foreach(var match in matched) { Assert.True(filter.IsRelevantAndUpdate(match)); } }; act(); filter = filter.Clone(); act(); var unknownBlock = uint256.Parse("00000000ad262227291eaf90cafdc56a8f8451e2d7653843122c5bb0bf2dfcdd"); node.SendMessageAsync(new GetDataPayload(new InventoryVector(InventoryType.MSG_FILTERED_BLOCK, Network.TestNet.GetGenesis().GetHash()))); merkle = list.ReceivePayload<MerkleBlockPayload>(); tree = merkle.Object.PartialMerkleTree; Assert.True(tree.Check(merkle.Object.Header.HashMerkleRoot)); Assert.True(!tree.GetMatchedTransactions().Contains(knownTx)); } } }
public MerkleBlock Filter(BloomFilter filter) { return(new MerkleBlock(this, filter)); }