I need some insights into what is using memory while the program mines a transaction in this code
import Foundation
import CryptoKit
struct Blockchain {
private var difficulty: Int
var chain: [Transaction]
init(_ difficulty: Int) {
self.difficulty = difficulty
chain = []
}
func isValidChain() -> Bool {
var prevHash: String? = nil
for transaction in chain {
let metadata = transaction.metadata
if transaction.id != 0 {
if metadata.prevHash != prevHash {
return false
}
}
if let derSignature = transaction.senderSignature {
if let signature = try? P256.Signing.ECDSASignature(derRepresentation: derSignature),
let publicKey = try? P256.Signing.PublicKey(derRepresentation: metadata.from),
let encoded = try? JSONEncoder().encode(metadata) {
if !publicKey.isValidSignature(signature, for: encoded){
return false
}
} else {
return false
}
} else {
return false
}
prevHash = calculateHash(transaction)
if let hash = prevHash {
if !hash.hasPrefix(String(repeating: "0", count: difficulty)) {
return false
}
}
}
return true
}
mutating func createTransaction(
to: Data,
privateKey: P256.Signing.PrivateKey,
value: Double
) {
var prevHash: String? = nil
if let prevTransaction = chain.last {
prevHash = calculateHash(prevTransaction)
}
let metadata = Transaction.Metadata(
prevHash: prevHash,
from: privateKey.publicKey.derRepresentation,
to: to,
value: value
)
var transaction = Transaction(
id: chain.count,
metadata: metadata,
senderSignature: calculateSignature(metadata, privateKey: privateKey)
)
var hash = calculateHash(transaction)
while true {
if let validHash = hash {
if validHash.hasPrefix(String(repeating: "0", count: difficulty)) {
break
} else {
transaction.nonce += 1
hash = calculateHash(transaction)
}
} else {
return
}
}
chain.append(transaction)
}
private func calculateHash(_ transaction: Transaction) -> String? {
if let encoded = try? JSONEncoder().encode(transaction) {
return SHA256.hash(data: encoded).compactMap {
String(format: "%02x", $0)
}.joined()
}
return nil
}
private func calculateSignature(
_ metadata: Transaction.Metadata,
privateKey: P256.Signing.PrivateKey
) -> Data? {
if let encoded = try? JSONEncoder().encode(metadata) {
return try? privateKey.signature(for: encoded).derRepresentation
}
return nil
}
struct Transaction: Codable, Identifiable {
var id: Int
var metadata: Metadata
var senderSignature: Data?
var nonce = 0
struct Metadata: Codable {
var prevHash: String?
var from: Data
var to: Data
var value: Double
}
}
}
#if DEBUG
var blockchain = Blockchain(4)
let privateKey1 = P256.Signing.PrivateKey.init(compactRepresentable: false)
let publicKey1 = privateKey1.publicKey
let privateKey2 = P256.Signing.PrivateKey.init(compactRepresentable: false)
let publicKey2 = privateKey2.publicKey
blockchain.createTransaction(
to: publicKey2.derRepresentation,
privateKey: privateKey1,
value: 0
)
blockchain.createTransaction(
to: publicKey1.derRepresentation,
privateKey: privateKey2,
value: 0
)
var output = "["
for transaction in blockchain.chain {
if let encoded = try? JSONEncoder().encode(transaction) {
output += String(data: encoded, encoding: .utf8)! + ","
}
}
let _ = output.popLast()
output += "]"
print(output)
print(blockchain.isValidChain())
while true {
sleep(1000)
}
#endif
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
This code crashed when running startApplianceListener()
when using onAppear() on a swiftui view
import AVFAudio
import CoreML
import SoundAnalysis
/// An observer that receives results from a classify sound request.
class ResultsObserver: NSObject, SNResultsObserving {
/// Notifies the observer when a request generates a prediction.
func request(_ request: SNRequest, didProduce result: SNResult) {
// Downcast the result to a classification result.
guard let result = result as? SNClassificationResult else { return }
// Get the prediction with the highest confidence.
guard let classification = result.classifications.first else { return }
// Get the starting time.
let timeInSeconds = result.timeRange.start.seconds
// Convert the time to a human-readable string.
let formattedTime = String(format: "%.2f", timeInSeconds)
print("Analysis result for audio at time: \(formattedTime)")
// Convert the confidence to a percentage string.
let percent = classification.confidence * 100.0
let percentString = String(format: "%.2f%%", percent)
// Print the classification's name (label) with its confidence.
print("\(classification.identifier): \(percentString) confidence.\n")
}
/// Notifies the observer when a request generates an error.
func request(_ request: SNRequest, didFailWithError error: Error) {
print("The the analysis failed: \(error.localizedDescription)")
}
/// Notifies the observer when a request is complete.
func requestDidComplete(_ request: SNRequest) {
print("The request completed successfully!")
}
}
func startApplianceListener() {
do {
var audioEngine: AVAudioEngine?
var inputBus: Int?
var inputFormat: AVAudioFormat?
var streamAnalyzer: SNAudioStreamAnalyzer
func startAudioEngine() {
audioEngine = AVAudioEngine()
inputBus = AVAudioNodeBus(0)
inputFormat = audioEngine!.inputNode.inputFormat(forBus: inputBus!)
do {
try audioEngine!.start()
} catch {
print("Unable to start AVAudioEngine \(error.localizedDescription)")
exit(1)
}
}
startAudioEngine()
streamAnalyzer = SNAudioStreamAnalyzer(format: inputFormat!)
let version1 = SNClassifierIdentifier.version1
let request = try SNClassifySoundRequest(classifierIdentifier: version1)
let resultsObserver = ResultsObserver()
try streamAnalyzer.add(request,
withObserver: resultsObserver)
func installAudioTap() {
audioEngine!.inputNode.installTap(onBus: inputBus!,
bufferSize: 8192,
format: inputFormat,
block: analyzeAudio(buffer:at:))
}
let analysisQueue = DispatchQueue(label: "dev.paulwalker.AnalysisQueue")
func analyzeAudio(buffer: AVAudioBuffer, at time: AVAudioTime) {
analysisQueue.async {
streamAnalyzer.analyze(buffer,
atAudioFramePosition: time.sampleTime)
}
}
installAudioTap()
} catch {}
}