public static Friend addFriend(Friend new_friend) { if (friends.Find(x => x.walletAddress.SequenceEqual(new_friend.walletAddress)) != null) { // Already in the list return(null); } // Add new friend to the friendlist friends.Add(new_friend); Node.shouldRefreshContacts = true; if (new_friend.approved) { lock (friendMatcher) { if (friendMatcher.Add(new_friend.walletAddress) == Cuckoo.CuckooStatus.NotEnoughSpace) { // rebuild cuckoo filter with a larger size friendMatcher = new Cuckoo(friendMatcher.numItems * 2); foreach (Friend f in friends) { friendMatcher.Add(f.walletAddress); } } } ProtocolMessage.resubscribeEvents(); } sortFriends(); return(new_friend); }
/// <summary> /// Subscribes client to transactionFrom, transactionTo and balance /// </summary> /// <remarks> /// This function is used to ensure that the remote endpoing has listed the correct IP and port information for their `PresenceList` entry. /// </remarks> /// <param name="endpoint">Target endpoint to verify for connectivity.</param> public static void subscribeToEvents(RemoteEndpoint endpoint) { if (endpoint.presenceAddress.type != 'M') { return; } // TODO TODO TODO events can be optimized as there is no real need to subscribe them to every connected node // Subscribe to transaction events, for own addresses var my_addresses = IxianHandler.getWalletStorage().getMyAddresses(); Cuckoo filter = new Cuckoo(my_addresses.Count()); foreach (var addr in my_addresses) { filter.Add(addr.address); } byte[] filter_data = filter.getFilterBytes(); byte[] event_data = NetworkEvents.prepareEventMessageData(NetworkEvents.Type.transactionFrom, filter_data); endpoint.sendData(ProtocolMessageCode.attachEvent, event_data); event_data = NetworkEvents.prepareEventMessageData(NetworkEvents.Type.transactionTo, filter_data); endpoint.sendData(ProtocolMessageCode.attachEvent, event_data); event_data = NetworkEvents.prepareEventMessageData(NetworkEvents.Type.balance, filter_data); endpoint.sendData(ProtocolMessageCode.attachEvent, event_data); }
/// <summary> /// Requests PIT for the specified block from a random connected neighbor node. /// Nominally, only the transactions included in `txids` need to be verifiable with the PIT, but /// due to how Cuckoo filtering works, some false positives will also be included. This helps with anonymization, if the false positive rate is high enough. /// </summary> /// <param name="block_num">Block number for which the PIT should be included.</param> /// <param name="txids">List of interesting transactions, which we wish to verify.</param> private void requestPITForBlock(ulong block_num, List <string> txids) { lock (pitCache) { long currentTime = Clock.getTimestamp(); // Request might already have been sent. In that case, we re-send it we have been waiting for too long. if (!pitCache.ContainsKey(block_num) || currentTime - pitCache[block_num].requestSent > pitRequestTimeout) { Cuckoo filter = new Cuckoo(txids.Count); foreach (var tx in txids) { filter.Add(Encoding.UTF8.GetBytes(tx)); } byte[] filter_bytes = filter.getFilterBytes(); MemoryStream m = new MemoryStream(filter_bytes.Length + 12); using (BinaryWriter w = new BinaryWriter(m, Encoding.UTF8, true)) { w.Write(block_num); w.Write(filter_bytes.Length); w.Write(filter_bytes); } CoreProtocolMessage.broadcastProtocolMessageToSingleRandomNode(new char[] { 'M' }, ProtocolMessageCode.getPIT, m.ToArray(), 0); PITCacheItem ci = new PITCacheItem() { pit = null, requestedForTXIDs = txids, requestSent = Clock.getTimestamp() }; pitCache.AddOrReplace(block_num, ci); } } }
public void trivialSanityTest() { Cuckoo cuckoo = new Cuckoo(100); byte[] item = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 }; Assert.IsFalse(cuckoo.Contains(item)); }
public void serializeDeserializeSmall() { SortedSet <byte[]> items = null; Cuckoo cuckoo = generateLargeCuckoo(20, 100, ref items); Stopwatch sw = new Stopwatch(); sw.Start(); byte[] serialized_cuckoo = cuckoo.getFilterBytes(); sw.Stop(); Trace.WriteLine(String.Format("Serializing cuckoo filter with {0} elements took {1} ms and yielded {2} bytes.", cuckoo.numItems, sw.ElapsedMilliseconds, serialized_cuckoo.Length)); sw.Start(); Cuckoo cuckoo2 = new Cuckoo(serialized_cuckoo); sw.Stop(); Trace.WriteLine(String.Format("Deserializing cuckoo filter took {0} ms.", sw.ElapsedMilliseconds)); // make sure all items are in the filter foreach (var i in items) { Assert.IsTrue(cuckoo2.Contains(i)); } }
private Cuckoo generateLargeCuckoo(int min_items, int max_items, ref SortedSet <byte[]> items) { int cap = RNG.Next(min_items, max_items); items = new SortedSet <byte[]>(new ByteArrayComparer()); Cuckoo cuckoo = new Cuckoo(cap); while (true) { byte[] item = new byte[32]; RNG.NextBytes(item); if (items.Contains(item)) { continue; } if (cuckoo.Add(item) == Cuckoo.CuckooStatus.NotEnoughSpace) { cuckoo.Add(item); Assert.IsTrue(cuckoo.numItems >= cap, "Cuckoo should accept at least its constructed capacity."); break; } items.Add(item); } return(cuckoo); }
private void PerformMoveCalculations(int depth) { Bitmap board = PieceFinderViewModel.GetInstance().FindPieces(this.GameBoard); // Ensure kings are on the board and game state makes some degree of sense if (!this.PassesSanityChecks()) { return; } DateTime startTime = DateTime.Now; string nextMove = string.Empty; // Calculate best move string newFen = this.GameBoard.GenerateFEN(); if (newFen != this.LastFen) { // Use the engine to calculate the next best move nextMove = Cuckoo.simplyCalculateMove(newFen, depth); // Inform view of updates this.UpdateBoardCallback(board, nextMove, EngineViewModel.GetInstance().PlayingWhite); this.LastFen = newFen; } TimeSpan elapsedTime = DateTime.Now - startTime; }
public void addItem() { Cuckoo cuckoo = new Cuckoo(100); byte[] item = new byte[32]; RNG.NextBytes(item); cuckoo.Add(item); Assert.IsTrue(cuckoo.Contains(item)); }
public void fillToCapacity() { SortedSet <byte[]> items = null; Cuckoo cuckoo = generateLargeCuckoo(2000, 4000, ref items); foreach (var i in items) { Assert.IsTrue(cuckoo.Contains(i), "Cuckoo should contain all items which were inserted."); } }
// Subscribe to event public bool attachEvent(NetworkEvents.Type type, byte[] filter) { if (address == null) { return(false); } lock (subscribedFilters) { // Check the quota int num_subscribed_addresses = subscribedFilters.Values.Aggregate(0, (acc, f) => acc + f.numItems); if (num_subscribed_addresses > CoreConfig.maximumSubscribableEvents) { return(false); } } Cuckoo cuckoo_filter = null; try { cuckoo_filter = new Cuckoo(filter); } catch (Exception) { Logging.warn("Error while attempting to replace {0} filter for endpoint {1}", type.ToString(), getFullAddress() ); return(false); } if (cuckoo_filter == null) { Logging.warn("Cannot attach event {0} to Remote Endpoint {1}, cuckoo filter is null.", type.ToString(), getFullAddress() ); return(false); } lock (subscribedFilters) { // Subscribing a new cuckoo for a particular event type will replace the old one subscribedFilters.AddOrReplace(type, cuckoo_filter); } return(true); }
public void Test() { Cuckoo c = new Cuckoo(); IOptiTestFunc f = new Weierstrass(); c.dimension = 10; c.searchSpace = f.SearchSpace; double[] res = c.Opti(f.Func); double val = f.Func(res); Assert.AreEqual(f.MinimumValue, val, 5); c = new Cuckoo(); f = new SumSquares(); c.dimension = 10; c.searchSpace = f.SearchSpace; res = c.Opti(f.Func); val = f.Func(res); Assert.AreEqual(f.MinimumValue, val, 5); }
public static void handleGetPIT2(byte[] data, RemoteEndpoint endpoint) { MemoryStream ms = new MemoryStream(data); using (BinaryReader r = new BinaryReader(ms)) { ulong block_num = r.ReadIxiVarUInt(); int filter_len = (int)r.ReadIxiVarUInt(); byte[] filter = r.ReadBytes(filter_len); Cuckoo cf; try { cf = new Cuckoo(filter); } catch (Exception) { Logging.warn("The Cuckoo filter in the getPIT message was invalid or corrupted!"); return; } Block b = Node.blockChain.getBlock(block_num, true, true); if (b is null) { return; } if (b.version < BlockVer.v6) { Logging.warn("Neighbor {0} requested PIT information for block {0}, which was below the minimal PIT version.", endpoint.fullAddress, block_num); return; } PrefixInclusionTree pit = new PrefixInclusionTree(44, 3); List <byte[]> interesting_transactions = new List <byte[]>(); foreach (var tx in b.transactions) { if (b.version < BlockVer.v8) { pit.add(UTF8Encoding.UTF8.GetBytes(Transaction.txIdV8ToLegacy(tx))); if (cf.Contains(tx)) { interesting_transactions.Add(UTF8Encoding.UTF8.GetBytes(Transaction.txIdV8ToLegacy(tx))); } } else { pit.add(tx); if (cf.Contains(tx)) { interesting_transactions.Add(tx); } } } // make sure we ended up with the correct PIT if (!b.pitChecksum.SequenceEqual(pit.calculateTreeHash())) { // This is a serious error, but I am not sure how to respond to it right now. Logging.error("Reconstructed PIT for block {0} does not match the checksum in block header!", block_num); return; } byte[] minimal_pit = pit.getMinimumTreeTXList(interesting_transactions); MemoryStream mOut = new MemoryStream(minimal_pit.Length + 12); using (BinaryWriter w = new BinaryWriter(mOut, Encoding.UTF8, true)) { w.WriteIxiVarInt(block_num); w.WriteIxiVarInt(minimal_pit.Length); w.Write(minimal_pit); } endpoint.sendData(ProtocolMessageCode.pitData2, mOut.ToArray()); } }