/// <summary> /// Attempt to find the value in the peer network. /// </summary> /// <returns>A null contact list is acceptable here as it is a valid return if the value is found. /// The caller is responsible for checking the timeoutError flag to make sure null contacts is not /// the result of a timeout error.</returns> public (List <Contact> contacts, string val, RpcError error) FindValue(Contact sender, ID key) { ErrorResponse error; ID id = ID.RandomID; bool timeoutError; var ret = RestCall.Post <FindValueResponse, ErrorResponse>(url + ":" + port + "//FindValue", new FindValueRequest() { Protocol = sender.Protocol, ProtocolName = sender.Protocol.GetType().Name, Subnet = subnet, Sender = sender.ID.Value, Key = key.Value, RandomID = id.Value }, out error, out timeoutError); try { var contacts = ret?.Contacts?.Select(val => new Contact(Protocol.InstantiateProtocol(val.Protocol, val.ProtocolName), new ID(val.Contact))).ToList(); // Return only contacts with supported protocols. return(contacts?.Where(c => c.Protocol != null).ToList(), ret.Value, GetRpcError(id, ret, timeoutError, error)); } catch (Exception ex) { return(null, null, new RpcError() { ProtocolError = true, ProtocolErrorMessage = ex.Message }); } }
/// <summary> /// PingBack is called in response to a ping for a few reasons: /// 1. This registers the node we're pinging in the sender's list of peers /// 2. It minimally verifies that the sender is a peer. /// 3. We can't simply ping the sender of the ping we received, as this would create an infinite loop of ping - reping. /// NOTE: THIS IS NOT IN THE KADEMLIA SPEC EXCEPT FOR DISCUSSION OF "piggyback" PING RESPONSE. /// </summary> public RpcError PingBack(Contact sender) { #if DEBUG // For unit tests: if (!Responds) { return(new RpcError() { TimeoutError = !Responds }); } #endif ErrorResponse error; ID id = ID.RandomID; bool timeoutError; var ret = RestCall.Post <FindValueResponse, ErrorResponse>(url + ":" + port + "//PingBack", new PingSubnetRequest() { Protocol = sender.Protocol, ProtocolName = sender.Protocol.GetType().Name, Subnet = subnet, Sender = sender.ID.Value, RandomID = id.Value }, out error, out timeoutError); return(GetRpcError(id, ret, timeoutError, error)); }
/// <summary> /// PingBack is called in response to a ping for a few reasons: /// 1. This registers the node we're pinging in the sender's list of peers /// 2. It minimally verifies that the sender is a peer. /// 3. We can't simply ping the sender of the ping we received, as this would create an infinite loop of ping - reping. /// NOTE: THIS IS NOT IN THE KADEMLIA SPEC EXCEPT FOR DISCUSSION OF "piggyback" PING RESPONSE. public RpcError PingBack(Contact sender) { ErrorResponse error; ID id = ID.RandomID; bool timeoutError; var ret = RestCall.Post <FindValueResponse, ErrorResponse>(url + ":" + port + "//PingBack", new PingSubnetRequest() { Protocol = sender.Protocol, ProtocolName = sender.Protocol.GetType().Name, Sender = sender.ID.Value, RandomID = id.Value }, out error, out timeoutError); return(GetRpcError(id, ret, timeoutError, error)); }
public RpcError Store(Contact sender, ID key, string val, bool isCached = false, int expirationTimeSec = 0) { ErrorResponse error; ID id = ID.RandomID; bool timeoutError; var ret = RestCall.Post <FindValueResponse, ErrorResponse>(url + ":" + port + "//Store", new StoreSubnetRequest() { Protocol = sender.Protocol, ProtocolName = sender.Protocol.GetType().Name, Sender = sender.ID.Value, Key = key.Value, Value = val, IsCached = isCached, ExpirationTimeSec = expirationTimeSec, RandomID = id.Value }, out error, out timeoutError); return(GetRpcError(id, ret, timeoutError, error)); }