public void Setup() { var keyBuffer = new byte[32]; _random.NextBytes(keyBuffer); var key = new uint256(keyBuffer); _testKey = key.ToBytes().Take(16).ToArray(); var builder = new GolombRiceFilterBuilder() .SetKey(key) .SetP(20); var itemsInFilter = new List <byte[]>(); for (var j = 0; j < N; j++) { var data = new byte[_random.Next(20, 30)]; _random.NextBytes(data); itemsInFilter.Add(data); } builder.AddEntries(itemsInFilter); _sample = itemsInFilter.OrderBy(x => _random.Next()).Take(N / 200).ToArray(); _filter = builder.Build(); }
private FilterModel CreateFiltersWith(IEnumerable <byte[]> scripts) { var keyBuffer = new byte[32]; Random.NextBytes(keyBuffer); var blockHash = new uint256(keyBuffer); var builder = new GolombRiceFilterBuilder() .SetKey(blockHash) .SetP(20); builder.AddEntries(scripts); return(new FilterModel( new SmartHeader(new uint256(blockHash), uint256.One, 0, DateTimeOffset.UtcNow), builder.Build())); }
private FilterModel CreateFiltersWith(IEnumerable <byte[]> scripts) { var keyBuffer = new byte[32]; Random.NextBytes(keyBuffer); var blockHash = new uint256(keyBuffer); var builder = new GolombRiceFilterBuilder() .SetKey(blockHash) .SetP(20); builder.AddEntries(scripts); return(new FilterModel { BlockHeight = 0, BlockHash = new uint256(blockHash), Filter = builder.Build() }); }
public void Setup() { var random = new Random(Seed: 145); var keyBuffer = new byte[32]; random.NextBytes(keyBuffer); var key = new uint256(keyBuffer); _builder = new GolombRiceFilterBuilder() .SetKey(key) .SetP(20); _itemsInFilter = new List <byte[]>(); for (var j = 0; j < N; j++) { var data = new byte[random.Next(20, 30)]; random.NextBytes(data); _itemsInFilter.Add(data); } _builder.AddEntries(_itemsInFilter); }
public void FalsePositivesTest() { // Given this library can be used for building and query filters for each block of // the bitcoin's blockchain, we must be sure it performs well, specially in the queries. // Considering a 4MB block (overestimated) with an average transaction size of 250 bytes (underestimated) // gives us 16000 transactions (this is about 27 tx/sec). Assuming 2.5 txouts per tx we have 83885 txouts // per block. const byte P = 20; const int blockCount = 100; const int maxBlockSize = 4_000_000; const int avgTxSize = 250; // Currently the average is around 1kb. const int txoutCountPerBlock = maxBlockSize / avgTxSize; const int avgTxoutPushDataSize = 20; // P2PKH scripts has 20 bytes. const int walletAddressCount = 1_000; // We estimate that our user will have 1000 addresses. var key = Hashes.Hash256(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }); var testKey = key.ToBytes().SafeSubarray(0, 16); // Generation of data to be added into the filter var random = new Random(); var blocks = new List <BlockFilter>(blockCount); for (var i = 0; i < blockCount; i++) { var builder = new GolombRiceFilterBuilder() .SetKey(key) .SetP(P); var txouts = new List <byte[]>(txoutCountPerBlock); for (var j = 0; j < txoutCountPerBlock; j++) { var pushDataBuffer = new byte[avgTxoutPushDataSize]; random.NextBytes(pushDataBuffer); txouts.Add(pushDataBuffer); } builder.AddEntries(txouts); var filter = builder.Build(); blocks.Add(new BlockFilter(filter, txouts)); } var walletAddresses = new List <byte[]>(walletAddressCount); var falsePositiveCount = 0; for (var i = 0; i < walletAddressCount; i++) { var walletAddress = new byte[avgTxoutPushDataSize]; random.NextBytes(walletAddress); walletAddresses.Add(walletAddress); } // Check that the filter can match every single txout in every block. foreach (var block in blocks) { if (block.Filter.MatchAny(walletAddresses, testKey)) { falsePositiveCount++; } } Assert.True(falsePositiveCount < 5); // Filter has to mat existing values var falseNegativeCount = 0; // Check that the filter can match every single txout in every block. foreach (var block in blocks) { if (!block.Filter.MatchAny(block.Data, testKey)) { falseNegativeCount++; } } Assert.Equal(0, falseNegativeCount); }