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

Is there a known issue around ContractSigned events for multi-clause contracts not firing? #301

Closed
jphillips-bp3 opened this issue Feb 28, 2019 · 9 comments

Comments

@jphillips-bp3
Copy link

OK so this might be my code (and am still digging), but I am seeing something odd. I have a contract that is made up of two clauses. Each clause has its own lifecycle that starts with initialised then onto contract signed. Once both are in the contract signed state, they are then able to be executed and do their thing.

Both clauses implement the method signature of: clause contractSigned(request : ContractSigned) : Response

When the contract is signed, both of the clauses are initialised OK. However, only one clause ever has its contract signed method called (always the same clause), despite the contract Timeline showing the init and contract signed requests made for both clauses (and with no errors). So the clause in question is always stuck in the initialised state. If I create a contract with just one of the clauses (either one), then the lifecycle works perfectly.

I also tried sending a contract signed request as a REST call to the clause and this worked and moved the state on, so maybe the engine is not passing the contract signed events on correctly?

So my question is, is there a known issue with multiple clauses not being able to receive contract signed requests?

@jphillips-bp3
Copy link
Author

OK so an update, I have run the test again by creating a new contract with both clauses added and this time the clause that was moving onto the contract signed state previously is no longer doing so, but the other is. So my claim that it is the same clause each time is not the case, it appears to be random which one actually gets/processes the contract signed event.

I also checked the Timeline and can see that both have been sent both the init and contract signed requests.

@jeromesimeon
Copy link
Member

At the moment, the Cicero engine triggers the first clause which matches the given request. We've had recent discussions on the Ergo call about this (see accordproject/ergo#550).

For the time being, you might want to merge the two clauses into one if possible for your scenario.

Any examples and requirements on triggering multiple clauses for the same event would be very useful since we haven't encountered many such scenarios yet.

@jphillips-bp3
Copy link
Author

OK that probably explains it. So the reason for having two clauses is because the contract has two clauses, separated by static text in between.

At the top of the contract is the SOW definition that outlines the parties and the contract affective dates etc. This has been implemented as a clause because I need to request that information which is then used by the second clause (see below) by passing in the SOW parameters returned in the response from this clause.

Then at the bottom of the contract there is the clause that performs a calculation, and amongst the information passed into its request, it also takes the party information returned by the clause above. The orchestration between the clause service calls is all handled by Node-RED.

In between both these clauses there will be static text, therefore we could not combine the two clauses into one.

We have (as you are aware) worked on other use cases that used the same pattern for the same reasons, but this worked because the lifecycle management was only implemented on one of the clauses, so this problem was never encountered.

If this explanation does not make sense then happy to have a call to demonstrate.

@dselman
Copy link
Contributor

dselman commented Mar 5, 2019

This makes sense to me. What do you think the order of invocation of the two clauses should be?

@jphillips-bp3
Copy link
Author

This makes sense to me. What do you think the order of invocation of the two clauses should be?

@dselman Are you talking in terms of executing the clause or the order in which the contract signed events should be dispatched to each clause in the contract?

@dselman
Copy link
Contributor

dselman commented Mar 5, 2019

This makes sense to me. What do you think the order of invocation of the two clauses should be?

@dselman Are you talking in terms of executing the clause or the order in which the contract signed events should be dispatched to each clause in the contract?

The latter: we need deterministic execution, so if we have N clauses that all want to process the same incoming transaction we need to somehow order them, and because each could perform state updates, it will be important for the programmer to understand this "conflict resolution". Thoughts?

@jphillips-bp3
Copy link
Author

OK so in my specific case it does not matter which order, because each clause is transitioning from an initialised state to a contract signed state. But I understand your point, so somehow we need to specify an order. Maybe this could be implemented as an annotation much like in Java, for example:

@dispatch(order = n)
clause contractSigned(request : ContractSigned) : Response {
...
}

Clauses with the same order or those that do not specify one are then the mercy of the dispatcher as to the order in which they are called.

The other issue is how we make this process atomic, i.e. if one clause successfully transitions state but another fails then the contract is inconsistent. This would need a way of reverting back to a last known state for each clause in the contract. This all starts to get quite complex!

@otawakkil
Copy link

Another way is to consider a sequence clause (like an atomic flow of execution), that will enforce the order of invocations and determine actions on failure.
Can a clause invoke another one ?

@mttrbrts
Copy link
Member

Closing in favour of accordproject/ergo#550

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

No branches or pull requests

5 participants