Know when a transaction happened
In the previous exercise, you created a CorDapp with a sales proposal. It was noted that the following annoyances are still present:
- The seller can surreptitiously reject the proposal at any time without letting the buyer know.
- The buyer has all the time in the world to scrutinize the offer.
Would it not be good to put time limits on both? For instance:
- The proposal has an expiration date.
- The buyer can only accept before expiration.
- The seller must honor the contract if the offer is accepted before expiration.
Yes, that would be an improvement. Is it enough to add this expiration date as a field in the sales proposal? For information purposes only, sure. But how would you enforce it?
As you learned in the fundamentals module, time in Distributed Ledger Technologies (DLTs) has an unusual meaning. Recall that you have a collection of nodes with unsynchronized clocks. Which one do you consider the authoritative source of "correct time?"
The short answer is, none!
The long answer is, which entity or process are we going to trust with deciding time?
In the case of Corda, the decision made for us is to use notaries. They are already used to provide authority about consumed states. They are also used for time-stamping. Obviously, it is in the best interest of a notary operator to provide an accurate service and this principle extends to time.
How do you ask for the time from a notary?
Corda introduced the concept of time-windows, which have a beginning and an end. Or a beginning and no end, or an end but no beginning. When such a time-window is set on the transaction, the notary will be contacted and asked to sign. The notary will do so only if its current time falls within the time-window, and it will return an error if its time does not. This is something to remember if your flow involves some back and forths for data and signature collection. Specify a wide enough time-window, especially if the other nodes may be busy or flaky.
So the notary does not provide time, it signs if its time falls inside the window. A time-window is:
- Open-ended when the transaction must happen before a certain time, or the transaction must happen after a certain time.
- Close-ended when the transaction must happen after a certain time and before a certain time.
At the time of notarisation and in the future, a party looking at the historical trail of transactions will have the assurance that the transaction was notarized during the specified time-window.
- The implementation of
TimeWindowis done with 2 nullable
Instantinstances, which represent both ends of the window. There are some utility functions to facilitate their creation, such as:
- As for the
Instantclass, it too has some facilities such as:
Instant.now(), which returns current time in UTC.
Instant.now().plus(Duration.ofMinutes(10)), which is self-explanatory.
Instant.now().minus(1, ChronoUnit.DAYS), another way to modify instants.
Time-windows are an accommodation of the limitations of DLTs. They force notarisation within a range of time. When combined with states and contracts, they can be used to enforce complex time thresholds.
In the next chapter you will look at an example implementation of time windows in the project.
- Documentation on time-windows.