Skip to content

Commit

Permalink
Add SessionExtendRequester
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-lsvk committed Oct 24, 2023
1 parent a384ef2 commit 6fe5114
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 56 deletions.
6 changes: 1 addition & 5 deletions Sources/WalletConnectSign/Engine/Common/SessionEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,9 @@ final class SessionEngine {
func hasSession(for topic: String) -> Bool {
return sessionStore.hasSession(forTopic: topic)
}

func getWCSessions() -> [WCSession] {
sessionStore.getAll()
}

func getSessions() -> [Session] {
getWCSessions().map { $0.publicRepresentation() }
sessionStore.getAll().map { $0.publicRepresentation() }
}

func request(_ request: Request) async throws {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Foundation

final class SessionExtendRequester {
private let sessionStore: WCSessionStorage
private let networkingInteractor: NetworkInteracting

init(
sessionStore: WCSessionStorage,
networkingInteractor: NetworkInteracting
) {
self.sessionStore = sessionStore
self.networkingInteractor = networkingInteractor
}

func extend(topic: String, by ttl: Int64) async throws {
guard var session = sessionStore.getSession(forTopic: topic) else {
throw WalletConnectError.noSessionMatchingTopic(topic)
}

let protocolMethod = SessionExtendProtocolMethod()
try session.updateExpiry(by: ttl)
let newExpiry = Int64(session.expiryDate.timeIntervalSince1970)
sessionStore.setSession(session)
let request = RPCRequest(method: protocolMethod.method, params: SessionType.UpdateExpiryParams(expiry: newExpiry))
try await networkingInteractor.request(request, topic: topic, protocolMethod: protocolMethod)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,7 @@ final class ControllerSessionStateMachine {
try await networkingInteractor.request(request, topic: topic, protocolMethod: protocolMethod)
}

func extend(topic: String, by ttl: Int64) async throws {
var session = try getSession(for: topic)
let protocolMethod = SessionExtendProtocolMethod()
try validateController(session)
try session.updateExpiry(by: ttl)
let newExpiry = Int64(session.expiryDate.timeIntervalSince1970 )
sessionStore.setSession(session)
let request = RPCRequest(method: protocolMethod.method, params: SessionType.UpdateExpiryParams(expiry: newExpiry))
try await networkingInteractor.request(request, topic: topic, protocolMethod: protocolMethod)
}

// MARK: - Handle Response

private func setupSubscriptions() {
networkingInteractor.responseSubscription(on: SessionUpdateProtocolMethod())
.sink { [unowned self] (payload: ResponseSubscriptionPayload<SessionType.UpdateParams, RPCResult>) in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,7 @@ final class NonControllerSessionStateMachine {
self.logger = logger
setupSubscriptions()
}

func extend(topic: String, by ttl: Int64) async throws {
guard var session = sessionStore.getSession(forTopic: topic) else {
throw WalletConnectError.noSessionMatchingTopic(topic)
}
let protocolMethod = SessionExtendProtocolMethod()
try session.updateExpiry(by: ttl)
let newExpiry = Int64(session.expiryDate.timeIntervalSince1970 )
sessionStore.setSession(session)
let request = RPCRequest(method: protocolMethod.method, params: SessionType.UpdateExpiryParams(expiry: newExpiry))
try await networkingInteractor.request(request, topic: topic, protocolMethod: protocolMethod)
}


private func setupSubscriptions() {
networkingInteractor.requestSubscription(on: SessionUpdateProtocolMethod())
.sink { [unowned self] (payload: RequestSubscriptionPayload<SessionType.UpdateParams>) in
Expand Down
12 changes: 5 additions & 7 deletions Sources/WalletConnectSign/Sign/SignClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ public final class SignClient: SignClientProtocol {
private let sessionPingService: SessionPingService
private let nonControllerSessionStateMachine: NonControllerSessionStateMachine
private let controllerSessionStateMachine: ControllerSessionStateMachine
private let sessionExtendRequester: SessionExtendRequester
private let appProposeService: AppProposeService
private let historyService: HistoryService
private let cleanupService: SignCleanupService
Expand Down Expand Up @@ -138,6 +139,7 @@ public final class SignClient: SignClientProtocol {
sessionPingService: SessionPingService,
nonControllerSessionStateMachine: NonControllerSessionStateMachine,
controllerSessionStateMachine: ControllerSessionStateMachine,
sessionExtendRequester: SessionExtendRequester,
appProposeService: AppProposeService,
disconnectService: DisconnectService,
historyService: HistoryService,
Expand All @@ -152,6 +154,7 @@ public final class SignClient: SignClientProtocol {
self.sessionPingService = sessionPingService
self.nonControllerSessionStateMachine = nonControllerSessionStateMachine
self.controllerSessionStateMachine = controllerSessionStateMachine
self.sessionExtendRequester = sessionExtendRequester
self.appProposeService = appProposeService
self.historyService = historyService
self.cleanupService = cleanupService
Expand Down Expand Up @@ -264,13 +267,8 @@ public final class SignClient: SignClientProtocol {
/// - topic: Topic of the session that is intended to be extended.
public func extend(topic: String) async throws {
let ttl: Int64 = Session.defaultTimeToLive
guard let session = sessionEngine.getWCSessions().first(where: { $0.topic == topic }) else {
throw WalletConnectError.noSessionMatchingTopic(topic)
}
if session.selfIsController {
try await controllerSessionStateMachine.extend(topic: topic, by: ttl)
} else {
try await nonControllerSessionStateMachine.extend(topic: topic, by: ttl)
if sessionEngine.hasSession(for: topic) {
try await sessionExtendRequester.extend(topic: topic, by: ttl)
}
}

Expand Down
2 changes: 2 additions & 0 deletions Sources/WalletConnectSign/Sign/SignClientFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public struct SignClientFactory {
let sessionEngine = SessionEngine(networkingInteractor: networkingClient, historyService: historyService, verifyContextStore: verifyContextStore, verifyClient: verifyClient, kms: kms, sessionStore: sessionStore, logger: logger)
let nonControllerSessionStateMachine = NonControllerSessionStateMachine(networkingInteractor: networkingClient, kms: kms, sessionStore: sessionStore, logger: logger)
let controllerSessionStateMachine = ControllerSessionStateMachine(networkingInteractor: networkingClient, kms: kms, sessionStore: sessionStore, logger: logger)
let sessionExtendRequester = SessionExtendRequester(sessionStore: sessionStore, networkingInteractor: networkingClient)
let sessionTopicToProposal = CodableStore<Session.Proposal>(defaults: RuntimeKeyValueStorage(), identifier: SignStorageIdentifiers.sessionTopicToProposal.rawValue)
let approveEngine = ApproveEngine(
networkingInteractor: networkingClient,
Expand Down Expand Up @@ -60,6 +61,7 @@ public struct SignClientFactory {
sessionPingService: sessionPingService,
nonControllerSessionStateMachine: nonControllerSessionStateMachine,
controllerSessionStateMachine: controllerSessionStateMachine,
sessionExtendRequester: sessionExtendRequester,
appProposeService: appProposerService,
disconnectService: disconnectService,
historyService: historyService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import WalletConnectKMS

class ControllerSessionStateMachineTests: XCTestCase {
var sut: ControllerSessionStateMachine!
var sessionExtendRequester: SessionExtendRequester!
var networkingInteractor: NetworkingInteractorMock!
var storageMock: WCSessionStorageMock!
var cryptoMock: KeyManagementServiceMock!
Expand All @@ -15,6 +16,7 @@ class ControllerSessionStateMachineTests: XCTestCase {
storageMock = WCSessionStorageMock()
cryptoMock = KeyManagementServiceMock()
sut = ControllerSessionStateMachine(networkingInteractor: networkingInteractor, kms: cryptoMock, sessionStore: storageMock, logger: ConsoleLoggerMock())
sessionExtendRequester = SessionExtendRequester(sessionStore: storageMock, networkingInteractor: networkingInteractor)
}

override func tearDown() {
Expand Down Expand Up @@ -66,40 +68,24 @@ class ControllerSessionStateMachineTests: XCTestCase {
let session = WCSession.stub(isSelfController: true, expiryDate: tomorrow)
storageMock.setSession(session)
let twoDays = 2*Time.day
await XCTAssertNoThrowAsync(try await sut.extend(topic: session.topic, by: Int64(twoDays)))
await XCTAssertNoThrowAsync(try await sessionExtendRequester.extend(topic: session.topic, by: Int64(twoDays)))
let extendedSession = storageMock.getAll().first {$0.topic == session.topic}!
XCTAssertEqual(extendedSession.expiryDate.timeIntervalSinceReferenceDate, TimeTraveler.dateByAdding(days: 2).timeIntervalSinceReferenceDate, accuracy: 1)
}

func testUpdateExpirySessionNotSettled() async {
let tomorrow = TimeTraveler.dateByAdding(days: 1)
let session = WCSession.stub(isSelfController: false, expiryDate: tomorrow, acknowledged: false)
storageMock.setSession(session)
let twoDays = 2*Time.day
await XCTAssertThrowsErrorAsync(try await sut.extend(topic: session.topic, by: Int64(twoDays)))
}

func testUpdateExpiryOnNonControllerClient() async {
let tomorrow = TimeTraveler.dateByAdding(days: 1)
let session = WCSession.stub(isSelfController: false, expiryDate: tomorrow)
storageMock.setSession(session)
let twoDays = 2*Time.day
await XCTAssertThrowsErrorAsync( try await sut.extend(topic: session.topic, by: Int64(twoDays)))
}

func testUpdateExpiryTtlTooHigh() async {
let tomorrow = TimeTraveler.dateByAdding(days: 1)
let session = WCSession.stub(isSelfController: true, expiryDate: tomorrow)
storageMock.setSession(session)
let tenDays = 10*Time.day
await XCTAssertThrowsErrorAsync( try await sut.extend(topic: session.topic, by: Int64(tenDays)))
await XCTAssertThrowsErrorAsync( try await sessionExtendRequester.extend(topic: session.topic, by: Int64(tenDays)))
}

func testUpdateExpiryTtlTooLow() async {
let dayAfterTommorow = TimeTraveler.dateByAdding(days: 2)
let session = WCSession.stub(isSelfController: true, expiryDate: dayAfterTommorow)
storageMock.setSession(session)
let oneDay = Int64(1*Time.day)
await XCTAssertThrowsErrorAsync( try await sut.extend(topic: session.topic, by: oneDay))
await XCTAssertThrowsErrorAsync( try await sessionExtendRequester.extend(topic: session.topic, by: oneDay))
}
}

0 comments on commit 6fe5114

Please sign in to comment.