mirror of https://github.com/oxen-io/session-ios
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
2.7 KiB
Swift
72 lines
2.7 KiB
Swift
// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
|
|
|
|
import Foundation
|
|
import SessionUtilitiesKit
|
|
|
|
internal protocol ValidatableResponse {
|
|
associatedtype ValidationData
|
|
associatedtype ValidationResponse
|
|
|
|
/// This valid controls the number of successful responses for a response to be considered "valid", a
|
|
/// positive number indicates an exact number of responses required whereas a negative number indicates
|
|
/// a dividing factor, eg.
|
|
/// 2 = Two nodes need to have returned success responses
|
|
/// -2 = 50% of the nodes need to have returned success responses
|
|
/// -4 = 25% of the nodes need to have returned success responses
|
|
static var requiredSuccessfulResponses: Int { get }
|
|
|
|
@discardableResult static func validated(
|
|
map validResultMap: [String: ValidationResponse],
|
|
totalResponseCount: Int
|
|
) throws -> [String: ValidationResponse]
|
|
|
|
@discardableResult func validResultMap(
|
|
swarmPublicKey: String,
|
|
validationData: ValidationData,
|
|
using dependencies: Dependencies
|
|
) throws -> [String: ValidationResponse]
|
|
}
|
|
|
|
// MARK: - Convenience
|
|
|
|
internal extension ValidatableResponse {
|
|
@discardableResult static func validated(
|
|
map validResultMap: [String: ValidationResponse],
|
|
totalResponseCount: Int
|
|
) throws -> [String: ValidationResponse] {
|
|
let numSuccessResponses: Int = validResultMap.count
|
|
let successPercentage: CGFloat = (CGFloat(numSuccessResponses) / CGFloat(totalResponseCount))
|
|
|
|
guard
|
|
( // Positive value is an exact number comparison
|
|
Self.requiredSuccessfulResponses >= 0 &&
|
|
numSuccessResponses >= Self.requiredSuccessfulResponses
|
|
) || (
|
|
// Negative value is a "divisor" for a percentage comparison
|
|
Self.requiredSuccessfulResponses < 0 &&
|
|
successPercentage >= abs(1 / CGFloat(Self.requiredSuccessfulResponses))
|
|
)
|
|
else { throw SnodeAPIError.responseFailedValidation }
|
|
|
|
return validResultMap
|
|
}
|
|
}
|
|
|
|
internal extension ValidatableResponse where ValidationData == Void {
|
|
@discardableResult func validResultMap(
|
|
swarmPublicKey: String,
|
|
using dependencies: Dependencies
|
|
) throws -> [String: ValidationResponse] {
|
|
return try validResultMap(swarmPublicKey: swarmPublicKey, validationData: (), using: dependencies)
|
|
}
|
|
}
|
|
|
|
internal extension ValidatableResponse where ValidationResponse == Bool {
|
|
@discardableResult static func validated(map validResultMap: [String: Bool]) throws -> [String: Bool] {
|
|
return try validated(
|
|
map: validResultMap.filter { $0.value },
|
|
totalResponseCount: validResultMap.count
|
|
)
|
|
}
|
|
}
|