Clean up logging and redact LibMobileCoin and Protobuf errors (#12)

This commit is contained in:
Kyle Fleming 2021-03-31 23:02:33 -10:00 committed by GitHub
parent b690db1326
commit dde923cb6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 166 additions and 133 deletions

View File

@ -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))
}

View File

@ -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

View File

@ -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
}
}

View File

@ -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,

View File

@ -0,0 +1,9 @@
//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
import Foundation
protocol CustomRedactingStringConvertible {
var redactingDescription: String { get }
}

View File

@ -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)
}
}

View File

@ -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)")
}
}
}

View File

@ -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))

View File

@ -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

View File

@ -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)"))

View File

@ -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)")
}
}
}

View File

@ -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 })

View File

@ -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

View File

@ -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")

View File

@ -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(

View File

@ -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,

View File

@ -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)")
}
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)")
}
}
}

View File

@ -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(())

View File

@ -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)")
}
}
}

View File

@ -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)

View File

@ -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)")
}
}

View File

@ -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")

View File

@ -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

View File

@ -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