Multisig Revamp for StructuredData/AppendableData

I think I misread sorry

To allow someone to read you just give the encryption key if it was encrypted. Others can be categorised as modification operation. I don’t know how useful is it to subdivide it further into write/modify/append etc. What you are suggesting can easily be achieved giving 100% ownership to everyone you want to share a particular facet with, so i am not sure i would call it imprecise (rather there is too much precision and that can be a problem with complexity). OTOH if we implement what you suggest then the opposite use-case of consensus-involved activity cannot be implemented which is equally important to support.

I had misread the use of weights. You must have replied before I deleted that post. So sorry again for my misreading.

Hey np at all man :smiley: - even if you misread it could also mean my explanation wasn’t precise, so i am all for anything i can write more to make things (from my perspective of things) clearer (unless i am sleepy, which i am now)

Assuming someone only has half the weight to make a change, requiring others to also confirm the change, presumably a mutation error should not be returned in those circumstances? Will this message be different in the future and will other owners be notified in some way to confirm the change?

This may be going beyond what is being described here, but it would be good to know how these use cases will be handled.

1 Like

I can say two things on this right now:

  1. There is no push model yet, so vaults (at-least for now) don’t send notifications.

  2. Illegal modification attempt will generate a mutation error right now. The person with limited weight will have to circulate the ShareableData to enough ppl to get to 100%. This has to be done out-of-band. So say you make changes and know that if i agree too, it will be accepted (will reach >= 100%). You can serialise it and send it to me using the SAFE Email app we released. When i get it, deserialise it, read the changes and agree to the changes, i will add my signature too and then POST it. It will now be accepted by vaults.


Thanks - it is great to hear that 2 will be (is already?) possible, even without push. I suspect a nice client could wrap this process, even before push is available.

Yes, the code in safe_core should already be there. All there needs to be done is expose it via FFI (API interface) to Launcher - whenever it demands. Infact most of this interface should already be there too, let’s see:

  1. Create an SD.

  2. Serialise it.

  3. Use the SAFE-email-app (just as an e.g.) to send it to the other you think necessary.

  4. They deserialise this to get back the SD.

  5. Check they agree to the changes. Other API’s will be exposed here if this discussion is fruitful and new fields as suggested in this thread are accepted in some form - then expose some more API’s to verify the changes in those fields too, not just data. Probably person shooting the mail should hint what’s changed so ppl receiving know what to look for. If they don’t trust the guy then they can always get the latest from vaults to check the diff.

  6. Add their signature (FFI API currently missing for this - but it’s trivial as you can guess and will put in soon, when Launcher/frontend requires it).

  7. Repeat 2 - 6 if more signatures/permissions are required.

  8. POST the final SD - hopefully should be accepted by vaults.

1 Like

I’m broadly in favour of this. A couple of thoughts though:

  1. I’ve never been a fan of the prev_owners field. I think the only place where that’s needed is when a mutation is being validated, and that check is done by the data holders who already hold the previous version and hence already have the set of previous owners’ keys. This is probably a separate topic though.

  2. By requiring >= 100% weight to modify data, we’re requiring at least one signature. This is probably fine - just pointing it out.

All the goat sacrifices i made seem to have worked :smiley: - your approval is a rare thing !

It’s during transfer/change of ownership i think. So if you want to transfer ownership to me your SD Post would look like:

current_owners: My-Onwer-Struct, // Or your's too if you wanted a shared ownership instead of just transferring.
previous_owners: Your-Onwer-Struct,

So in this case vaults verifiy the signature against prev_owners (instead of usual current_owners). When they store data at vaults though they blank out the pre_owners so that field in current implementation is always blank if you look into Valuts (at-least that is my knowledge of it).

What do you propose here (which should be able to do all that the current one does) ? A separate API for ownership transfer ? Difference in representation in stored vs serialised version ? Maybe a Type/API snippet might be helpful if you can provide one.

Just curious : Why the probably ? Are we missing something ?

Just to be sure - you agree to both parts right ? (Part-0 and 1)

Simply removing previous_owners from SD is all I’m recommending. I believe SD could do with a complete overhaul, so I’m not going to spend time here detailing what I think it should be - that’s a separate RFC in itself! :slight_smile: But if you imagine that the only change to SD’s API is that previous_owner_keys is removed from new().

To transfer ownership, Clients would continue to behave as they do now - construct a new SD from the existing one’s fields, swapping out the public keys for the new ones. They add signatures using their old keys.

The Vaults handling the request already have the existing version stored - they’re using this existing version to call validate_self_against_successor(). There’s no need for other to provide the previous set of public keys there - we even go as far as checking that they’re the same at the moment, even though we go on to validate the signatures (which would fail if they weren’t the right keys)!

Yes - I agree to both parts!

Good point - that makes me think that non-ownership-transferring POST updates could even blank out the current_owners. So if current_owners is blank, vaults continue to use the stored current_owners. If it has something then swap it (transfer of ownership kind of stuff). That would basically make majority of the POSTs not carry that field at all - some (depending on number of owners) reduction in B/W ? Will that have issues ?

Not that I can see, but I’m usually wrong :smiley:

Ah @Fraser just realised one thing: dropping previous_owners and the rest would invalidate Part - 1 which you had agreed to as well.

Ah - right - good point. I guess I’d opt for dropping the previous_owners (reducing message size and saving space on disk) at the expense of the processing inefficiencies you pointed out. I guess we could always change to ordering the Vec of keys and Vec of signatures to match, so the only waste would be if we provide less signatures than keys we’d still be doing O(n) signature validations where n is the number of keys rather than the number of signatures.

1 Like

Thread Summary:

We mostly agree to this on the first look so will keep it ready for implementation when other higher priority tasks get flushed out. Also when 100% weight can only be reached by more than one signature, we will need to come up with a good solution to get it. Currently it is only possible by circulating the data around and the last owner doing the post after adding signature. We will look at if anything better can be done here such as maybe getting Vaults to accumulate signatures for POST operations from different clients until the required weight is reached and then handling the request. We might need to check how certain other systems do multisig as well to see how we compare. The adding of granularity does make it powerful but need to ensure it does not come at the cost of complexity and devs understand it easily.


Weighted signatures with a threshold is a great step in the right direction, and the proposed implementation seems solid.

However, I think there is much to be gained by looking at bitcoin script, particularly BIP-16 Pay to Script Hash.

Determining ownership

Considered at the highest level, ownership depends on an ownership_test function:

has_ownership = ownership_test(owners, signatures)
if (has_ownership) { modify }

Initially, ownership_test checked more than half of owners signed:

ownership_test(owners, signatures) {
    valid_signatures = find_valid_signatures(owners, signatures)
    return len(valid_signatures) > 0.5 * len(owners)

In this thread, it has been proposed to check if a weight threshold has been exceeded:

ownership_test(owners, signatures, threshold_weight) {
    valid_signatures = find_valid_signatures(owners, signatures)
    signed_weight = combined_weight(valid_signatures)
    return signed_weight > threshold_weight

I believe more complex ownership_test functions will be required in the future. I base this on the increasing complexity of bitcoin’s scripting language and popularity of multisig and P2SH transactions. Ownership testing in structured data may take the form ownership_test(owners, signatures, script) so the evaluation of ownership is independent of the SD itself. ie

ownership_test(owners, signatures, script) {
    return script(owners, signatures)

This is not without risk, and it increases complexity. It’s likely this is a step too far too soon, but I want to put it out there for consideration.

The safe network is also potentially looking to having cpu available as a network resource; this may tie in with that.