Quick questions on data types for usecase

So let’s say I want to store a list of xornames on the network, but I want the ability to add new xornames one at a time to this list.

I assume I should use registers for this as they take exactly the size of a xorname, so it would be efficient, although it would cost each time one is added. Another benefit is it would store the entire version history.

Is there a way to set owners so that only specified owners can append new xornames?

Can these ‘owners’ add new owners?

Is it possible so everyone can append new xornames?

I assume it’s not possible to prevent duplicate xornames from being added, so I guess it would be up to the app to ignore duplicate xornames that it finds in the list.

Could it be possible for the owner to be a smart contract on Arbitrum so more complex processing can be done before a xorname is appended?

5 Likes

Is the list of xornames just for one user (i.e. the person with the keys) or is this a publicly readable list? Or a higher level question, how will this list be used?

The usecase would be a list of xornames for an image scrolling app.

It would allow submission of xornames to the list by any user and the app would just detect if the xorname is an image and then display it. It would also detect if the image is a duplicate and just not re-show it.

The separate ability to only allow white-listed owners to submit to a certain list would allow personal collections - i.e approved submitters only.

2 Likes

Cool, I get it. I ran into the same thing trying to figure out how to share a common data space with a potentially malicious user base, in my case a search index. Where my thought experiment ended up is that users can upload whatever they want, index it themselves, and share their index (and links to other indexes) with others. Then instead of fighting the ‘single shared resource problem’, you just need to filter out the junk. Which, you would need to do anyway.

It also allows your users to pick which indexes they want to view. Basicially, instead of an “approved submitters” mechanism, it is a “view what is relevant to you” system. The end user gets the same thing, just from the opposite direction.

For duplication, as the user’s index is built by recursing through their list of indexes, the first xorname found is kept and any other references are dropped, with the theory being that the closer an index is to you, the more trustworthy/relevant it must be to you.

Hopefully I explained the concept well enough here. You can check out my video about Colony where I go into a detailed explanation of how the pod search/index operates. If you leverage the same concept, the data you’re putting in your application could be directly linked with Colony search and you would also be able to store metadata for each image.

Sorry for the cheerleading here, but I feel very strongly that data uploaded to the network should be interoperable between apps and searchable :slight_smile:

What are your thoughts?

2 Likes

I totally agree that all data should be interoperable if possible.

I think I’ll leave it for now and wait to see some other implementations and examples as they come out :+1:

1 Like

Just a few general points:

  • you can share the private key for append only types, as you can’t overwrite what has already been persisted.
  • you can use signatures to validate who appended the data, discarding unknown data at read time.
  • Sequences can use derived keys, based on the root key. This provides the scaffolding for where future items will be.

These 3 things should take you a long way towards your goal.

5 Likes

Careful, a malicious user can set the counter of e.g. a Pointer or Scratchpad to its MAX value to effectively stop it from being updated any further! This affects higher-level types too - e.g. a Register uses a Pointer to point to its head. A malicious actor could set the pointer target to whatever they want and set the version counter to u32::MAX making their register value the final one ad infinitum.

3 Likes

isn’t the pointer there just a speedup? you can always traverse the graph entries and get to the right value even if pointers are broken (but slower ofc) … that’s how I interpreted it … didn’t have a look at any implementation details there

1 Like

As I understand it, you can derive an endless list of derived keys, so you wouldn’t need to use the pointers in this context. The order would just be implied from the first data item.

Maybe there is a cleaner way that could be designed to prevent pointer abuse, but this approach sounds like its avoidable.

Note that I haven’t experimented with this in practice yet, but I will be looking at it for IMIM comments threads, etc.

1 Like

The Register stores a pointer to the head of the underlying graph. As GraphEntrys are immutable, the graph is only traversable top-down - older entries simply don’t know who their parents are. The head could be pointed at whatever graph the malicious user wants - completely rewriting history if they’d like.

Anyway, Register was just an example to raise awareness that even the two mutable low-level data types Pointer and Scratchpad can be made immutable.

3 Likes

and important to consider and consider that in higher level data types as you say

2 Likes

And as a reminder that history CAN be rewritten, something to keep in mind as well.

1 Like

This is correct, you don’t need the pointer and in fact this is the default behaviour in dweb at the moment since Pointers were not updating (still the case AFAIK).

The speed issue is a problem though because it takes about a minute to determine that you’ve reached the head, on top of the time it to traverse the tree. (You can always find the root because that’s based on the Register address, as is the Pointer.)

In fact, dweb uses dweb::history, but the underlying implementation is very similar to Registers.

3 Likes

Hey @WeeBert - does this not remind you of John Greig?

As you kind of wrote a nice post about me yesterday, I’m not going to search the web to find out what to write about you and your dodgy fitba team…..

I do believe Mr Greig kicked yer team up and down the park…..which I can totally understand as you would drive anyone to do that

Thanks for correcting my comment above. I genuinely thought Register traverses the graph from the head down. I stand corrected!

3 Likes

Simply the best.

I stiill remember the Celtic fans singing
" A million housewives every day,
open a tin of beans and say
“John Greigs a bastard”
As true then as now

The nodes could enforce monotonic increment, and that problem would be smaller, but not eliminated (it would take a while to loop through and update to MAX).

It could also be a useful feature, if we want to edit for a while, then seal it. A mutable-into-immutable “chunk” with chosen* address.
That seems powerful to me.

*E.g. by placing it in a hiearchy using key derivation.


Depending on your requirements, I’d say a much faster implementation could be made using Scratchpad. Same goes for Register. I haven’t gone into that yet though.

2 Likes

It appears we still have problems with mutable types. I’ll be looking into Scratchpads this week, but I checked a Pointer created by riddim today which has not updated in over a day, older ones have been stuck for months.

These types work fine locally but so far not on mainnet. It was the same with the old Registers implementation going back a year now.

So for now we can’t use Pointer and have to traverse the graph for Register/History, which is very slow because checking for the end takes around a minute.

I haven’t tried Scratchpads on mainnet yet so maybe they work better than Pointers, but I’d have thought the implementation is similar. Again they work fine locally.

2 Likes

Yes, it is useful. I don’t think the existing behavior should change. I use this approach in my own project to:

a) make sure a certain value is final, just as you described it, and to
b) retire certain values by setting a predefined tombstone value and then finalizing it

Retiring is the closest thing we have to deleting content on Autonomi. I use it with Scratchpads that are no longer needed but may contain sensitive content. When reading any scratchpad from the network, I return an Error if it fulfills all the conditions to be considered Retired.

4 Likes