Skip to content

Commit

Permalink
updated the 'Conclusions' section of the document
Browse files Browse the repository at this point in the history
Signed-off-by: Alexander Sukhachev <alexander.sukhachev@dsr-corporation.com>
  • Loading branch information
alexsdsr committed Oct 13, 2023
1 parent ef1b91c commit 3cbc45b
Showing 1 changed file with 27 additions and 18 deletions.
45 changes: 27 additions & 18 deletions PleaseAck.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ There is a [list of protocols](https://github.com/search?q=repo%3Ahyperledger%2F
- [0035-report-problem](https://github.com/hyperledger/aries-rfcs/blob/097053c6e91f16d4dad18b5367cf338721423dc7/features/0035-report-problem/README.md)


## Possible options to hande the `please_ack` decorator
## Possible options to handle the `please_ack` decorator

There are, at least, three possible ways to implement support of `please_ack` decorator:

Expand Down Expand Up @@ -66,21 +66,21 @@ The common handler can be implemented, for example, as functions that are called
##### The common handler doesn't exist yet

Currently the `ACA-py` code doesn't have a common handler for all message types. Each message is processed in a message-specific handler which is implemented as a part of the protocol.
To make the `please_ack` processing a common feature for all protocols the `dispatcher.py` (or the `base_handler.py`) should be changed to add support for the common handler to process all messages before/after a message-specific handler is called. It would change the current design where each message is processed only by a single message-specific handler implemented as a part of particilar protocol. Message processing code would be scattered across several files (common handler and message-specific handler).
To make the `please_ack` processing a common feature for all protocols the `dispatcher.py` (or the `base_handler.py`) should be changed to add support for the common handler to process all messages before/after a message-specific handler is called. It would change the current design where each message is processed only by a single message-specific handler implemented as a part of particular protocol. Message processing code would be scattered across several files (common handler and message-specific handler).

##### `ack` message type

The `ack` message type depends on particular protocol being processed.
The `ack` message type depends on the particular protocol being processed.
For example, `0454-present-proof-v2` protocol includes a specific type for `ack` messages. The `V20PresAck` message type extends the common `V10Ack` type defined by notification protocol with the new field `verification_result`.
If the `please_ack` decorator is handled by some common handler it is impossible to send `ack` of specific type.


##### `OUTCOME` acknowledge is protocol-specific

It seems hard (or even impossible) to handle `please_ack` decorator with `on=['OUTCOME']` in the common handler since the handler doesn't have any information about result of message processing done by the message-specific protocol handler.
For example, if the issued credentials is not accepted by holder, message-specific handler sends a `problem_report` message. Depending on the result of processing in the message-specific handler common hanler must either send `status=OK` or send nothing. But the common handler doesn't have result of processing (unless special code is implemented for that purpose).
It seems hard (or even impossible) to handle `please_ack` decorator with `on=['OUTCOME']` in the common handler since the handler doesn't have any information about the result of message processing done by the message-specific protocol handler.
For example, if the issued credentials is not accepted by the holder, a message-specific handler sends a `problem_report` message. Depending on the result of processing in the message-specific handler, the common handler must either send `status=OK` or send nothing. But the common handler doesn't have the result of processing (unless special code is implemented for that purpose).

Assume the common handler "knows" the result produced by the message-specific handler. In that case an `ack (STATUS=OK)` message is sent by the common handler. But the `problem_report` (in case of any problems) is sent by the message-specific handler. It seems to be bad design of code. It is better when both `ack` and `problem_report` are sent from the same layer of the code.
Assume the common handler "knows" the result produced by the message-specific handler. In that case an `ack (STATUS=OK)` message is sent by the common handler. But the `problem_report` (in case of any problems) is sent by the message-specific handler. It seems to be a bad design of code. It is better when both `ack` and `problem_report` are sent from the same layer of the code.


##### There are more than one point of decision whether to send `ack` or not
Expand All @@ -91,12 +91,12 @@ For example, the `0454-present-proof-v2` protocol defines the following conditio
- the `will_confirm` field in the `request-presentation` message is set to true
- the `please_ack` decorator is included into the `presentation` message

This example shows that message-specific handler must take into account such cases in order to prevent duplication of `ack` messages. It requires protocol implementations (at least, `0454-present-proof-v2`) to be changed. It is not a good idea since it requires additional effort to change the code of handlers and, even worse, creates implicit dependencies between the common handler and the message-specific handlers in such cases.
This example shows that message-specific handlers must take into account such cases in order to prevent duplication of `ack` messages. It requires protocol implementations (at least, `0454-present-proof-v2`) to be changed. It is not a good idea since it requires additional effort to change the code of handlers and, even worse, creates implicit dependencies between the common handler and the message-specific handlers in such cases.


##### Possibility to send an `ack` when it is not allowed by the protocol

When the message is being processed only by single message-specific handler any corrupted messages can be detected.
When the message is being processed only by a single message-specific handler any corrupted messages can be detected.
On the other hand, in case when the common handler doesn't take into account the current state of the protocol being processed it becomes possible to add the `please_ack` decorator in the message that must not have the `please_ack` according to the protocol. In this case the common handler may send an `ack` message in response to some message with the `please_ack` decorator even if it is not allowed by the protocol. Then this corrupted message will be processed by the message-specific protocol.


Expand All @@ -105,29 +105,29 @@ On the other hand, in case when the common handler doesn't take into account the
It seems easier to implement the `please_ack` support in all message-specific handlers that should have it.

**Advantages:**
- it is not neccessary to change base logic of `ACA-py` code (for example, `core/dispatcher.py`).
- there is no implicit dependencies (it is not neccessary to keep in mind any logic that is executed outside the message handlers implemented in the protocol)
- it is not necessary to change the base logic of `ACA-py` code (for example, `core/dispatcher.py`).
- there is no implicit dependencies (it is not necessary to keep in mind any logic that is executed outside the message handlers implemented in the protocol)
- it is possible to add the `please_ack` support step-by-step (first protocol, second one, etc.)

**Disadvantages:**
- each protocol should implement the `please_ack` support seperately
- each protocol should implement the `please_ack` support separately
- only message handlers that implement it explicitly are able to react on the `please_ack` decorator

In fact, it seems there are not many disadvantages of this approach. None of them looks so serious. In the same time amount of the additional code to handle the `please_ack` decorator is expected to be quite small.
In fact, it seems there are not many disadvantages of this approach. None of them looks so serious. At the same time the amount of the additional code to handle the `please_ack` decorator is expected to be quite small.

### Option 3: common handler ('RECEIPT') + support in each protocol ('OUTCOME')

The idea is to consider different kinds of `please_ack` separately and process them seperately as well.
The idea is to consider different kinds of `please_ack` separately and process them separately as well.

`please_ack(on=['RECEIPT'])` is a decorator that requests "please let me know you have received this message". There should be the same behaviour in all protocols (to send an `ack` message and call the message-specific handler). It seems the code for the `please_ack(on=['RECEIPT'])` decorator processing can be implemented as a common handler outside the code of protocols. The common handler doesn't depend on message-specific handler and can be called before it.
`please_ack(on=['RECEIPT'])` is a decorator that requests "please let me know you have received this message". There should be the same behavior in all protocols (to send an `ack` message and call the message-specific handler). It seems the code for the `please_ack(on=['RECEIPT'])` decorator processing can be implemented as a common handler outside the code of protocols. The common handler doesn't depend on the message-specific handler and can be called before it.

On the other hand an `please_ack(on=['OUTCOME'])` is a decorator that requests "please let me know that the processing result is successful". Unlike the `please_ack(on=['RECEIPT'])` processing of the `please_ack(on=['OUTCOME'])` is protocol-specific:
- protocol-specific type of an `ack` message
- result (in terms of success/failure) depends on the protocol and behaviour (to send an `ack` or `problem_report`) depends on the protocol as well.
- result (in terms of success/failure) depends on the protocol and behavior (to send an `ack` or `problem_report`) depends on the protocol as well.

That means that it is a good idea to implement support for the `OUTCOME` decorator as a part of code of each protocol where it is expected.

The `RECEIPT` option is processed by the common handler. If there is only `RECEIPT` option in `please_ack` the common handler returns the `ack (status=OK)`. If both `RECEIPT` and `OUTCOME` are specified the common handler returns the `ack (status=PENDING)`.
The `RECEIPT` option is processed by the common handler. If there is only the `RECEIPT` option in `please_ack` the common handler returns the `ack (status=OK)`. If both `RECEIPT` and `OUTCOME` are specified the common handler returns the `ack (status=PENDING)`.

The `OUTCOME` is processed by the message-specific handler.

Expand All @@ -147,12 +147,21 @@ The `OUTCOME` is processed by the message-specific handler.
- Option 2 seems easy to implement, but the `please_ack` decorator is only handled when it is expected by the protocol message handlers implementation (unexpected `please_ack` will be ignored)
- Option 3 allows to answer with an `ack` message to any messages that include the `please_ack(on=['RECEIPT'])` decorator. It allows the initiator to know if the message was received by the other side or not. Although it seems like the best option it requires some changes of code design.

The final decision depends on the answer to the question "do we need to support the `please_ack` in all messages?". If yes, the option 3 is only possible. If not, the option 2 can be implemented.
The final decision depends on the answer to the question "do we need to support the `please_ack` in all messages?". If yes, option 3 is only possible. If not, option 2 can be implemented.

According to the [please_ack documentation](https://github.com/hyperledger/aries-rfcs/tree/main/features/0317-please-ack#requesting-an-ack-please_ack) we should support the `please_ack` in all messages:

> Suppose Alice likes to bid at online auctions. Normally she may submit a bid and be willing to wait for the auction to unfold organically to see the effect. But if she's bidding on a high-value item and is about to put her phone in airplane mode because her plane's ready to take off, she may want an immediate ACK that the bid was accepted.
Since the option 3, in fact, includes the option 2 it seems to be good idea to start implementation of the `please_ack` support from the option 2. Once it is done the solution can be extended with the common handler to support the `please_ack(on=['RECEIPT'])` if it is found neccessary.

The option 2, in its turn, can be implemented iteratively (first protocol, second one, etc) since there is no any dependencies between protocols.

Possible plan may look so:
1. define the list of protocols that must support the `please_ack(on=['OUTCOME'])` decorator and order them according to their priorities
2. implement the `please_ack` support for each protocol step-by-step
3. decide if the `please_ack(on=['RECEIPT'])` decorator support is required
4. if yes, to design and implement the common handler

## Open questions

Expand All @@ -166,7 +175,7 @@ There is a list of protocols above where the `please_ack` is mentioned explicitl

**Should an ACA-py agent ignore the `please_ack` decorator if it is not expected according to the protocol?**

This questions determines the possible implementation as mentioned above.
This question determines the possible implementation as mentioned above.
In case of option 2 the `please_ack` will be just ignored in all messages where it is not expected explicitly. Will it be correct?


Expand Down

0 comments on commit 3cbc45b

Please sign in to comment.