5 func preflightVouchWithBottle(bottleID: String,
6 reply: @escaping (String?, Set<String>?, TPPolicy?, Error?) -> Void) {
8 let reply: (String?, Set<String>?, TPPolicy?, Error?) -> Void = {
9 os_log("preflightVouchWithBottle complete: %{public}@",
10 log: tplogTrace, type: .info, traceError($3))
11 self.semaphore.signal()
15 self.fetchAndPersistChangesIfNeeded { fetchError in
16 guard fetchError == nil else {
17 os_log("preflightVouchWithBottle unable to fetch current peers: %{public}@", log: tplogDebug, type: .default, (fetchError as CVarArg?) ?? "")
18 reply(nil, nil, nil, fetchError)
22 // Ensure we have all policy versions claimed by peers, including our sponsor
23 let allPolicyVersions = self.model.allPolicyVersions()
24 self.fetchPolicyDocumentsWithSemaphore(versions: allPolicyVersions) { _, fetchPolicyDocumentsError in
25 guard fetchPolicyDocumentsError == nil else {
26 os_log("preflightVouchWithBottle unable to fetch policy documents: %{public}@", log: tplogDebug, type: .default, (fetchPolicyDocumentsError as CVarArg?) ?? "no error")
27 reply(nil, nil, nil, fetchPolicyDocumentsError)
31 self.moc.performAndWait {
32 guard let egoPeerID = self.containerMO.egoPeerID,
33 let egoPermData = self.containerMO.egoPeerPermanentInfo,
34 let egoPermSig = self.containerMO.egoPeerPermanentInfoSig else {
35 os_log("fetchCurrentPolicy failed to find ego peer information", log: tplogDebug, type: .error)
36 reply(nil, nil, nil, ContainerError.noPreparedIdentity)
40 let keyFactory = TPECPublicKeyFactory()
41 guard let egoPermanentInfo = TPPeerPermanentInfo(peerID: egoPeerID, data: egoPermData, sig: egoPermSig, keyFactory: keyFactory) else {
42 os_log("fetchCurrentPolicy failed to create TPPeerPermanentInfo", log: tplogDebug, type: .error)
43 reply(nil, nil, nil, ContainerError.invalidPermanentInfoOrSig)
47 self.onqueueFindBottle(bottleID: bottleID) { bottleMO, error in
48 guard let bottleMO = bottleMO else {
49 os_log("preflightVouchWithBottle found no bottle: %{public}@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "")
50 reply(nil, nil, nil, error)
54 guard let sponsorPeer = self.model.peer(withID: bottleMO.peerID ?? "") else {
55 os_log("preflightVouchWithBottle found no peer to match bottle", log: tplogDebug, type: .default)
56 reply(nil, nil, nil, ContainerError.sponsorNotRegistered(bottleMO.peerID ?? "no peer ID given"))
60 guard let sponsorPeerStableInfo = sponsorPeer.stableInfo else {
61 os_log("preflightVouchWithBottle sponsor peer has no stable info", log: tplogDebug, type: .default)
62 reply(nil, nil, nil, ContainerError.sponsorNotRegistered(bottleMO.peerID ?? "no peer ID given"))
67 // We need to extract the syncing policy that the remote peer would have used (if they were the type of device that we are)
68 // So, figure out their policy version...
69 let (views, policy) = try self.policyAndViewsFor(permanentInfo: egoPermanentInfo, stableInfo: sponsorPeerStableInfo)
71 reply(bottleMO.peerID, views, policy, nil)
73 os_log("preflightVouchWithBottle failed to fetch policy: %{public}@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "")
74 reply(nil, nil, nil, error)