This feels like another one of those common patterns that most apps will want in some form or another, in order to provide fields like date_created and date_modified. It would be good to get traction on the development of this functionality to avoid many of us reinventing the wheel!
So I want to copy some things from this github issue and outline the requirements we can see emerging for this in different types of economic networks. Primarily I’m interested in knowing:
Have others already created any of this functionality?
Are there other types of timestamping behaviour that I’m missing?
I suspect it is best developed by a “mixin zome” that can be easily injected alongside other zomes in a DNA in order to provide the timestamping functionality as a pluggable service.
(aside:) I have also been looking for a worthwhile “mixin zome” candidate for development that has broad utility for potential HoloREA integrators. The “anchor pattern” that @artbrock told me was being used internally in some hApps was another one (we haven’t done indexes yet), but @philipbeadle wasn’t sure where to find that code (any help?) The other worthwhile avenue to explore in proofing that pattern is to get others using HoloREA zomes as mixins in their own apps. Open to all input on what to do next, but timestamping might be it.
I also think this behavior will need to be configurable as resilience / trust levels depend on the network. There are a few options that could be taken:
Trusted notary: good for trusted networks that are always available. In this case there would be a trusted autonomous agent listening on the DHT which registers timestamps when it receives new records. All other nodes use these timestamps for date_created and date_modified.
Quorum time: good for untrusted networks with higher numbers of nodes. Configuration would be the number of nodes required to witness the record- each would write a timestamp, these timestamps would be averaged to get date_created & date_modified. Configured node count is also the minimum number of nodes that need to be online for the network to operate… if fewer nodes are online, the delayed observations will throw times out.
Countersigned time: good for smaller untrusted networks. Basically like quorum time except that we only require one other agent to be online to witness a timestamp. Also good if you’re doing offline transactions with QR codes or similar. Weakness is that partners might be able to collude by syncing clocks.
Trusted time: basically just taking people’s word for it, assign date_created from whatever creation timestamp is provided in the request.
Open questions:
The 4 flavours of timestamping outlined above might be best developed as entirely separate zomes. There is no reason for all functionality to be packaged together into 1 zome with configuration options, as this would simply make the zome WASM bundle bloated with unexecuted code. But- does the timestamping method used in a DNA potentially need to be changed dynamically without every user having to update the app? Like, if you lost users and were under the threshold for quorum time, you might have to temporarily switch to countersigned time. If so, the configurable option would be needed. It’s also possible that a configurable version could be provided that simply composes methods from the other mixin zomes and wraps them in some config layer.
Suggestions & opinions:
Zome API traits can be used to synchronise the public APIs of all mixin zomes so that they are compatible.
The default implementations of the timestamping zomes might as well include a public API for querying record timestamps by address. Implementors who do not want a public API exposed can import standalone entry & link type definitions into their projects without importing the API function handlers, as per holo-rea/#80.
Using the same entry & link type names for every zome is the only requirement necessary to ensure that the same helper library can be used by implementors regardless of the actual zome used. In other words, this can give us polymorphism in the behaviour of timestamp links & entries.
The helper library API should be a pretty simple thing, something like record_created_timestamp(Address) and query_created_timestamp(Address) et al. This provides simple read / write access to timestamping info from within third-party zomes in the same DNA; where the query_ logic and the means of calling record_ depend on the “timestamping flavour” being provided. In practise, implementors would call query_ when returning record timestamps to consumers of their zome API.
It’s likely that other stuff will be involved, I expect a signalling API standard could factor in. record_created_timestamp(Address) may not be an exposed method; rather, the mixin zomes might expect certain events to be broadcast from the third-party zome which will trigger them to process writing the timestamps.
Wow this is a great idea @pospi
I haven’t found anything like this around but I’ve definitely run into the need a few times.
I’d love to help out developing these zomes.
I really like how you’ve broken down the different types of time and I agree it would be ideal to be able to switch out the type depending on the state of the network.
I don’t imagine these would be very large zomes though so if you had to include a few in your hApp it shouldn’t add too much bloat.
This would be a great thing to do together because the more eyes we have on it the better chance it’s done right.
Definitely! I wonder if @philipbeadle@pauldaoust@dhtnetwork or other hApps team members would like to start an official process for kicking off community efforts like these?
I suppose I’m suggesting front-loading something like what happened with the file upload zome that @ryan started. It would be nice to have an official process that directs people towards collaborating on a unit of functionality in the open, with visibility to the rest of the ecosystem.
I would suggest the process begins by agreeing on the necessity of the work and then creating a github repo under the holochain org with collaborator access for anyone who is interested in assisting. In future we might use a set of template issues or seed the repository with a boilerplate project. Or we could implement these kinds of scaffolding within hc generate.
There might also be particular stewardship roles to define, with associated responsibilities. For example the initiator of a project (in this case I guess it me) might be responsible for communicating project updates back to the community forum.
Would anyone be interested in creating a first-pass process to enact, which we could follow with a project post-mortem to iterate on?
@pospi I agree with the others that this could be a good demonstration case for developing Holochain’s code reuse / modularity / interoperability story. As well as for creating community practices around it, which is probably just as important (if not more important).
Thoughts, thoughts… so much food for thought here.
I love the options you’ve presented so far, along with information about the different use cases and different network conditions that each one is appropriate for. Other options:
Centralised signed timestamping service — would require the cooperation of the UI. The public key of the timestamping service could be in the config block of the DNA bundle for in-app validation.
Built-in quorum time — FWIU in the future the first n validation signatures on an entry (and their timestamps) will be accessible to the HDK. I think they’re calling it ‘network time’.
What do you see as the product of the record_created_timestamp() function? It sounds like you’re saying that it would create an entry with a timestamp and all the supporting information needed to verify the timestamp. And given that its only dependency is the address of an existing (or perhaps not-yet-existing) entry, it doesn’t need to know about the structure of the information that it’s timestamping. That’s nice; reduces any tight two-way coupling.
When you say ‘third party’, you mean ‘consumer of the timestamp lib’, right?
Could you tell me more about this?
Using the same entry & link type names for every zome is the only requirement necessary to ensure that the same helper library can be used by implementors regardless of the actual zome used. In other words, this can give us polymorphism in the behaviour of timestamp links & entries.
Built-in quorum time sounds like the optimal way to approach an MVP of this. Any details of how to access that information much appreciated
record_created_timestamp()
Exactly as you say.
When you say ‘third party’, you mean ‘consumer of the timestamp lib’, right?
Right.
Entry behaviour polymorphism
It’s pretty straightforward I guess. It’d be nice to have only 1 helper library that a ‘consumer of the timestamp lib’ has to think about. We can do that if every timestamp zome implementation uses the same entry & link type names; because all we’re doing in record_created_timestamp() is writing such entries. The logic for how and why those entries are written is up to the ‘consumer of the timestamp lib’.
If the definitions match, other zomes don’t have to care about exactly which timestamping zome is used.
Update on entry polymorphism: it looks like the HC core devs have created a stable foundation for this kind of “utility zome” logic in their “anchors” library:
You can imagine implementing other methods in different utility libraries which could manage anchors entries in different ways.
(unrelated: is there an index of efforts like these somewhere? Visibility of what’s being developed in the arena of Holochain libraries and mixin zomes is lacking…)
The de-facto index is “look in Holochain · GitHub for official core libs or blessed community libs”. Not a satisfying answer, I know… Another spot we intend to make this visible is in the #technical:libraries category here. Maybe we need to create more visibility around it