TeraPublicationEvidence.swift (2618B)
1 import Foundation 2 import TeraKitBindings 3 4 enum TeraPublicationDeliveryState: Sendable, Equatable { 5 case notIssued, unknown, partiallyAccepted, accepted 6 } 7 8 /// A projection of backend facts, independent of the native waiter's state. 9 struct TeraPublicationEvidence: Sendable, Equatable { 10 let state: TeraPublicationDeliveryState 11 let stopRequestedAtUnixMilliseconds: UInt64? 12 let schedulingRevision: UInt64 13 let retainedFacts: UInt32 14 let recordedAttempts: UInt32 15 let unresolvedClaims: Bool 16 17 var isStopped: Bool { 18 stopRequestedAtUnixMilliseconds != nil 19 } 20 21 func follows(_ previous: Self) -> Bool { 22 guard schedulingRevision >= previous.schedulingRevision, 23 retainedFacts >= previous.retainedFacts, recordedAttempts >= previous.recordedAttempts, 24 previous.stopRequestedAtUnixMilliseconds == nil 25 || stopRequestedAtUnixMilliseconds == previous.stopRequestedAtUnixMilliseconds else { return false } 26 switch previous.state { 27 case .accepted: return state == .accepted 28 case .partiallyAccepted: return [.partiallyAccepted, .accepted].contains(state) 29 case .unknown: return state != .notIssued 30 case .notIssued: return true 31 } 32 } 33 34 var stoppedSummary: String { 35 switch state { 36 case .notIssued: "Stopped. No relay delivery attempt was issued." 37 case .unknown: "Stopped. Relay delivery is uncertain; the original operation is retained for reconciliation." 38 case .partiallyAccepted: "Stopped. Some saved relays accepted this publication." 39 case .accepted: "Stopped. Delivery was accepted under the saved relay policy." 40 } 41 } 42 43 static func decode(_ value: FfiPublicationDeliveryEvidence) throws -> Self { 44 guard value.schedulingRevision > 0, value.schedulingRevision <= UInt64(Int64.max), 45 value.retainedFacts <= 1024, value.recordedAttempts <= 1024, 46 value.stopRequestedAtUnixMs.map({ $0 > 0 && $0 <= UInt64(Int64.max) }) != false, 47 value.state != .notIssued || (!value.unresolvedClaims && value.retainedFacts == 0 && value.recordedAttempts == 0) 48 else { throw TeraGeneratedSubmission.mismatch() } 49 let state: TeraPublicationDeliveryState = switch value.state { 50 case .notIssued: .notIssued 51 case .unknown: .unknown 52 case .partiallyAccepted: .partiallyAccepted 53 case .accepted: .accepted 54 } 55 return Self(state: state, stopRequestedAtUnixMilliseconds: value.stopRequestedAtUnixMs, 56 schedulingRevision: value.schedulingRevision, retainedFacts: value.retainedFacts, 57 recordedAttempts: value.recordedAttempts, unresolvedClaims: value.unresolvedClaims) 58 } 59 }