Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Approve engine refactor #260

Merged
merged 13 commits into from
Jun 8, 2022
Merged

Approve engine refactor #260

merged 13 commits into from
Jun 8, 2022

Conversation

flypaper0
Copy link
Contributor

What changed

  • ApproveEngine created
  • NetworkInteractor callbacks replaced with publishers
  • Error handling for ApproveEngine

ApproveEngine works with events:

- proposeResponse(topic: String, proposal: SessionProposal)
- sessionProposal(Session.Proposal)
- sessionRejected

@flypaper0 flypaper0 changed the base branch from main to develop June 3, 2022 13:58
@chadyj
Copy link
Contributor

chadyj commented Jun 3, 2022

Does this have a related issue?

@Mike117687
Copy link

merge-these-changes

@@ -157,8 +157,8 @@ extension Sign {
/// - Parameters:
/// - proposal: Session Proposal received from peer client in a WalletConnect delegate.
/// - reason: Reason why the session proposal was rejected. Conforms to CAIP25.
public func reject(proposal: Session.Proposal, reason: RejectionReason) {
client.reject(proposal: proposal, reason: reason)
public func reject(proposal: Session.Proposal, reason: RejectionReason) throws {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a note: we are currently approving by proposalId(aka: proposer.publicKey) so maybe we should also rejecting by proposalId instead of requiring the whole Proposal object.

Comment on lines 160 to 166
guard let (sessionTopic, proposal) = pairingEngine.approveProposal(proposerPubKey: proposalId, validating: namespaces) else {return}
let (sessionTopic, proposal) = try approveEngine.approveProposal(proposerPubKey: proposalId, validating: namespaces)
try sessionEngine.settle(topic: sessionTopic, proposal: proposal, namespaces: namespaces)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of the motivations to have an approveEngine for me was to not pass (sessionTopic, proposal) between engines in the client.
a think the sessionEngine.settle method should also go to approveEngine
to me proposal response and settle request are like two pieces of an approval so make sense to perform them in one object.

try sessionEngine.settle(topic: sessionTopic, proposal: proposal, namespaces: namespaces)
}

/// For the responder to reject a session proposal.
/// - Parameters:
/// - proposal: Session Proposal received from peer client in a WalletConnect delegate.
/// - reason: Reason why the session proposal was rejected. Conforms to CAIP25.
public func reject(proposal: Session.Proposal, reason: RejectionReason) {
pairingEngine.reject(proposal: proposal.proposal, reason: reason.internalRepresentation())
public func reject(proposal: Session.Proposal, reason: RejectionReason) throws {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we also make it async method?
it could throw on networking errors then.

Comment on lines 299 to 309
approveEngine.approvePublisher.sink { [unowned self] response in
switch response {
case .proposeResponse(let topic, let proposal):
self.sessionEngine.settlingProposal = proposal
self.sessionEngine.setSubscription(topic: topic)
case .sessionProposal(let proposal):
self.delegate?.didReceive(sessionProposal: proposal)
case .sessionRejected(proposal: let proposal, reason: let reason):
self.delegate?.didReject(proposal: proposal, reason: reason.publicRepresentation())
}
}.store(in: &publishers)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I do not necessarily find enums publisher cleaner than callbacks 🤔
I think some people would also say that it is less Open–closed principle conformant

@@ -157,16 +162,16 @@ public final class SignClient {
namespaces: [String: SessionNamespace]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be also nice if approve is async

@flypaper0
Copy link
Contributor Author

Does this have a related issue?

Before we doesn't handle some of approve errors which could occur. Now they handled and respond to another participant
Also I continue work, started by @llbartekll, of splitting client to Engines, to esolate responsabilities.

@flypaper0 flypaper0 requested a review from llbartekll June 7, 2022 12:40
Comment on lines 8 to 12
typealias SessionRequestCallback = (Request) -> Void
typealias SessionResponseCallback = (Response) -> Void
typealias SessionRejectedCallback = (String, SessionType.Reason) -> Void
typealias SessionDeleteCallback = (String, SessionType.Reason) -> Void
typealias EventReceivedCallback = (String, Session.Event, Blockchain?) -> Void

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of spreading too many typealiases through the code. They can make it harder to understand the code when used excessively.

// TODO: Delete pairing if inactive
}

func settle(topic: String, proposal: SessionProposal, namespaces: [String: SessionNamespace]) throws {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if something can make the settlement fail after the proposal is responded with a success, and if this can cause any problems. Something that we can think about in the future.


// MARK: SessionSettleRequest

func handleSessionSettleRequest(payload: WCRequestSubscriptionPayload, settleParams: SessionType.SettleParams) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We moved ApproveEngine to /Controller dir but I see that you moved non-controller method handleSessionSettleRequest to ApproveEngine as well.

maybe we should later have /Non-Controller/SettleEngine and let it handle Session settle request?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, Created TODO for that

@flypaper0 flypaper0 merged commit b3db843 into develop Jun 8, 2022
@flypaper0 flypaper0 deleted the approve-engine-refactor branch June 8, 2022 10:58
@flypaper0 flypaper0 mentioned this pull request Jun 9, 2022
flypaper0 added a commit that referenced this pull request Jun 9, 2022
* Cleanup Service + SequenceStore refactor (#241)

* Cleanup service

* Clean sessionToPairingTopic

* SequenceStore refactor

* Rename KeyValueStore -> CodableStore

* Deliver an invite (#254)

* Add Chat target, split packages

* savepoint

* Update networking interactor  to decode unencrypted messages

* pass on invite test

* restructure chat's project folder

* Add engine storages

* extract storage domain identifiers

* update logging

* fix schemas

* Update style

* Add publishers to Chat

* rename kv store to codable strore

* UI tests (#242)

* Pairing testcase

* Ping testcase

* ApproveSessionExistingPairing test case

* Unused extensions deleted

* Renamed to RegressionTests

* UITests step on CI

* CleanLaunch instead of deleting app

* Fix test on Real device

* Launch App fix

* Approve engine refactor (#260)

* Approve method moved ApproveEngine

* Reject and wcSessionSubscriptions for ApproveEngine

* Private methods moved in extension

* ApproveEngine errors handlers

* Try on reject

* ApproveEngine moved to callbacks

* Session Settle moved to approve Engine

* onProposeResponse subscription removed

* Reject by proposalId

* Settle moved to approve

* ApproveEngine moved to Controller folder

* typealias removed

* TODO for SettleEngine

* #256 JSON-RPC Package (& Commons) (#261)

* Add Chat target, split packages

* savepoint

* restructure chat's project folder

* fix schemas

* Add JSONRPC and Commons packages

* Moved AnyCodable to Commons

* Fixed test import

* Reintroduces either type

* Add request and response types

* Add simple response decode tests

* Add response ID parsing tests

* Fixed tests typo

* Improved response round trip coding test

* Error response decoding tests

* Invalid response decode tests

* Enabled code coverage for library

* Response decoding tests for structured result values

* Add flexible initializers with tests

* Add descriptions to errors thrown in response decoding

* Renamed response internalResult to outcome

* Basic RPC request decoding tests

* Tests for request empty cases and corner cases

* Add flexible inits for requests

* Add identifier generation inits

* Joined request notification extensions

* Renamed files

* Implemented default JSONRPC error cases

* Declared RPCRequestConvertible as public

* Remove rebase artifacts

* Added debug description to request param primitives error

Co-authored-by: Bartosz Rozwarski <bartus000@gmail.com>
Co-authored-by: André Vants <MisterVants@users.noreply.github.com>
@flypaper0 flypaper0 linked an issue Jun 16, 2022 that may be closed by this pull request
@flypaper0 flypaper0 mentioned this pull request Jul 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Refactor approval flow in engines
5 participants