public void BuildFilterAndMatchValues() { var names = from name in new[] { "New York", "Amsterdam", "Paris", "Buenos Aires", "La Habana" } select Encoding.ASCII.GetBytes(name); var key = Hashes.Hash256(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }); var filter = new GolombRiceFilterBuilder() .SetKey(key) .AddEntries(names) .SetP(0x10) .Build(); var testKey = key.ToBytes().SafeSubarray(0, 16); // The filter should match all the values that were added. foreach (var name in names) { Assert.True(filter.Match(name, testKey)); } // The filter should NOT match any extra value. Assert.False(filter.Match(Encoding.ASCII.GetBytes("Porto Alegre"), testKey)); Assert.False(filter.Match(Encoding.ASCII.GetBytes("Madrid"), testKey)); // The filter should match because it has one element indexed: Buenos Aires. var otherCities = new[] { "La Paz", "Barcelona", "El Cairo", "Buenos Aires", "Asunción" }; var otherNames = from name in otherCities select Encoding.ASCII.GetBytes(name); Assert.True(filter.MatchAny(otherNames, testKey)); // The filter should NOT match because it doesn't have any element indexed. var otherCities2 = new[] { "La Paz", "Barcelona", "El Cairo", "Córdoba", "Asunción" }; var otherNames2 = from name in otherCities2 select Encoding.ASCII.GetBytes(name); Assert.False(filter.MatchAny(otherNames2, testKey)); }
public void EdgeCaseSipHashEqualZero() { var dummyScriptPubKey = Encoders.Hex.DecodeData("0009BBE4C2D17185643765C265819BF5261755247D"); var blockHash = Encoders.Hex.DecodeData("CB4D1D1ED725B888173BEF553BBE2BF4237B42364BC90638F0CB040F87B57CD4"); var filter = new GolombRiceFilterBuilder() .SetKey(new uint256(blockHash)) .SetP(20) .SetM(1 << 20) .AddEntries(new[] { dummyScriptPubKey }) .Build(); var scriptPubKey = Encoders.Hex.DecodeData("D432CB07482718ECE932DA6914D1FDC1A8EACE3F127D"); var key = blockHash.SafeSubarray(0, 16); Assert.False(filter.Match(scriptPubKey, key)); }
public void CanSupportCustomeFiltersTest() { var blockHex = File.ReadAllText("./data/block-testnet-828575.txt"); var block = Block.Parse(blockHex, Network.TestNet); var scripts = new HashSet <Script>(); foreach (var tx in block.Transactions) { for (int i = 0; i < tx.Outputs.Count; i++) { var output = tx.Outputs[i]; if (!output.ScriptPubKey.IsScriptType(ScriptType.P2SH) && output.ScriptPubKey.IsScriptType(ScriptType.Witness)) { var outpoint = new OutPoint(tx.GetHash(), i); scripts.Add(output.ScriptPubKey); } } } var key = block.GetHash(); var testkey = key.ToBytes().SafeSubarray(0, 16); var filter = new GolombRiceFilterBuilder() .SetP(20) .SetM(1U << 20) .SetKey(key) .AddEntries(scripts.Select(x => x.ToCompressedBytes())) .Build(); Assert.Equal("017821b8", filter.ToString()); foreach (var tx in block.Transactions) { for (int i = 0; i < tx.Outputs.Count; i++) { var output = tx.Outputs[i]; if (!output.ScriptPubKey.IsScriptType(ScriptType.P2SH) && output.ScriptPubKey.IsScriptType(ScriptType.Witness)) { Assert.True(filter.Match(output.ScriptPubKey.ToCompressedBytes(), testkey)); } } } }
public void CanHandleCustomPandMValuesTest() { var byteArray0 = new byte[] { 1, 2, 3, 4 }; var byteArray1 = new byte[] { 2, 3, 4 }; var byteArray2 = new byte[] { 3, 4 }; var key = Hashes.Hash256(new byte[] { 99, 99, 99, 99 }); var testKey = key.ToBytes().SafeSubarray(0, 16); var filter = new GolombRiceFilterBuilder() .SetKey(key) .SetP(10) .SetM(1U << 10) .AddEntries(new[] { byteArray0, byteArray1, byteArray2 }) .AddScriptPubkey(Script.FromBytesUnsafe(byteArray0)) .AddScriptPubkey(Script.FromBytesUnsafe(byteArray1)) .AddScriptPubkey(Script.FromBytesUnsafe(byteArray2)) .Build(); var filterSize10_10 = filter.ToBytes().Length; Assert.Equal(3, filter.N); Assert.Equal(10, filter.P); Assert.Equal(1U << 10, filter.M); Assert.True(filter.Match(byteArray0, testKey)); Assert.True(filter.Match(byteArray1, testKey)); Assert.True(filter.Match(byteArray2, testKey)); Assert.False(filter.Match(new byte[] { 6, 7, 8 }, testKey)); filter = new GolombRiceFilterBuilder() .SetKey(key) .SetP(10) .SetM(1U << 4) .AddEntries(new[] { byteArray0, byteArray1, byteArray2 }) .AddScriptPubkey(Script.FromBytesUnsafe(byteArray0)) .AddScriptPubkey(Script.FromBytesUnsafe(byteArray1)) .AddScriptPubkey(Script.FromBytesUnsafe(byteArray2)) .Build(); var filterSize10_4 = filter.ToBytes().Length; Assert.Equal(3, filter.N); Assert.Equal(10, filter.P); Assert.Equal(1U << 4, filter.M); Assert.True(filter.Match(byteArray0, testKey)); Assert.True(filter.Match(byteArray1, testKey)); Assert.True(filter.Match(byteArray2, testKey)); Assert.False(filter.Match(new byte[] { 6, 7, 8 }, testKey)); Assert.Equal(filterSize10_4, filterSize10_10); filter = new GolombRiceFilterBuilder() .SetKey(key) .SetP(8) .SetM(1U << 4) .AddEntries(new[] { byteArray0, byteArray1, byteArray2 }) .AddScriptPubkey(Script.FromBytesUnsafe(byteArray0)) .AddScriptPubkey(Script.FromBytesUnsafe(byteArray1)) .AddScriptPubkey(Script.FromBytesUnsafe(byteArray2)) .Build(); var filterSize8_4 = filter.ToBytes().Length; Assert.Equal(3, filter.N); Assert.Equal(8, filter.P); Assert.Equal(1U << 4, filter.M); Assert.True(filter.Match(byteArray0, testKey)); Assert.True(filter.Match(byteArray1, testKey)); Assert.True(filter.Match(byteArray2, testKey)); Assert.False(filter.Match(new byte[] { 6, 7, 8 }, testKey)); Assert.True(filterSize8_4 < filterSize10_10); // filter size depends only on P parameter }