Clean up logging and redact LibMobileCoin and Protobuf errors (#12)
This commit is contained in:
parent
b690db1326
commit
dde923cb6e
@ -43,8 +43,8 @@ extension Account {
|
||||
Result<(transaction: Transaction, receipt: Receipt), TransactionPreparationError>
|
||||
) -> Void
|
||||
) {
|
||||
logger.info("recipient: \(recipient.debugDescription), " +
|
||||
"amount: \(redacting: amount), fee: \(fee)")
|
||||
logger.info(
|
||||
"recipient: \(redacting: recipient), amount: \(redacting: amount), fee: \(fee)")
|
||||
guard amount > 0 else {
|
||||
logger.info("failure - Cannot spend 0 MOB")
|
||||
serialQueue.async {
|
||||
@ -69,8 +69,8 @@ extension Account {
|
||||
})
|
||||
{
|
||||
case .success(let txOutsToSpend):
|
||||
logger.info("success - txOutsToSpend: " +
|
||||
"\(redacting: txOutsToSpend.map { $0.publicKey })")
|
||||
logger.info(
|
||||
"success - txOutsToSpend: \(redacting: txOutsToSpend.map { $0.publicKey })")
|
||||
transactionPreparer.prepareTransaction(
|
||||
inputs: txOutsToSpend,
|
||||
recipient: recipient,
|
||||
@ -79,7 +79,7 @@ extension Account {
|
||||
tombstoneBlockIndex: tombstoneBlockIndex,
|
||||
completion: completion)
|
||||
case .failure(let error):
|
||||
logger.info("failure - error: \(error.localizedDescription)")
|
||||
logger.info("failure - error: \(error)")
|
||||
serialQueue.async {
|
||||
completion(.failure(error))
|
||||
}
|
||||
@ -94,8 +94,8 @@ extension Account {
|
||||
Result<(transaction: Transaction, receipt: Receipt), TransactionPreparationError>
|
||||
) -> Void
|
||||
) {
|
||||
logger.info("recipient: \(recipient.debugDescription), " +
|
||||
"amount: \(redacting: amount), feeLevel: \(feeLevel)")
|
||||
logger.info("recipient: \(redacting: recipient), amount: \(redacting: amount), " +
|
||||
"feeLevel: \(feeLevel)")
|
||||
guard amount > 0 else {
|
||||
logger.info("failure - Cannot spend 0 MOB")
|
||||
serialQueue.async {
|
||||
@ -132,7 +132,7 @@ extension Account {
|
||||
tombstoneBlockIndex: tombstoneBlockIndex,
|
||||
completion: completion)
|
||||
case .failure(let error):
|
||||
logger.info("failure - error: \(error.localizedDescription)")
|
||||
logger.info("failure - error: \(error)")
|
||||
serialQueue.async {
|
||||
completion(.failure(error))
|
||||
}
|
||||
|
||||
@ -16,8 +16,6 @@ final class Account {
|
||||
self.accountKey = accountKey.accountKey
|
||||
}
|
||||
|
||||
var debugDescription: String { publicAddress.debugDescription }
|
||||
|
||||
var publicAddress: PublicAddress {
|
||||
accountKey.publicAddress
|
||||
}
|
||||
@ -166,7 +164,7 @@ final class Account {
|
||||
private func ownedTxOut(for receipt: Receipt) -> Result<KnownTxOut?, InvalidInputError> {
|
||||
logger.info("""
|
||||
receipt.txOutPublicKey: \(redacting: receipt.txOutPublicKey), \
|
||||
account: \(accountKey.publicAddress.debugDescription)
|
||||
account: \(redacting: accountKey.publicAddress)
|
||||
""")
|
||||
if let lastTxOut = ownedTxOuts.last {
|
||||
logger.info("Last received TxOut: Tx pubkey: \(redacting: lastTxOut.publicKey)")
|
||||
@ -226,6 +224,12 @@ extension Account {
|
||||
}
|
||||
}
|
||||
|
||||
extension Account: CustomRedactingStringConvertible {
|
||||
var redactingDescription: String {
|
||||
publicAddress.redactingDescription
|
||||
}
|
||||
}
|
||||
|
||||
final class TxOutTracker {
|
||||
let knownTxOut: KnownTxOut
|
||||
|
||||
|
||||
@ -104,8 +104,7 @@ public struct AccountKey {
|
||||
return try proto.serializedData()
|
||||
} catch {
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`.
|
||||
logger.fatalError(
|
||||
"Error: Protobuf serialization failed: \(redacting: error.localizedDescription)")
|
||||
logger.fatalError("Protobuf serialization failed: \(redacting: error)")
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,20 +222,19 @@ struct AccountKeyWithFog {
|
||||
let accountKey: AccountKey
|
||||
|
||||
init?(accountKey: AccountKey) {
|
||||
logger.info(accountKey.publicAddress.debugDescription)
|
||||
logger.info("\(redacting: accountKey.publicAddress)")
|
||||
|
||||
guard accountKey.fogInfo != nil else {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.accountKey = accountKey
|
||||
}
|
||||
|
||||
var fogInfo: AccountKey.FogInfo {
|
||||
guard let fogInfo = accountKey.fogInfo else {
|
||||
// Safety: accountKey is guaranteed to have fogInfo.
|
||||
logger.fatalError("accountKey doesn't have fogInfo.")
|
||||
logger.fatalError("accountKey doesn't have fogInfo")
|
||||
}
|
||||
|
||||
return fogInfo
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,8 +52,7 @@ public struct PublicAddress {
|
||||
return try proto.serializedData()
|
||||
} catch {
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`.
|
||||
logger.fatalError(
|
||||
"Error: Protobuf serialization failed: \(error)")
|
||||
logger.fatalError("Protobuf serialization failed: \(redacting: error)")
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,19 +67,28 @@ public struct PublicAddress {
|
||||
var fogReportUrl: FogUrl? { fogInfo?.reportUrl }
|
||||
var fogReportId: String? { fogInfo?.reportId }
|
||||
var fogAuthoritySig: Data? { fogInfo?.authoritySig }
|
||||
|
||||
var debugDescription: String {
|
||||
"(viewPublicKey, spendPublicKey): " +
|
||||
"(\(redacting: viewPublicKey), \(redacting: spendPublicKey)), " +
|
||||
"fogReportUrl: \(String(describing: fogReportUrl?.url)), " +
|
||||
"fogReportId: \(String(describing: fogReportId)), " +
|
||||
"fogAuthoritySig: \(redacting: String(describing: fogAuthoritySig))"
|
||||
}
|
||||
}
|
||||
|
||||
extension PublicAddress: Equatable {}
|
||||
extension PublicAddress: Hashable {}
|
||||
|
||||
extension PublicAddress: CustomRedactingStringConvertible {
|
||||
var redactingDescription: String {
|
||||
var params = [
|
||||
"viewPublicKey=\(redacting: viewPublicKey.base64EncodedString())",
|
||||
"spendPublicKey=\(redacting: spendPublicKey.base64EncodedString())",
|
||||
]
|
||||
if let fogInfo = fogInfo {
|
||||
params += [
|
||||
"fogReportUrl: \(fogInfo.reportUrlString)",
|
||||
"fogReportId: \(fogInfo.reportId)",
|
||||
"fogAuthoritySig: \(redacting: fogInfo.authoritySig)",
|
||||
]
|
||||
}
|
||||
return "PublicAddress(\(params.joined(separator: ", ")))"
|
||||
}
|
||||
}
|
||||
|
||||
extension PublicAddress {
|
||||
init(
|
||||
viewPrivateKey: RistrettoPrivate,
|
||||
|
||||
9
Sources/Common/CustomRedactingStringConvertible.swift
Normal file
9
Sources/Common/CustomRedactingStringConvertible.swift
Normal file
@ -0,0 +1,9 @@
|
||||
//
|
||||
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol CustomRedactingStringConvertible {
|
||||
var redactingDescription: String { get }
|
||||
}
|
||||
@ -1,5 +1,3 @@
|
||||
// swiftlint:disable:this file_name
|
||||
|
||||
//
|
||||
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
|
||||
//
|
||||
@ -250,9 +248,21 @@ extension Logger {
|
||||
}
|
||||
|
||||
extension DefaultStringInterpolation {
|
||||
mutating func appendInterpolation<T: CustomStringConvertible>(sensitive: T) {
|
||||
mutating func appendInterpolation<T>(redacting value: T)
|
||||
where T: CustomStringConvertible & TextOutputStreamable
|
||||
{
|
||||
if logSensitiveDataInternal.get() {
|
||||
appendInterpolation(sensitive)
|
||||
appendInterpolation(value)
|
||||
} else {
|
||||
appendInterpolation("<redacted>")
|
||||
}
|
||||
}
|
||||
|
||||
mutating func appendInterpolation<T: TextOutputStreamable>(redacting value: T) {
|
||||
if logSensitiveDataInternal.get() {
|
||||
appendInterpolation(value)
|
||||
} else {
|
||||
appendInterpolation("<redacted>")
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,4 +273,24 @@ extension DefaultStringInterpolation {
|
||||
appendInterpolation("<redacted>")
|
||||
}
|
||||
}
|
||||
|
||||
mutating func appendInterpolation<T>(redacting value: T) {
|
||||
if logSensitiveDataInternal.get() {
|
||||
appendInterpolation(value)
|
||||
} else {
|
||||
appendInterpolation("<redacted>")
|
||||
}
|
||||
}
|
||||
|
||||
mutating func appendInterpolation(redacting value: Any.Type) {
|
||||
if logSensitiveDataInternal.get() {
|
||||
appendInterpolation(value)
|
||||
} else {
|
||||
appendInterpolation("<redacted>")
|
||||
}
|
||||
}
|
||||
|
||||
mutating func appendInterpolation<T: CustomRedactingStringConvertible>(redacting value: T) {
|
||||
appendInterpolation(value.redactingDescription)
|
||||
}
|
||||
}
|
||||
@ -46,12 +46,11 @@ enum VersionedCryptoBox {
|
||||
}).mapError {
|
||||
switch $0.errorCode {
|
||||
case .aead:
|
||||
return InvalidInputError($0.description)
|
||||
return InvalidInputError("\(redacting: $0.description)")
|
||||
default:
|
||||
// Safety: mc_versioned_crypto_box_encrypt should not throw
|
||||
// non-documented errors.
|
||||
logger.fatalError(
|
||||
"Unhandled LibMobileCoin error: \(redacting: $0.description)")
|
||||
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: $0)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -77,16 +76,15 @@ enum VersionedCryptoBox {
|
||||
switch $0.errorCode {
|
||||
case .aead:
|
||||
return .invalidInput(
|
||||
"VersionedCryptoBox decryption error: \($0.description)")
|
||||
"VersionedCryptoBox decryption error: \(redacting: $0.description)")
|
||||
case .unsupportedCryptoBoxVersion:
|
||||
return .unsupportedVersion($0.description)
|
||||
return .unsupportedVersion("\(redacting: $0.description)")
|
||||
case .invalidInput:
|
||||
logger.fatalError("error: \($0.description)")
|
||||
logger.fatalError("error: \(redacting: $0.description)")
|
||||
default:
|
||||
// Safety: mc_tx_out_get_key_image should not throw non-documented
|
||||
// errors.
|
||||
logger.fatalError(
|
||||
"Unhandled LibMobileCoin error: \(redacting: $0.description)")
|
||||
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: $0)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,8 @@ public enum MobUri {
|
||||
logger.info("")
|
||||
guard let uri = URL(string: uriString) else {
|
||||
logger.info("Could not parse MobURI as URL: \(redacting: uriString)")
|
||||
return .failure(InvalidInputError("Could not parse MobUri as URL: \(uriString)"))
|
||||
return .failure(
|
||||
InvalidInputError("Could not parse MobUri as URL: \(redacting: uriString)"))
|
||||
}
|
||||
guard let scheme = uri.scheme else {
|
||||
logger.info("MobUri scheme cannot be empty.")
|
||||
@ -81,8 +82,7 @@ extension MobUri.Payload {
|
||||
let payloadString = pathComponents[1]
|
||||
guard let decodingResult = Base58Coder.decode(payloadString) else {
|
||||
return .failure(InvalidInputError(
|
||||
"MobUri payload base-58 decoding " +
|
||||
"failed. payload \(redacting: payloadString)"))
|
||||
"MobUri payload base-58 decoding failed. Payload: \(redacting: payloadString)"))
|
||||
}
|
||||
|
||||
return .success(MobUri.Payload(decodingResult))
|
||||
|
||||
@ -32,8 +32,7 @@ extension Printable_PrintableWrapper {
|
||||
serialized = try serializedData()
|
||||
} catch {
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`.
|
||||
logger.fatalError(
|
||||
"Error: Protobuf serialization failed: \(error)")
|
||||
logger.fatalError("Protobuf serialization failed: \(redacting: error)")
|
||||
}
|
||||
|
||||
return serialized.asMcBuffer { bufferPtr in
|
||||
|
||||
@ -26,10 +26,10 @@ struct FogUntrustedTxOutFetcher {
|
||||
results.first(where: { $0.txOutPubkey.data == outputPublicKey.data })
|
||||
else {
|
||||
logger.info("failure - Fog UntrustedTxOut service failed to " +
|
||||
"return the requested TxOut: \(redacting: results)")
|
||||
"return the requested TxOut: \(redacting: results)")
|
||||
return .failure(.invalidServerResponse(
|
||||
"Fog UntrustedTxOut service failed to return the requested TxOut. " +
|
||||
"\(results)"))
|
||||
"\(results)"))
|
||||
}
|
||||
return .success((result, blockCount: blockCount))
|
||||
})
|
||||
@ -55,7 +55,7 @@ struct FogUntrustedTxOutFetcher {
|
||||
let outputPublicKeys = outputPublicKeys.map { $0.data }
|
||||
guard let results = publicKeyToResult[outputPublicKeys] else {
|
||||
logger.info("failure - Fog UntrustedTxOut service failed to " +
|
||||
"return the requested TxOuts: \(redacting: response.results)")
|
||||
"return the requested TxOuts: \(redacting: response.results)")
|
||||
return .failure(.invalidServerResponse(
|
||||
"Fog UntrustedTxOut service failed to return the requested TxOuts. " +
|
||||
"\(response)"))
|
||||
|
||||
@ -50,8 +50,7 @@ final class FogResolver {
|
||||
serializedReportResponse = try reportResponse.serializedData()
|
||||
} catch {
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`.
|
||||
logger.fatalError(
|
||||
"ERROR - Protobuf serialization failed: \(error)")
|
||||
logger.fatalError("Protobuf serialization failed: \(redacting: error)")
|
||||
}
|
||||
|
||||
serializedReportResponse.asMcBuffer { reportResponsePtr in
|
||||
@ -74,8 +73,7 @@ final class FogResolver {
|
||||
default:
|
||||
// Safety: mc_fog_resolver_add_report_response should not throw non-documented
|
||||
// errors.
|
||||
logger.fatalError(
|
||||
"ERROR - Unhandled LibMobileCoin error: \(error)")
|
||||
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ final class FogResolverManager {
|
||||
addresses: [PublicAddress],
|
||||
completion: @escaping (Result<FogResolver, ConnectionError>) -> Void
|
||||
) {
|
||||
logger.info("addresses: \(addresses.map { $0.debugDescription })")
|
||||
logger.info("addresses: \(addresses.map { "\(redacting: $0)" })")
|
||||
let reportUrls = Set(addresses.compactMap { $0.fogReportUrl })
|
||||
reportUrls.mapAsync({ reportUrl, callback in
|
||||
reportManager.reportResponse(for: reportUrl) {
|
||||
@ -51,8 +51,8 @@ final class FogResolverManager {
|
||||
desiredMinPubkeyExpiry: UInt64,
|
||||
completion: @escaping (Result<FogResolver, ConnectionError>) -> Void
|
||||
) {
|
||||
logger.info("\(addresses.map { $0.debugDescription }), " +
|
||||
"desiredMinPubkeyExpiry: \(desiredMinPubkeyExpiry)")
|
||||
logger.info("\(addresses.map { "\(redacting: $0)" }), " +
|
||||
"desiredMinPubkeyExpiry: \(desiredMinPubkeyExpiry)")
|
||||
let fogInfos = addresses.compactMap { $0.fogInfo }
|
||||
|
||||
let reportUrlsToFogInfos = Dictionary(grouping: fogInfos, by: { $0.reportUrl })
|
||||
|
||||
@ -41,13 +41,12 @@ final class FogRng {
|
||||
}.mapError {
|
||||
switch $0.errorCode {
|
||||
case .invalidInput:
|
||||
return .invalidKey($0.description)
|
||||
return .invalidKey("\(redacting: $0.description)")
|
||||
case .unsupportedCryptoBoxVersion:
|
||||
return .unsupportedCryptoBoxVersion($0.description)
|
||||
return .unsupportedCryptoBoxVersion("\(redacting: $0.description)")
|
||||
default:
|
||||
// Safety: mc_fog_rng_create should not throw non-documented errors.
|
||||
logger.fatalError(
|
||||
"Unhandled LibMobileCoin error: \($0)")
|
||||
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: $0)")
|
||||
}
|
||||
}.map { ptr in
|
||||
FogRng(ptr)
|
||||
@ -66,14 +65,13 @@ final class FogRng {
|
||||
switch $0.errorCode {
|
||||
case .invalidInput:
|
||||
logger.warning("invalid key: \(redacting: $0.description)")
|
||||
return .invalidKey($0.description)
|
||||
return .invalidKey("\(redacting: $0.description)")
|
||||
case .unsupportedCryptoBoxVersion:
|
||||
logger.warning("unsupported crypto box version: \(redacting: $0.description)")
|
||||
return .unsupportedCryptoBoxVersion($0.description)
|
||||
return .unsupportedCryptoBoxVersion("\(redacting: $0.description)")
|
||||
default:
|
||||
// Safety: mc_fog_rng_deserialize_proto should not throw non-documented errors.
|
||||
logger.fatalError(
|
||||
"Unhandled LibMobileCoin error: \(redacting: $0.description)")
|
||||
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: $0)")
|
||||
}
|
||||
}
|
||||
}.map { ptr in
|
||||
|
||||
@ -25,7 +25,7 @@ final class FogRngSet {
|
||||
numOutputs: PositiveInt,
|
||||
minOutputsPerSelectedRng: Int
|
||||
) -> FogSearchAttempt {
|
||||
logger.info("requestedBlockCount: \(redacting: String(describing: requestedBlockCount)), " +
|
||||
logger.info("requestedBlockCount: \(String(describing: requestedBlockCount)), " +
|
||||
"numOutputs: \(numOutputs.value), minOutputsPerSelectedRng: " +
|
||||
"\(minOutputsPerSelectedRng)")
|
||||
// Max rngs we can select while maintaining the requested minimum outputs per selected rng.
|
||||
@ -109,6 +109,9 @@ final class FogRngSet {
|
||||
}
|
||||
}
|
||||
|
||||
// Record that Fog has told us about all rngs that could possibly have been active up to
|
||||
// `highestProcessedBlockCount` (while accounting for the possibility that we already have
|
||||
// more up-to-date information already).
|
||||
if highestProcessedBlockCount > rngRecordsKnownBlockCount {
|
||||
rngRecordsKnownBlockCount = highestProcessedBlockCount
|
||||
}
|
||||
@ -287,7 +290,7 @@ extension RngTracker {
|
||||
static func make(rngRecord: FogView_RngRecord, accountKey: AccountKey)
|
||||
-> Result<RngTracker, ConnectionError>
|
||||
{
|
||||
logger.info("rngRecordPubKey: \(redacting: rngRecord.pubkey.pubkey)")
|
||||
logger.info("rngRecordPubKey: \(rngRecord.pubkey.pubkey)")
|
||||
switch FogRng.make(accountKey: accountKey, fogRngKey: FogRngKey(rngRecord.pubkey)) {
|
||||
case .success(let rng):
|
||||
logger.info("success")
|
||||
|
||||
@ -142,7 +142,7 @@ final class FogView {
|
||||
serializedTxOutRecord = try txOutRecord.serializedData()
|
||||
} catch {
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`.
|
||||
logger.fatalError("Protobuf serialization failed: \(error)")
|
||||
logger.fatalError("Protobuf serialization failed: \(redacting: error)")
|
||||
}
|
||||
logger.info("Invalid TxOut returned from Fog View.")
|
||||
return .failure(.invalidServerResponse(
|
||||
|
||||
@ -20,8 +20,7 @@ enum FogViewUtils {
|
||||
plaintext = try txOutRecord.serializedData()
|
||||
} catch {
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`.
|
||||
logger.fatalError(
|
||||
"Error: Protobuf serialization failed: \(error)")
|
||||
logger.fatalError("Protobuf serialization failed: \(redacting: error)")
|
||||
}
|
||||
return VersionedCryptoBox.encrypt(
|
||||
plaintext: plaintext,
|
||||
|
||||
@ -26,8 +26,7 @@ struct TxOut: TxOutProtocol {
|
||||
return try proto.serializedData()
|
||||
} catch {
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`.
|
||||
logger.fatalError(
|
||||
"Error: Protobuf serialization failed: \(error)")
|
||||
logger.fatalError("Protobuf serialization failed: \(redacting: error)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -26,8 +26,7 @@ extension TxOutMembershipProof {
|
||||
serializedData = try txOutMembershipProof.serializedData()
|
||||
} catch {
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`.
|
||||
logger.fatalError(
|
||||
"Error: Protobuf serialization failed: \(error)")
|
||||
logger.fatalError("Protobuf serialization failed: \(redacting: error)")
|
||||
}
|
||||
self.init(serializedData: serializedData)
|
||||
}
|
||||
|
||||
@ -28,8 +28,7 @@ func withMcError(_ body: (inout UnsafeMutablePointer<McError>?) -> OpaquePointer
|
||||
logger.fatalError("Error: \(#function): \(error)")
|
||||
}
|
||||
guard err.errorCode != .panic else {
|
||||
logger.fatalError(
|
||||
"Error: \(#function): LibMobileCoin function panicked: \(err.description)")
|
||||
logger.fatalError("LibMobileCoin function panicked: \(redacting: err.description)")
|
||||
}
|
||||
return .failure(err)
|
||||
}
|
||||
@ -58,8 +57,7 @@ func withMcError(_ body: (inout UnsafeMutablePointer<McError>?) -> Bool)
|
||||
logger.fatalError("Error: \(#function): \(error)")
|
||||
}
|
||||
guard err.errorCode != .panic else {
|
||||
logger.fatalError(
|
||||
"Error: \(#function): LibMobileCoin function panicked: \(err.description)")
|
||||
logger.fatalError("LibMobileCoin function panicked: \(redacting: err.description)")
|
||||
}
|
||||
return .failure(err)
|
||||
}
|
||||
@ -89,8 +87,7 @@ func withMcErrorReturningOptional<T>(_ body: (inout UnsafeMutablePointer<McError
|
||||
logger.fatalError("Error: \(#function): \(error)")
|
||||
}
|
||||
guard err.errorCode != .panic else {
|
||||
logger.fatalError(
|
||||
"Error: \(#function): LibMobileCoin function panicked: \(err.description)")
|
||||
logger.fatalError("LibMobileCoin function panicked: \(redacting: err.description)")
|
||||
}
|
||||
return .failure(err)
|
||||
}
|
||||
@ -114,8 +111,7 @@ func withMcErrorReturningArrayCount(_ body: (inout UnsafeMutablePointer<McError>
|
||||
logger.fatalError("Error: \(#function): \(error)")
|
||||
}
|
||||
guard err.errorCode != .panic else {
|
||||
logger.fatalError(
|
||||
"Error: \(#function): LibMobileCoin function panicked: \(err.description)")
|
||||
logger.fatalError("LibMobileCoin function panicked: \(redacting: err.description)")
|
||||
}
|
||||
return .failure(err)
|
||||
}
|
||||
|
||||
@ -15,11 +15,10 @@ enum Bip39Utils {
|
||||
switch $0.errorCode {
|
||||
case .invalidInput:
|
||||
return InvalidInputError(
|
||||
"BIP39: error deriving entropy from mnemonic: \($0.description)")
|
||||
"BIP39: error deriving entropy from mnemonic: \(redacting: $0.description)")
|
||||
default:
|
||||
// Safety: mc_bip39_entropy_from_mnemonic should not throw non-documented errors.
|
||||
logger.fatalError(
|
||||
"\(Self.self).\(#function): Unhandled LibMobileCoin error: \($0)")
|
||||
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: $0)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -47,12 +46,11 @@ enum Bip39Utils {
|
||||
}.mapError {
|
||||
switch $0.errorCode {
|
||||
case .invalidInput:
|
||||
return InvalidInputError(
|
||||
"BIP39: error getting seed from mnemonic and passphrase: \($0.description)")
|
||||
return InvalidInputError("BIP39: error getting seed from mnemonic and " +
|
||||
"passphrase: \(redacting: $0.description)")
|
||||
default:
|
||||
// Safety: mc_bip39_get_seed should not throw non-documented errors.
|
||||
logger.fatalError(
|
||||
"\(Self.self).\(#function): Unhandled LibMobileCoin error: \($0)")
|
||||
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: $0)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ public final class MobileCoinClient {
|
||||
-> Result<MobileCoinClient, InvalidInputError>
|
||||
{
|
||||
guard let accountKey = AccountKeyWithFog(accountKey: accountKey) else {
|
||||
logger.error("Accounts without fog URLs are not currently supported.")
|
||||
return .failure(
|
||||
InvalidInputError("Accounts without fog URLs are not currently supported."))
|
||||
}
|
||||
@ -74,8 +75,8 @@ public final class MobileCoinClient {
|
||||
}
|
||||
|
||||
public func updateBalance(completion: @escaping (Result<Balance, ConnectionError>) -> Void) {
|
||||
logger.info("")
|
||||
inner.accessAsync {
|
||||
logger.info("")
|
||||
Account.BalanceUpdater(
|
||||
account: self.accountLock,
|
||||
fogViewService: $0.serviceProvider.fogViewService,
|
||||
@ -84,6 +85,7 @@ public final class MobileCoinClient {
|
||||
fogQueryScalingStrategy: self.fogQueryScalingStrategy,
|
||||
targetQueue: self.serialQueue
|
||||
).updateBalance { result in
|
||||
logger.info("updateBalance result: \(redacting: result)")
|
||||
self.callbackQueue.async {
|
||||
completion(result)
|
||||
}
|
||||
@ -95,10 +97,12 @@ public final class MobileCoinClient {
|
||||
-> Result<UInt64, BalanceTransferEstimationError>
|
||||
{
|
||||
logger.info("feeLevel: \(feeLevel)")
|
||||
return Account.TransactionEstimator(
|
||||
let amountTransferable = Account.TransactionEstimator(
|
||||
account: accountLock,
|
||||
txOutSelectionStrategy: self.txOutSelectionStrategy
|
||||
).amountTransferable(feeLevel: feeLevel)
|
||||
logger.info("amountTransferable result: \(redacting: amountTransferable)")
|
||||
return amountTransferable
|
||||
}
|
||||
|
||||
public func estimateTotalFee(
|
||||
@ -106,20 +110,24 @@ public final class MobileCoinClient {
|
||||
feeLevel: FeeLevel = .minimum
|
||||
) -> Result<UInt64, TransactionEstimationError> {
|
||||
logger.info("toSendAmount: \(redacting: amount), feeLevel: \(feeLevel)")
|
||||
return Account.TransactionEstimator(
|
||||
let totalFee = Account.TransactionEstimator(
|
||||
account: accountLock,
|
||||
txOutSelectionStrategy: self.txOutSelectionStrategy
|
||||
).estimateTotalFee(toSendAmount: amount, feeLevel: feeLevel)
|
||||
logger.info("totalFee result: \(redacting: totalFee)")
|
||||
return totalFee
|
||||
}
|
||||
|
||||
public func requiresDefragmentation(toSendAmount amount: UInt64, feeLevel: FeeLevel = .minimum)
|
||||
-> Result<Bool, TransactionEstimationError>
|
||||
{
|
||||
logger.info("toSendAmount: \(redacting: amount), feeLevel: \(feeLevel)")
|
||||
return Account.TransactionEstimator(
|
||||
let requiresDefragmentation = Account.TransactionEstimator(
|
||||
account: accountLock,
|
||||
txOutSelectionStrategy: self.txOutSelectionStrategy
|
||||
).requiresDefragmentation(toSendAmount: amount, feeLevel: feeLevel)
|
||||
logger.info("requiresDefragmentation result: \(redacting: requiresDefragmentation)")
|
||||
return requiresDefragmentation
|
||||
}
|
||||
|
||||
public func prepareTransaction(
|
||||
@ -130,9 +138,9 @@ public final class MobileCoinClient {
|
||||
Result<(transaction: Transaction, receipt: Receipt), TransactionPreparationError>
|
||||
) -> Void
|
||||
) {
|
||||
logger.info(
|
||||
"recipient: \(recipient.debugDescription), amount: \(redacting: amount), fee: \(fee)")
|
||||
inner.accessAsync {
|
||||
logger.info("recipient: \(redacting: recipient), amount: \(redacting: amount), " +
|
||||
"fee: \(redacting: fee)")
|
||||
Account.TransactionOperations(
|
||||
account: self.accountLock,
|
||||
fogMerkleProofService: $0.serviceProvider.fogMerkleProofService,
|
||||
@ -156,10 +164,9 @@ public final class MobileCoinClient {
|
||||
Result<(transaction: Transaction, receipt: Receipt), TransactionPreparationError>
|
||||
) -> Void
|
||||
) {
|
||||
logger.info(
|
||||
"recipient: \(recipient.debugDescription), amount: \(redacting: amount), " +
|
||||
"feeLevel: \(feeLevel)")
|
||||
inner.accessAsync {
|
||||
logger.info("recipient: \(redacting: recipient), amount: \(redacting: amount), " +
|
||||
"feeLevel: \(feeLevel)")
|
||||
Account.TransactionOperations(
|
||||
account: self.accountLock,
|
||||
fogMerkleProofService: $0.serviceProvider.fogMerkleProofService,
|
||||
@ -328,6 +335,7 @@ extension MobileCoinClient {
|
||||
networkConfig.consensusTrustRoots =
|
||||
try trustRoots.map { try NIOSSLCertificate(bytes: Array($0), format: .der) }
|
||||
} catch {
|
||||
logger.error("Failed parsing Consensus trust roots: \(error)")
|
||||
return .failure(InvalidInputError("Failed parsing Consensus trust roots: \(error)"))
|
||||
}
|
||||
return .success(())
|
||||
@ -339,6 +347,7 @@ extension MobileCoinClient {
|
||||
networkConfig.fogTrustRoots =
|
||||
try trustRoots.map { try NIOSSLCertificate(bytes: Array($0), format: .der) }
|
||||
} catch {
|
||||
logger.error("Failed parsing Fog trust roots: \(error)")
|
||||
return .failure(InvalidInputError("Failed parsing Fog trust roots: \(error)"))
|
||||
}
|
||||
return .success(())
|
||||
|
||||
@ -237,14 +237,13 @@ private final class FfiAttestAke {
|
||||
}.mapError {
|
||||
switch $0.errorCode {
|
||||
case .invalidInput:
|
||||
return .invalidInput($0.description)
|
||||
return .invalidInput("\(redacting: $0.description)")
|
||||
case .attestationVerificationFailed:
|
||||
return .attestationVerificationFailed($0.description)
|
||||
return .attestationVerificationFailed("\(redacting: $0.description)")
|
||||
default:
|
||||
// Safety: mc_attest_ake_process_auth_response should not throw
|
||||
// non-documented errors.
|
||||
logger.fatalError(
|
||||
"Unhandled LibMobileCoin error: \($0)")
|
||||
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: $0)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -260,13 +259,12 @@ private final class FfiAttestAke {
|
||||
}).mapError {
|
||||
switch $0.errorCode {
|
||||
case .aead:
|
||||
return .aead($0.description)
|
||||
return .aead("\(redacting: $0.description)")
|
||||
case .cipher:
|
||||
return .cipher($0.description)
|
||||
return .cipher("\(redacting: $0.description)")
|
||||
default:
|
||||
// Safety: mc_attest_ake_encrypt should not throw non-documented errors.
|
||||
logger.fatalError(
|
||||
"Unhandled LibMobileCoin error: \($0)")
|
||||
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: $0)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -283,13 +281,12 @@ private final class FfiAttestAke {
|
||||
}.mapError {
|
||||
switch $0.errorCode {
|
||||
case .aead:
|
||||
return .aead($0.description)
|
||||
return .aead("\(redacting: $0.description)")
|
||||
case .cipher:
|
||||
return .cipher($0.description)
|
||||
return .cipher("\(redacting: $0.description)")
|
||||
default:
|
||||
// Safety: mc_attest_ake_decrypt should not throw non-documented errors.
|
||||
logger.fatalError(
|
||||
"Unhandled LibMobileCoin error: \($0)")
|
||||
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: $0)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,9 +75,8 @@ extension AttestedGrpcCallable
|
||||
do {
|
||||
plaintext = try request.serializedData()
|
||||
} catch {
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`
|
||||
logger.fatalError(
|
||||
"Error: Protobuf serialization failed: \(error)")
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`.
|
||||
logger.fatalError("Protobuf serialization failed: \(redacting: error)")
|
||||
}
|
||||
|
||||
return attestAkeCipher.encryptMessage(aad: aad, plaintext: plaintext)
|
||||
@ -129,9 +128,8 @@ extension AttestedGrpcCallable
|
||||
aad = try requestAad.serializedData()
|
||||
plaintext = try request.serializedData()
|
||||
} catch {
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`
|
||||
logger.fatalError(
|
||||
"Error: Protobuf serialization failed: \(error)")
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`.
|
||||
logger.fatalError("Protobuf serialization failed: \(redacting: error)")
|
||||
}
|
||||
|
||||
return attestAkeCipher.encryptMessage(aad: aad, plaintext: plaintext)
|
||||
|
||||
@ -56,9 +56,8 @@ public struct Receipt {
|
||||
do {
|
||||
return try proto.serializedData()
|
||||
} catch {
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`
|
||||
logger.fatalError(
|
||||
"Error: Protobuf serialization failed: \(error)")
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`.
|
||||
logger.fatalError("Protobuf serialization failed: \(redacting: error)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -23,9 +23,8 @@ public struct Transaction {
|
||||
do {
|
||||
return try proto.serializedData()
|
||||
} catch {
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`
|
||||
logger.fatalError(
|
||||
"Error: Protobuf serialization failed: \(error)")
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`.
|
||||
logger.fatalError("Protobuf serialization failed: \(redacting: error)")
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,9 +103,8 @@ extension Transaction {
|
||||
do {
|
||||
txOutData = try $0.serializedData()
|
||||
} catch {
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`
|
||||
logger.fatalError(
|
||||
"Error: Protobuf serialization failed: \(error)")
|
||||
// Safety: Protobuf binary serialization is no fail when not using proto2 or `Any`.
|
||||
logger.fatalError("Protobuf serialization failed: \(redacting: error)")
|
||||
}
|
||||
guard let txOut = TxOut(serializedData: txOutData) else {
|
||||
logger.fatalError("serialization failure")
|
||||
|
||||
@ -314,12 +314,11 @@ final class TransactionBuilder {
|
||||
}.mapError {
|
||||
switch $0.errorCode {
|
||||
case .invalidInput:
|
||||
return .invalidInput($0.description)
|
||||
return .invalidInput("\(redacting: $0.description)")
|
||||
default:
|
||||
// Safety: mc_transaction_builder_add_input should not throw
|
||||
// non-documented errors.
|
||||
logger.fatalError(
|
||||
"Unhandled LibMobileCoin error: \($0)")
|
||||
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: $0)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -349,14 +348,13 @@ final class TransactionBuilder {
|
||||
}).mapError {
|
||||
switch $0.errorCode {
|
||||
case .invalidInput:
|
||||
return .invalidInput($0.description)
|
||||
return .invalidInput("\(redacting: $0.description)")
|
||||
case .attestationVerificationFailed:
|
||||
return .attestationVerificationFailed($0.description)
|
||||
return .attestationVerificationFailed("\(redacting: $0.description)")
|
||||
default:
|
||||
// Safety: mc_transaction_builder_add_output should not throw
|
||||
// non-documented errors.
|
||||
logger.fatalError(
|
||||
"Unhandled LibMobileCoin error: \($0)")
|
||||
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: $0)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -389,11 +387,10 @@ final class TransactionBuilder {
|
||||
}).mapError {
|
||||
switch $0.errorCode {
|
||||
case .invalidInput:
|
||||
return .invalidInput($0.description)
|
||||
return .invalidInput("\(redacting: $0.description)")
|
||||
default:
|
||||
// Safety: mc_transaction_builder_build should not throw non-documented errors.
|
||||
logger.fatalError(
|
||||
"Unhandled LibMobileCoin error: \($0)")
|
||||
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: $0)")
|
||||
}
|
||||
}
|
||||
}.map { txBytes in
|
||||
|
||||
@ -14,7 +14,6 @@ extension Collection {
|
||||
guard distance(from: startIndex, to: endIndex) > 0 else {
|
||||
break
|
||||
}
|
||||
|
||||
chunks.append(self[startIndex ..< Swift.min(nextIndex, self.endIndex)])
|
||||
}
|
||||
return chunks
|
||||
|
||||
Loading…
Reference in New Issue
Block a user