seekia/internal/network/sendRequests/sendRequests.go

1677 lines
58 KiB
Go

// sendRequests provides functions for making requests to Seekia hosts
// Each function provides a way to send a server request to a host through an active connection
// This package is imported by queryHosts.
// queryHosts is a higher level package which provides functions to split requests up, to save retrieved data, and more
package sendRequests
//TODO: Add if request successful, remove host from unreachable list
//TODO: Verify that input does not exceed maximum size for request of that type
//TODO: Add ability to handle busy responses
// If host is busy, we will keep track of that in a new package and not try to recontact them for a while
import "seekia/internal/byteRange"
import "seekia/internal/encoding"
import "seekia/internal/helpers"
import "seekia/internal/identity"
import "seekia/internal/messaging/readMessages"
import "seekia/internal/moderation/readReports"
import "seekia/internal/moderation/readReviews"
import "seekia/internal/network/maliciousHosts"
import "seekia/internal/network/mateCriteria"
import "seekia/internal/network/peerClient"
import "seekia/internal/network/serverRequest"
import "seekia/internal/network/serverResponse"
import "seekia/internal/parameters/readParameters"
import "seekia/internal/profiles/readProfiles"
import "seekia/internal/readContent"
import "bytes"
import "errors"
import "slices"
//Outputs:
// -bool: Download successsful
// -map[string]int64: Map of ParametersType -> Parameters broadcast time
// -error
func GetParametersInfoFromHost(connectionIdentifier [21]byte, hostIdentityHash [16]byte, networkType byte)(bool, map[string]int64, error){
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
if (err != nil) { return false, nil, err }
if (connectionExists == false){
return false, nil, nil
}
if (connectionHostIdentityHash != hostIdentityHash){
return false, nil, errors.New("GetParametersInfoFromHost called with hostIdentityHash which does not match connection metadata.")
}
if (connectionNetworkType != networkType){
return false, nil, errors.New("GetParametersInfoFromHost called with networkType which does not match connection metadata.")
}
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetParametersInfo(hostIdentityHash, connectionKey, networkType)
if (err != nil) { return false, nil, err }
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
if (err != nil) { return false, nil, err }
if (requestSuccessful == false){
return false, nil, nil
}
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, parametersInfoMap, err := serverResponse.ReadServerResponse_GetParametersInfo(responseData, connectionKey)
if (err != nil) { return false, nil, err }
if (ableToRead == false){
// Host sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil){ return false, nil, err }
return false, nil, nil
}
// Now we check to make sure response is valid
checkIfResponseIsValid := func()(bool, error){
if (requestIdentifier != requestIdentifier_Received){
// Host sent invalid response, must be malicious
return false, nil
}
if (hostIdentityHash != hostIdentityHash_Received){
// Host sent invalid response, must be malicious
return false, nil
}
return true, nil
}
responseIsValid, err := checkIfResponseIsValid()
if (err != nil) { return false, nil, err }
if (responseIsValid == false){
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil){ return false, nil, err }
return false, nil, nil
}
return true, parametersInfoMap, nil
}
//Outputs:
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
// -[][]byte: List of parameters
// -error
func GetParametersFromHost(
connectionIdentifier [21]byte,
hostIdentityHash [16]byte,
networkType byte,
parametersTypesToRetrieveList []string)(bool, [][]byte, error){
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
if (err != nil) { return false, nil, err }
if (connectionExists == false){
return false, nil, nil
}
if (connectionHostIdentityHash != hostIdentityHash){
return false, nil, errors.New("GetParametersFromHost called with hostIdentityHash which does not match connection metadata.")
}
if (connectionNetworkType != networkType){
return false, nil, errors.New("GetParametersFromHost called with networkType which does not match connection metadata.")
}
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetParameters(hostIdentityHash, connectionKey, networkType, parametersTypesToRetrieveList)
if (err != nil) { return false, nil, err }
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
if (err != nil) { return false, nil, err }
if (requestSuccessful == false){
return false, nil, nil
}
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, parametersList, err := serverResponse.ReadServerResponse_GetParameters(responseData, connectionKey)
if (err != nil) { return false, nil, err }
if (ableToRead == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil) { return false, nil, err }
return false, nil, nil
}
// Now we check to make sure response is valid based on input request information
checkIfResponseIsValid := func()(bool, error){
if (requestIdentifier != requestIdentifier_Received){
// Host sent invalid response, must be malicious
return false, nil
}
if (hostIdentityHash != hostIdentityHash_Received){
return false, nil
}
for _, parametersBytes := range parametersList{
ableToRead, _, parametersNetworkType, _, parametersType, _, _, err := readParameters.ReadParameters(false, parametersBytes)
if (err != nil) { return false, err }
if (ableToRead == false){
return false, errors.New("ReadServerResponse_GetParameters not verifying network parameters")
}
if (parametersNetworkType != networkType){
// We did not request parameters for this networkType.
return false, nil
}
isExpected := slices.Contains(parametersTypesToRetrieveList, parametersType)
if (isExpected == false){
// We did not request this parameters type. Response is malformed.
return false, nil
}
}
return true, nil
}
responseIsValid, err := checkIfResponseIsValid()
if (err != nil) { return false, nil, err }
if (responseIsValid == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil) { return false, nil, err }
return false, nil, nil
}
return true, parametersList, nil
}
//Outputs:
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
// -[]serverResponse.ProfileInfoStruct: Profiles info map list
// -error
func GetProfilesInfoFromHost(
connectionIdentifier [21]byte,
hostIdentityHash [16]byte,
networkType byte,
profileTypeToRetrieve string,
rangeStart [16]byte,
rangeEnd [16]byte,
identityHashesList [][16]byte,
criteria []byte,
getNewestProfilesOnly bool,
getViewableProfilesOnly bool)(bool, []serverResponse.ProfileInfoStruct, error){
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
if (err != nil) { return false, nil, err }
if (connectionExists == false){
return false, nil, nil
}
if (connectionHostIdentityHash != hostIdentityHash){
return false, nil, errors.New("GetProfilesInfoFromHost called with hostIdentityHash which does not match connection metadata.")
}
if (connectionNetworkType != networkType){
return false, nil, errors.New("GetProfilesInfoFromHost called with networkType which does not match connection metadata.")
}
acceptableProfileVersionsList := []int{1}
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetProfilesInfo(hostIdentityHash, connectionKey, networkType, acceptableProfileVersionsList, profileTypeToRetrieve, rangeStart, rangeEnd, identityHashesList, criteria, getNewestProfilesOnly, getViewableProfilesOnly)
if (err != nil) { return false, nil, err }
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
if (err != nil) { return false, nil, err }
if (requestSuccessful == false){
return false, nil, nil
}
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, profileInfoObjectsList, err := serverResponse.ReadServerResponse_GetProfilesInfo(responseData, connectionKey)
if (err != nil) { return false, nil, err }
if (ableToRead == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil){ return false, nil, err }
return false, nil, nil
}
// Now we check to make sure response is valid based on input request information
checkIfResponseIsValid := func()(bool, error){
if (requestIdentifier != requestIdentifier_Received){
// Host sent invalid response, must be malicious
return false, nil
}
if (hostIdentityHash != hostIdentityHash_Received){
// Peer sent invalid response, must be malicious
return false, nil
}
// Now we verify received profile identity hashes fulfill request filters
// We use map to make sure that only 1 profile hash per identity is returned (if getNewestProfilesOnly == true)
// Map structure: Identity Hash -> Nothing
identitiesMap := make(map[[16]byte]struct{})
for _, profileInfoObject := range profileInfoObjectsList{
receivedProfileAuthor := profileInfoObject.ProfileAuthor
identityType, err := identity.GetIdentityTypeFromIdentityHash(receivedProfileAuthor)
if (err != nil){
receivedProfileAuthorHex := encoding.EncodeBytesToHexString(receivedProfileAuthor[:])
return false, errors.New("ReadServerResponse_GetProfilesInfo not verifying profileInfoObject receivedProfileAuthor: " + receivedProfileAuthorHex)
}
if (identityType != profileTypeToRetrieve){
return false, nil
}
if (len(identityHashesList) != 0){
identityIsInRequestedList := slices.Contains(identityHashesList, receivedProfileAuthor)
if (identityIsInRequestedList == false){
return false, nil
}
}
isWithinRange, err := byteRange.CheckIfIdentityHashIsWithinRange(rangeStart, rangeEnd, receivedProfileAuthor)
if (err != nil) { return false, err }
if (isWithinRange == false){
return false, nil
}
if (getNewestProfilesOnly == true){
_, exists := identitiesMap[receivedProfileAuthor]
if (exists == true){
// We received two profiles with the same author in a getNewestProfilesOnly response.
return false, nil
}
identitiesMap[receivedProfileAuthor] = struct{}{}
}
}
return true, nil
}
responseIsValid, err := checkIfResponseIsValid()
if (err != nil) { return false, nil, err }
if (responseIsValid == false){
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil){ return false, nil, err }
return false, nil, nil
}
return true, profileInfoObjectsList, nil
}
//Outputs:
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
// -[][]byte: List of profiles
// -error
func GetProfilesFromHost(
connectionIdentifier [21]byte,
hostIdentityHash [16]byte,
networkType byte,
profileTypeToRetrieve string,
profileHashesList [][28]byte,
expectedProfileIdentityHashesMap map[[28]byte][16]byte, // Profile Hash -> Profile Identity hash
expectedProfileBroadcastTimesMap map[[28]byte]int64, // Profile Hash -> Profile Broadcast Time
expectedCriteria []byte)(bool, [][]byte, error){
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
if (err != nil) { return false, nil, err }
if (connectionExists == false){
return false, nil, nil
}
if (connectionHostIdentityHash != hostIdentityHash){
return false, nil, errors.New("GetProfilesFromHost called with hostIdentityHash which does not match connection metadata.")
}
if (connectionNetworkType != networkType){
return false, nil, errors.New("GetProfilesFromHost called with networkType which does not match connection metadata.")
}
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetProfiles(hostIdentityHash, connectionKey, networkType, profileTypeToRetrieve, profileHashesList)
if (err != nil) { return false, nil, err }
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
if (err != nil) { return false, nil, err }
if (requestSuccessful == false){
return false, nil, nil
}
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, profilesList, err := serverResponse.ReadServerResponse_GetProfiles(responseData, connectionKey)
if (err != nil) { return false, nil, err }
if (ableToRead == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil) { return false, nil, err }
return false, nil, nil
}
// Now we check to make sure response is valid based on input request information
checkIfResponseIsValid := func()(bool, error){
if (requestIdentifier != requestIdentifier_Received){
// Host sent invalid response, must be malicious
return false, nil
}
if (hostIdentityHash != hostIdentityHash_Received){
return false, nil
}
if (len(profilesList) > len(profileHashesList)){
return false, nil
}
for _, profileBytes := range profilesList{
ableToRead, profileHash, profileVersion, profileNetworkType, profileIdentityHash, profileBroadcastTime, _, rawProfileMap, err := readProfiles.ReadProfileAndHash(false, profileBytes)
if (err != nil) { return false, err }
if (ableToRead == false){
return false, errors.New("ReadServerResponse_GetProfiles not verifying received profile is valid.")
}
profileHashIsExpected := slices.Contains(profileHashesList, profileHash)
if (profileHashIsExpected == false){
return false, nil
}
if (profileNetworkType != networkType){
// The host must have sent us a different networkType profile when we requested profilesInfo
return false, nil
}
expectedProfileIdentityHash, profileExists := expectedProfileIdentityHashesMap[profileHash]
if (profileExists == false){
return false, errors.New("ExpectedProfileIdentityHashesMap missing entry for profile contained in ProfileHashesList")
}
if (profileIdentityHash != expectedProfileIdentityHash){
return false, nil
}
expectedProfileBroadcastTime, exists := expectedProfileBroadcastTimesMap[profileHash]
if (exists == false){
return false, errors.New("expectedProfileBroadcastTimesMap missing entry for profile contained in ProfileHashesList")
}
if (profileBroadcastTime != expectedProfileBroadcastTime){
// Profile is does not fulfill the expected BroadcastTime
return false, nil
}
if (expectedCriteria != nil){
criteriaIsValid, fulfillsCriteria, err := mateCriteria.CheckIfMateProfileFulfillsCriteria(false, profileVersion, rawProfileMap, expectedCriteria)
if (err != nil) { return false, err }
if (criteriaIsValid == false){
return false, errors.New("GetProfilesFromHost called with invalid expectedCriteria")
}
if (fulfillsCriteria == false){
return false, nil
}
}
}
return true, nil
}
responseIsValid, err := checkIfResponseIsValid()
if (err != nil) { return false, nil, err }
if (responseIsValid == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil) { return false, nil, err }
return false, nil, nil
}
return true, profilesList, nil
}
//Outputs:
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
// -[][26]byte: Received message hashes list
// -error
func GetMessageHashesListFromHost(
connectionIdentifier [21]byte,
hostIdentityHash [16]byte,
networkType byte,
rangeStart [10]byte,
rangeEnd [10]byte,
inboxesToRetrieveList [][10]byte,
getViewableMessagesOnly bool,
getDecryptableMessagesOnly bool)(bool, [][26]byte, error){
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
if (err != nil) { return false, nil, err }
if (connectionExists == false){
return false, nil, nil
}
if (connectionHostIdentityHash != hostIdentityHash){
return false, nil, errors.New("GetMessageHashesListFromHost called with hostIdentityHash which does not match connection metadata.")
}
if (connectionNetworkType != networkType){
return false, nil, errors.New("GetMessageHashesListFromHost called with networkType which does not match connection metadata.")
}
acceptableMessageVersionsList := []int{1}
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetMessageHashesList(hostIdentityHash, connectionKey, networkType, acceptableMessageVersionsList, rangeStart, rangeEnd, inboxesToRetrieveList, getViewableMessagesOnly, getDecryptableMessagesOnly)
if (err != nil) { return false, nil, err }
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
if (err != nil) { return false, nil, err }
if (requestSuccessful == false){
return false, nil, nil
}
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, messageHashesList_Received, err := serverResponse.ReadServerResponse_GetMessageHashesList(responseData, connectionKey)
if (err != nil) { return false, nil, err }
if (ableToRead == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil){ return false, nil, err }
return false, nil, nil
}
// Now we check to make sure response is valid based on input request information
checkIfResponseIsValid := func()(bool, error){
if (requestIdentifier != requestIdentifier_Received){
// Host sent invalid response, must be malicious
return false, nil
}
if (hostIdentityHash != hostIdentityHash_Received){
// Peer sent invalid response, must be malicious
return false, nil
}
return true, nil
}
responseIsValid, err := checkIfResponseIsValid()
if (err != nil) { return false, nil, err }
if (responseIsValid == false){
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil){ return false, nil, err }
return false, nil, nil
}
return true, messageHashesList_Received, nil
}
//Outputs:
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
// -[][]byte: List of messages
// -error
func GetMessagesFromHost(
connectionIdentifier [21]byte,
hostIdentityHash [16]byte,
networkType byte,
messageHashesList [][26]byte,
expectedInboxRangeStart [10]byte,
expectedInboxRangeEnd [10]byte,
expectedInboxesList [][10]byte)(bool, [][]byte, error){
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
if (err != nil) { return false, nil, err }
if (connectionExists == false){
return false, nil, nil
}
if (connectionHostIdentityHash != hostIdentityHash){
return false, nil, errors.New("GetMessagesFromHost called with hostIdentityHash which does not match connection metadata.")
}
if (connectionNetworkType != networkType){
return false, nil, errors.New("GetMessagesFromHost called with networkType which does not match connection metadata.")
}
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetMessages(hostIdentityHash, connectionKey, networkType, messageHashesList)
if (err != nil) { return false, nil, err }
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
if (err != nil) { return false, nil, err }
if (requestSuccessful == false){
return false, nil, nil
}
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, messagesList, err := serverResponse.ReadServerResponse_GetMessages(responseData, connectionKey)
if (err != nil) { return false, nil, err }
if (ableToRead == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil) { return false, nil, err }
return false, nil, nil
}
// Now we check to make sure response is valid based on input request information
checkIfResponseIsValid := func()(bool, error){
if (requestIdentifier != requestIdentifier_Received){
// Host sent invalid response, must be malicious
return false, nil
}
if (hostIdentityHash != hostIdentityHash_Received){
return false, nil
}
for _, messageBytes := range messagesList{
ableToRead, messageHash, _, messageNetworkType, messageInbox, _, _, _, _, _, _, err := readMessages.ReadChatMessagePublicDataAndHash(false, messageBytes)
if (err != nil) { return false, err }
if (ableToRead == false){
return false, errors.New("ReadServerResponse_GetMessages not verifying each message.")
}
isExpected := slices.Contains(messageHashesList, messageHash)
if (isExpected == false){
return false, nil
}
if (messageNetworkType != networkType){
// Host must have sent us a different networkType messageHash when we got messageHashesList response
return false, nil
}
if (len(expectedInboxesList) != 0){
messageInboxIsExpected := slices.Contains(expectedInboxesList, messageInbox)
if (messageInboxIsExpected == false){
return false, nil
}
} else {
inboxIsWithinRange, err := byteRange.CheckIfInboxIsWithinRange(expectedInboxRangeStart, expectedInboxRangeEnd, messageInbox)
if (err != nil) { return false, err }
if (inboxIsWithinRange == false){
return false, nil
}
}
}
return true, nil
}
responseIsValid, err := checkIfResponseIsValid()
if (err != nil) { return false, nil, err }
if (responseIsValid == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil) { return false, nil, err }
return false, nil, nil
}
return true, messagesList, nil
}
//Outputs:
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
// -map[[29]byte][]byte: Received reviews info map (Review Hash -> Reviewed Hash)
// -error
func GetIdentityReviewsInfoFromHost(
connectionIdentifier [21]byte,
hostIdentityHash [16]byte,
networkType byte,
identityTypeToRetrieve string,
rangeStart [16]byte,
rangeEnd [16]byte,
reviewedIdentityHashesList [][16]byte,
reviewersList [][16]byte)(bool, map[[29]byte][]byte, error){
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
if (err != nil) { return false, nil, err }
if (connectionExists == false){
return false, nil, nil
}
if (connectionHostIdentityHash != hostIdentityHash){
return false, nil, errors.New("GetIdentityReviewsInfoFromHost called with hostIdentityHash which does not match connection metadata.")
}
if (connectionNetworkType != networkType){
return false, nil, errors.New("GetIdentityReviewsInfoFromHost called with networkType which does not match connection metadata.")
}
acceptableReviewVersionList := []int{1}
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetIdentityReviewsInfo(hostIdentityHash, connectionKey, networkType, acceptableReviewVersionList, identityTypeToRetrieve, rangeStart, rangeEnd, reviewedIdentityHashesList, reviewersList)
if (err != nil) { return false, nil, err }
requestSuccessful, responseBytes, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
if (err != nil) { return false, nil, err }
if (requestSuccessful == false){
return false, nil, nil
}
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, reviewsInfoMap, err := serverResponse.ReadServerResponse_GetIdentityReviewsInfo(responseBytes, connectionKey)
if (err != nil) { return false, nil, err }
if (ableToRead == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil){ return false, nil, err }
return false, nil, nil
}
// Now we check to make sure response is valid based on input request information
checkIfResponseIsValid := func()(bool, error){
if (requestIdentifier != requestIdentifier_Received){
// Host sent invalid response, must be malicious
return false, nil
}
if (hostIdentityHash != hostIdentityHash_Received){
// Peer sent invalid response, must be malicious
return false, nil
}
// Now we verify received reviews info map fulfills request filters
for _, reviewedHash := range reviewsInfoMap{
// reviewedHash is either Profile hash or identity hash or attribute hash
reviewedHashType, err := helpers.GetReviewedTypeFromReviewedHash(reviewedHash)
if (err != nil) {
reviewedHashHex := encoding.EncodeBytesToHexString(reviewedHash)
return false, errors.New("ReadServerResponse_GetReviewsInfo not verifying reviewsInfoMap reviewedHash: " + reviewedHashHex)
}
if (reviewedHashType != "Identity" && reviewedHashType != "Profile" && reviewedHashType != "Attribute"){
// Must be a message hash. Host is malicious.
reviewedHashHex := encoding.EncodeBytesToHexString(reviewedHash)
return false, errors.New("ReadServerResponse_GetReviewsInfo not verifying reviewsInfoMap reviewedHash: " + reviewedHashHex)
}
if (reviewedHashType == "Identity"){
if (len(reviewedHash) != 16){
reviewedHashHex := encoding.EncodeBytesToHexString(reviewedHash)
return false, errors.New("GetReviewedTypeFromReviewedHash returning Identity for different length reviewedHash: " + reviewedHashHex)
}
reviewedIdentityHash := [16]byte(reviewedHash)
if (len(reviewedIdentityHashesList) == 0){
// We only need to verify identityType if a reviewedHashesList was not requested
identityType, err := identity.GetIdentityTypeFromIdentityHash(reviewedIdentityHash)
if (err != nil){
reviewedIdentityHashHex := encoding.EncodeBytesToHexString(reviewedIdentityHash[:])
return false, errors.New("GetReviewedTypeFromReviewedHash fails to verify identity hash: " + reviewedIdentityHashHex)
}
if (identityType != identityTypeToRetrieve){
return false, nil
}
}
isWithinRange, err := byteRange.CheckIfIdentityHashIsWithinRange(rangeStart, rangeEnd, reviewedIdentityHash)
if (err != nil) { return false, err }
if (isWithinRange == false){
return false, nil
}
if (len(reviewedIdentityHashesList) != 0){
identityHashIsInRequestedList := slices.Contains(reviewedIdentityHashesList, reviewedIdentityHash)
if (identityHashIsInRequestedList == false){
return false, nil
}
}
continue
} else if (reviewedHashType == "Profile"){
if (len(reviewedHash) != 28){
reviewedHashHex := encoding.EncodeBytesToHexString(reviewedHash)
return false, errors.New("GetReviewedTypeFromReviewedHash returning Profile for different length reviewedHash: " + reviewedHashHex)
}
reviewedProfileHash := [28]byte(reviewedHash)
if (len(reviewedIdentityHashesList) == 0){
// We only need to verify profileType if a reviewedIdentityHashesList was not requested
profileType, isDisabled, err := readProfiles.ReadProfileHashMetadata(reviewedProfileHash)
if (err != nil) {
reviewedProfileHashHex := encoding.EncodeBytesToHexString(reviewedProfileHash[:])
return false, errors.New("ReadServerResponse_GetReviewsInfo not verifying reviewsInfoMap reviewedHash: " + reviewedProfileHashHex)
}
if (isDisabled == true){
return false, errors.New("ReadServerResponse_GetReviewsInfo not verifying reviewsInfoMap reviewedHash: Profile hash is disabled.")
}
if (profileType != identityTypeToRetrieve){
return false, nil
}
}
}
}
return true, nil
}
responseIsValid, err := checkIfResponseIsValid()
if (err != nil) { return false, nil, err }
if (responseIsValid == false){
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil){ return false, nil, err }
return false, nil, nil
}
return true, reviewsInfoMap, nil
}
//Outputs:
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
// -map[[29]byte][26]byte: Received reviews info map (Review Hash -> Reviewed Message Hash)
// -error
func GetMessageReviewsInfoFromHost(
connectionIdentifier [21]byte,
hostIdentityHash [16]byte,
networkType byte,
rangeStart [10]byte,
rangeEnd [10]byte,
reviewedMessageHashesList [][26]byte,
reviewersList [][16]byte)(bool, map[[29]byte][26]byte, error){
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
if (err != nil) { return false, nil, err }
if (connectionExists == false){
return false, nil, nil
}
if (connectionHostIdentityHash != hostIdentityHash){
return false, nil, errors.New("GetMessageReviewsInfoFromHost called with hostIdentityHash which does not match connection metadata.")
}
if (connectionNetworkType != networkType){
return false, nil, errors.New("GetMessageReviewsInfoFromHost called with networkType which does not match connection metadata.")
}
acceptableReviewVersionList := []int{1}
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetMessageReviewsInfo(hostIdentityHash, connectionKey, networkType, acceptableReviewVersionList, rangeStart, rangeEnd, reviewedMessageHashesList, reviewersList)
if (err != nil) { return false, nil, err }
requestSuccessful, responseBytes, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
if (err != nil) { return false, nil, err }
if (requestSuccessful == false){
return false, nil, nil
}
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, reviewsInfoMap, err := serverResponse.ReadServerResponse_GetMessageReviewsInfo(responseBytes, connectionKey)
if (err != nil) { return false, nil, err }
if (ableToRead == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil){ return false, nil, err }
return false, nil, nil
}
// Now we check to make sure response is valid based on input request information
checkIfResponseIsValid := func()(bool, error){
if (requestIdentifier != requestIdentifier_Received){
// Host sent invalid response, must be malicious
return false, nil
}
if (hostIdentityHash != hostIdentityHash_Received){
// Peer sent invalid response, must be malicious
return false, nil
}
// Now we verify received reviews info map fulfills request filters
for _, reviewedHash := range reviewsInfoMap{
// reviewedHash is a message hash
if (len(reviewedMessageHashesList) != 0){
messageHashIsInRequestedList := slices.Contains(reviewedMessageHashesList, reviewedHash)
if (messageHashIsInRequestedList == false){
return false, nil
}
}
}
return true, nil
}
responseIsValid, err := checkIfResponseIsValid()
if (err != nil) { return false, nil, err }
if (responseIsValid == false){
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil){ return false, nil, err }
return false, nil, nil
}
return true, reviewsInfoMap, nil
}
//Outputs:
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
// -[][]byte: Retrieved list of reviews
// -error
func GetReviewsFromHost(
connectionIdentifier [21]byte,
hostIdentityHash [16]byte,
networkType byte,
reviewHashesList [][29]byte,
expectedReviewsInfoMap map[[29]byte][]byte, // Review Hash -> Reviewed Hash
expectedReviewersList [][16]byte)(bool, [][]byte, error){
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
if (err != nil) { return false, nil, err }
if (connectionExists == false){
return false, nil, nil
}
if (connectionHostIdentityHash != hostIdentityHash){
return false, nil, errors.New("GetReviewsFromHost called with hostIdentityHash which does not match connection metadata.")
}
if (connectionNetworkType != networkType){
return false, nil, errors.New("GetReviewsFromHost called with networkType which does not match connection metadata.")
}
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetReviews(hostIdentityHash, connectionKey, networkType, reviewHashesList)
if (err != nil) { return false, nil, err }
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
if (err != nil) { return false, nil, err }
if (requestSuccessful == false){
return false, nil, nil
}
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, reviewsList, err := serverResponse.ReadServerResponse_GetReviews(responseData, connectionKey)
if (err != nil) { return false, nil, err }
if (ableToRead == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil) { return false, nil, err }
return false, nil, nil
}
// Now we check to make sure response is valid based on input request information
checkIfResponseIsValid := func()(bool, error){
if (requestIdentifier != requestIdentifier_Received){
// Host sent invalid response, must be malicious
return false, nil
}
if (hostIdentityHash != hostIdentityHash_Received){
return false, nil
}
for _, reviewBytes := range reviewsList{
ableToRead, reviewHash, _, reviewNetworkType, authorIdentityHash, _, _, reviewReviewedHash, _, _, err := readReviews.ReadReviewAndHash(false, reviewBytes)
if (err != nil) { return false, err }
if (ableToRead == false){
return false, errors.New("ReadServerResponse_GetReviews not verifying each review")
}
if (reviewNetworkType != networkType){
return false, nil
}
if (len(expectedReviewersList) != 0){
isExpectedReviewer := slices.Contains(expectedReviewersList, authorIdentityHash)
if (isExpectedReviewer == false){
return false, nil
}
}
expectedReviewedHash, exists := expectedReviewsInfoMap[reviewHash]
if (exists == false) {
// We received an unexpected reviewHash
return false, nil
}
areEqual := bytes.Equal(reviewReviewedHash, expectedReviewedHash)
if (areEqual == false){
// We received an unexpected reviewedHash for expected reviewHash
return false, nil
}
}
return true, nil
}
responseIsValid, err := checkIfResponseIsValid()
if (err != nil) { return false, nil, err }
if (responseIsValid == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil) { return false, nil, err }
return false, nil, nil
}
return true, reviewsList, nil
}
//Outputs:
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
// -map[[30]byte][]byte: Reports info map (Report Hash -> Reported Hash)
// -error
func GetIdentityReportsInfoFromHost(
connectionIdentifier [21]byte,
hostIdentityHash [16]byte,
networkType byte,
identityTypeToRetrieve string,
rangeStart [16]byte,
rangeEnd [16]byte,
reportedIdentityHashesList [][16]byte)(bool, map[[30]byte][]byte, error){
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
if (err != nil) { return false, nil, err }
if (connectionExists == false){
return false, nil, nil
}
if (connectionHostIdentityHash != hostIdentityHash){
return false, nil, errors.New("GetIdentityReportsInfoFromHost called with hostIdentityHash which does not match connection metadata.")
}
if (connectionNetworkType != networkType){
return false, nil, errors.New("GetIdentityReportsInfoFromHost called with networkType which does not match connection metadata.")
}
acceptableReportVersionsList := []int{1}
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetIdentityReportsInfo(hostIdentityHash, connectionKey, networkType, acceptableReportVersionsList, identityTypeToRetrieve, rangeStart, rangeEnd, reportedIdentityHashesList)
if (err != nil) { return false, nil, err }
requestSuccessful, responseBytes, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
if (err != nil) { return false, nil, err }
if (requestSuccessful == false){
return false, nil, nil
}
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, reportsInfoMap, err := serverResponse.ReadServerResponse_GetIdentityReportsInfo(responseBytes, connectionKey)
if (err != nil) { return false, nil, err }
if (ableToRead == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil){ return false, nil, err }
return false, nil, nil
}
// Now we check to make sure response is valid based on input request information
checkIfResponseIsValid := func()(bool, error){
if (requestIdentifier != requestIdentifier_Received){
// Host sent invalid response, must be malicious
return false, nil
}
if (hostIdentityHash != hostIdentityHash_Received){
// Peer sent invalid response, must be malicious
return false, nil
}
// Now we verify received reports info map fulfills request filters
for _, reportedHash := range reportsInfoMap{
// reportedHash is either Profile hash or identity hash or Attribute hash
reportedType, err := helpers.GetReportedTypeFromReportedHash(reportedHash)
if (err != nil){
reportedHashHex := encoding.EncodeBytesToHexString(reportedHash)
return false, errors.New("ReadServerResponse_GetReportsInfo not verifying reportedHash: " + reportedHashHex)
}
if (reportedType != "Identity" && reportedType != "Profile" && reportedType != "Attribute"){
reportedHashHex := encoding.EncodeBytesToHexString(reportedHash)
return false, errors.New("ReadServerResponse_GetReportsInfo not verifying reportedHash: " + reportedHashHex)
}
if (reportedType == "Identity"){
if (len(reportedHash) != 16){
reportedHashHex := encoding.EncodeBytesToHexString(reportedHash)
return false, errors.New("GetReportedTypeFromReportedHash returning Identity for different length reportedHash: " + reportedHashHex)
}
reportedIdentityHash := [16]byte(reportedHash)
if (len(reportedIdentityHashesList) == 0){
identityType, err := identity.GetIdentityTypeFromIdentityHash(reportedIdentityHash)
if (err != nil){
reportedIdentityHashHex := encoding.EncodeBytesToHexString(reportedIdentityHash[:])
return false, errors.New("GetReportedTypeFromReportedHash not verifying identityHash: " + reportedIdentityHashHex)
}
if (identityType != identityTypeToRetrieve){
// We only need to verify identityType if a reportedHashesList was not requested
return false, nil
}
}
isWithinRange, err := byteRange.CheckIfIdentityHashIsWithinRange(rangeStart, rangeEnd, reportedIdentityHash)
if (err != nil) { return false, err }
if (isWithinRange == false){
return false, nil
}
if (len(reportedIdentityHashesList) != 0){
identityHashIsInRequestedList := slices.Contains(reportedIdentityHashesList, reportedIdentityHash)
if (identityHashIsInRequestedList == false){
return false, nil
}
}
continue
}
if (reportedType == "Profile"){
if (len(reportedHash) != 28){
reportedHashHex := encoding.EncodeBytesToHexString(reportedHash)
return false, errors.New("GetReportedTypeFromReportedHash returning Profile for different length reportedHash: " + reportedHashHex)
}
reportedProfileHash := [28]byte(reportedHash)
if (len(reportedIdentityHashesList) == 0){
// We only need to verify profileType if a reportedHashesList was not requested
profileType, isDisabled, err := readProfiles.ReadProfileHashMetadata(reportedProfileHash)
if (err != nil) {
return false, errors.New("GetReportedTypeFromReportedHash not verifying profileHash")
}
if (isDisabled == true){
return false, errors.New("GetReportedTypeFromReportedHash not verifying profileHash is not disabled.")
}
if (profileType != identityTypeToRetrieve){
return false, nil
}
}
}
}
return true, nil
}
responseIsValid, err := checkIfResponseIsValid()
if (err != nil) { return false, nil, err }
if (responseIsValid == false){
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil){ return false, nil, err }
return false, nil, nil
}
return true, reportsInfoMap, nil
}
//Outputs:
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
// -map[[30]byte][26]byte: Reports info map (Report Hash -> Reported Message Hash)
// -error
func GetMessageReportsInfoFromHost(
connectionIdentifier [21]byte,
hostIdentityHash [16]byte,
networkType byte,
rangeStart [10]byte,
rangeEnd [10]byte,
reportedMessageHashesList [][26]byte)(bool, map[[30]byte][26]byte, error){
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
if (err != nil) { return false, nil, err }
if (connectionExists == false){
return false, nil, nil
}
if (connectionHostIdentityHash != hostIdentityHash){
return false, nil, errors.New("GetMessageReportsInfoFromHost called with hostIdentityHash which does not match connection metadata.")
}
if (connectionNetworkType != networkType){
return false, nil, errors.New("GetMessageReportsInfoFromHost called with networkType which does not match connection metadata.")
}
acceptableReportVersionsList := []int{1}
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetMessageReportsInfo(hostIdentityHash, connectionKey, networkType, acceptableReportVersionsList, rangeStart, rangeEnd, reportedMessageHashesList)
if (err != nil) { return false, nil, err }
requestSuccessful, responseBytes, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
if (err != nil) { return false, nil, err }
if (requestSuccessful == false){
return false, nil, nil
}
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, reportsInfoMap, err := serverResponse.ReadServerResponse_GetMessageReportsInfo(responseBytes, connectionKey)
if (err != nil) { return false, nil, err }
if (ableToRead == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil){ return false, nil, err }
return false, nil, nil
}
// Now we check to make sure response is valid based on input request information
checkIfResponseIsValid := func()(bool, error){
if (requestIdentifier != requestIdentifier_Received){
// Host sent invalid response, must be malicious
return false, nil
}
if (hostIdentityHash != hostIdentityHash_Received){
// Peer sent invalid response, must be malicious
return false, nil
}
// Now we verify received reports info map fulfills request filters
for _, reportedHash := range reportsInfoMap{
// reportedHash is a message hash
if (len(reportedMessageHashesList) != 0){
messageHashIsInRequestedList := slices.Contains(reportedMessageHashesList, reportedHash)
if (messageHashIsInRequestedList == false){
return false, nil
}
}
}
return true, nil
}
responseIsValid, err := checkIfResponseIsValid()
if (err != nil) { return false, nil, err }
if (responseIsValid == false){
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil){ return false, nil, err }
return false, nil, nil
}
return true, reportsInfoMap, nil
}
//Outputs:
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
// -[][]byte: Retrieved list of reports
// -error
func GetReportsFromHost(
connectionIdentifier [21]byte,
hostIdentityHash [16]byte,
networkType byte,
reportHashesList [][30]byte,
expectedReportsInfoMap map[[30]byte][]byte)(bool, [][]byte, error){
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
if (err != nil) { return false, nil, err }
if (connectionExists == false){
return false, nil, nil
}
if (connectionHostIdentityHash != hostIdentityHash){
return false, nil, errors.New("GetReportsFromHost called with hostIdentityHash which does not match connection metadata.")
}
if (connectionNetworkType != networkType){
return false, nil, errors.New("GetReportsFromHost called with networkType which does not match connection metadata.")
}
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetReports(hostIdentityHash, connectionKey, networkType, reportHashesList)
if (err != nil) { return false, nil, err }
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
if (err != nil) { return false, nil, err }
if (requestSuccessful == false){
return false, nil, nil
}
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, reportsList, err := serverResponse.ReadServerResponse_GetReports(responseData, connectionKey)
if (err != nil) { return false, nil, err }
if (ableToRead == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil) { return false, nil, err }
return false, nil, nil
}
// Now we check to make sure response is valid based on input request information
checkIfResponseIsValid := func()(bool, error){
if (requestIdentifier != requestIdentifier_Received){
// Host sent invalid response, must be malicious
return false, nil
}
if (hostIdentityHash != hostIdentityHash_Received){
return false, nil
}
for _, reportBytes := range reportsList{
ableToRead, reportHash, _, reportNetworkType, _, _, reportReportedHash, _, err := readReports.ReadReportAndHash(false, reportBytes)
if (err != nil) { return false, err }
if (ableToRead == false){
// Report is invalid, peer must be malicious.
return false, nil
}
if (reportNetworkType != networkType){
return false, nil
}
expectedReportedHash, exists := expectedReportsInfoMap[reportHash]
if (exists == false) {
// We received an unexpected reportHash
return false, nil
}
areEqual := bytes.Equal(reportReportedHash, expectedReportedHash)
if (areEqual == false){
// We received an unexpected reportedHash for expected reportHash
return false, nil
}
}
return true, nil
}
responseIsValid, err := checkIfResponseIsValid()
if (err != nil) { return false, nil, err }
if (responseIsValid == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil) { return false, nil, err }
return false, nil, nil
}
return true, reportsList, nil
}
//Outputs:
// -bool: Successful download
// -[]serverResponse.DepositStruct
// -[]string: List of addresses with no deposits
// -error
func GetAddressDepositsFromHost(
connectionIdentifier [21]byte,
hostIdentityHash [16]byte,
networkType byte,
cryptocurrency string,
cryptoAddressesList []string)(bool, []serverResponse.DepositStruct, []string, error){
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
if (err != nil) { return false, nil, nil, err }
if (connectionExists == false){
return false, nil, nil, nil
}
if (connectionHostIdentityHash != hostIdentityHash){
return false, nil, nil, errors.New("GetAddressDepositsFromHost called with hostIdentityHash which does not match connection metadata.")
}
if (connectionNetworkType != networkType){
return false, nil, nil, errors.New("GetAddressDepositsFromHost called with networkType which does not match connection metadata.")
}
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetAddressDeposits(hostIdentityHash, connectionKey, networkType, cryptocurrency, cryptoAddressesList)
if (err != nil) { return false, nil, nil, err }
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
if (err != nil) { return false, nil, nil, err }
if (requestSuccessful == false){
return false, nil, nil, nil
}
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, addressDepositObjectsList, err := serverResponse.ReadServerResponse_GetAddressDeposits(responseData, connectionKey)
if (err != nil) { return false, nil, nil, err }
if (ableToRead == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil) { return false, nil, nil, err }
return false, nil, nil, nil
}
// Now we check to make sure response is valid based on input request information
// This map will store all addresses which have deposits
addressesWithDepositsMap := make(map[string]struct{})
checkIfResponseIsValid := func()(bool, error){
if (requestIdentifier != requestIdentifier_Received){
// Host sent invalid response, must be malicious
return false, nil
}
if (hostIdentityHash != hostIdentityHash_Received){
return false, nil
}
for _, depositObject := range addressDepositObjectsList{
depositAddress := depositObject.Address
addressExists := slices.Contains(cryptoAddressesList, depositAddress)
if (addressExists == false){
return false, nil
}
addressesWithDepositsMap[depositAddress] = struct{}{}
}
return true, nil
}
responseIsValid, err := checkIfResponseIsValid()
if (err != nil) { return false, nil, nil, err }
if (responseIsValid == false){
// Host sent invalid response, they must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil) { return false, nil, nil, err }
return false, nil, nil, nil
}
addressesWithoutDepositsList := make([]string, 0)
for _, cryptoAddress := range cryptoAddressesList{
_, exists := addressesWithDepositsMap[cryptoAddress]
if (exists == false){
addressesWithoutDepositsList = append(addressesWithoutDepositsList, cryptoAddress)
}
}
return true, addressDepositObjectsList, addressesWithoutDepositsList, nil
}
//Inputs:
// -[21]byte: Connection Identifier
// -[16]byte: Host Identity Hash
// -byte: Network Type
// -[][16]byte: Identity hashes to retrieve viewable statuses for
// -[][28]byte: Profiles hashes to retrieve viewable statuses for
//Outputs:
// -bool: Successful download
// -map[[16]byte]bool: Identity Hash Statuses Map (Identity Hash -> true/false) (true = viewable, false = unviewable)
// -map[[28]byte]bool: Profile Hash Statuses Map (Profile Hash -> true/false) (true = viewable, false = unviewable)
// -error
func GetViewableStatusesFromHost(
connectionIdentifier [21]byte,
hostIdentityHash [16]byte,
networkType byte,
identityHashesList [][16]byte,
profileHashesList [][28]byte)(bool, map[[16]byte]bool, map[[28]byte]bool, error){
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
if (err != nil) { return false, nil, nil, err }
if (connectionExists == false){
return false, nil, nil, nil
}
if (connectionHostIdentityHash != hostIdentityHash){
return false, nil, nil, errors.New("GetViewableStatusesFromHost called with hostIdentityHash which does not match connection metadata.")
}
if (connectionNetworkType != networkType){
return false, nil, nil, errors.New("GetViewableStatusesFromHost called with networkType which does not match connection metadata.")
}
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetViewableStatuses(hostIdentityHash, connectionKey, networkType, identityHashesList, profileHashesList)
if (err != nil) { return false, nil, nil, err }
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
if (err != nil) { return false, nil, nil, err }
if (requestSuccessful == false){
return false, nil, nil, nil
}
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, identityHashStatusesMap, profileHashStatusesMap, err := serverResponse.ReadServerResponse_GetViewableStatuses(responseData, connectionKey)
if (err != nil) { return false, nil, nil, err }
if (ableToRead == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil) { return false, nil, nil, err }
return false, nil, nil, nil
}
// Now we check to make sure response is valid based on input request information
checkIfResponseIsValid := func()(bool, error){
if (requestIdentifier != requestIdentifier_Received){
// Host sent invalid response, must be malicious
return false, nil
}
if (hostIdentityHash != hostIdentityHash_Received){
return false, nil
}
for identityHash, _ := range identityHashStatusesMap{
isRequestedIdentityHash := slices.Contains(identityHashesList, identityHash)
if (isRequestedIdentityHash == false){
return false, nil
}
}
for profileHash, _ := range profileHashStatusesMap{
isRequestedProfileHash := slices.Contains(profileHashesList, profileHash)
if (isRequestedProfileHash == false){
return false, nil
}
}
return true, nil
}
responseIsValid, err := checkIfResponseIsValid()
if (err != nil) { return false, nil, nil, err }
if (responseIsValid == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil) { return false, nil, nil, err }
return false, nil, nil, nil
}
return true, identityHashStatusesMap, profileHashStatusesMap, nil
}
//Inputs:
// -[21]byte: Connection Identifier
// -[16]byte: Host Identity Hash
// -byte: Network Type
// -string: Content Type ("Profile"/"Message"/"Review"/"Report"/"Parameters")
// -[][]byte: Contents list
//Outputs:
// -bool: Successful download
// -map[string]bool: Received Content Accepted Info Map (Content Hash -> true/false)
// -error
func BroadcastContentToHost(
connectionIdentifier [21]byte,
hostIdentityHash [16]byte,
networkType byte,
contentType string,
contentList [][]byte)(bool, map[string]bool, error){
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
if (err != nil) { return false, nil, err }
if (connectionExists == false){
return false, nil, nil
}
if (connectionHostIdentityHash != hostIdentityHash){
return false, nil, errors.New("BroadcastContentToHost called with hostIdentityHash which does not match connection metadata.")
}
if (connectionNetworkType != networkType){
return false, nil, errors.New("BroadcastContentToHost called with networkType which does not match connection metadata.")
}
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_BroadcastContent(hostIdentityHash, connectionKey, networkType, contentType, contentList)
if (err != nil) { return false, nil, err }
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
if (err != nil) { return false, nil, err }
if (requestSuccessful == false){
return false, nil, nil
}
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, contentAcceptedInfoMap, err := serverResponse.ReadServerResponse_BroadcastContent(responseData, connectionKey)
if (err != nil) { return false, nil, err }
if (ableToRead == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil) { return false, nil, err }
return false, nil, nil
}
// Now we check to make sure response is valid based on input request information
checkIfResponseIsValid := func()(bool, error){
if (requestIdentifier != requestIdentifier_Received){
// Host sent invalid response, must be malicious
return false, nil
}
if (hostIdentityHash != hostIdentityHash_Received){
return false, nil
}
for _, contentBytes := range contentList{
ableToRead, contentHash, err := readContent.GetContentHashFromContentBytes(false, contentType, contentBytes)
if (err != nil) { return false, err }
if (ableToRead == false){
return false, errors.New("CreateServerRequest_BroadcastContent not verifying content is valid.")
}
_, exists := contentAcceptedInfoMap[string(contentHash)]
if (exists == false){
// Host did not tell us if they accepted the content
// Host is malicious
return false, nil
}
}
return true, nil
}
responseIsValid, err := checkIfResponseIsValid()
if (err != nil) { return false, nil, err }
if (responseIsValid == false){
// Peer sent invalid response, must be malicious
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
if (err != nil) { return false, nil, err }
return false, nil, nil
}
return true, contentAcceptedInfoMap, nil
}