Holochain Forum

Dynamical bridging at validate_agent() of a newly instantiated DNA

Hi everyone!

I’m from the Kizuna messaging app team and we’re currently designing/implementing a P2P private communication DNA intended for only 2 agents.

With this, we are using the conductor admin calls to install a template DNA and instantiate it and request the other party to join the DNA as well. We would like to have a validate_agent function in the newly created DNA (named p2p communication DNA)

I currently thought of these two processes with only difference between them being the validate_agent function. The second diagram is the one concerned in this topic.

TLDR of the DNA Installation flow:

  1. Alice and Bob is both in the same Lobby DNA
  2. Alice clone a DNA from P2P Communication DNA template with property {alice_address: Address, bob_address: Address}
  3. validate_agent() runs which bridge-calls to a lobby DNA to call get_my_address in lobby DNA and compare it with the address found in the Property of the DNA. If it matches with either of the address, Alice can join, if not reject agent (which means it is not Alice).
  4. send a request for Bob to join the DNA
  5. Bob joins the DNA
  6. runs the validate_agent but this time for Bob.

Question
From my understanding, validate_agent runs when AgentId is committed. And since the validate_agent() has a bridge call to lobby DNA, I have to add the bridge with admin/bridge/add after the DNA is instantiated. Question is, assuming that the chain of admin calls to clone a DNA is this:

  1. admin/dna/install_from_file
  2. admin/instance/add
  3. admin/interface/add_instance
  4. admin/instance/start

At what point should I call the admin/bridge/add so that when the agent “joins” the DNA, validate_agent() will be able to properly bridge to the lobby DNA? I’m assuming that it will be after the admin/instance/add but I just wanted to make sure before we start implementing it :smiley:

P.S. I may be asking too much but if (and this is a big if) you can give any feedback on the way we are checking “if the intended agents (from one DNA) actually joined the newly created DNA and not other agents”, that would be super duper appreciated!!

Thank you so much in advance!!

Uhhh such an interesting question and flow. What I’m doing right now in these kinds of scenarios is actually just using the same agent id in all cloned dnas. This simplifies a lot the agent management, and we don’t lose any security there.

In the future, I think that this “relating two keys together” will be a job for deep key. I don’t know the specs or full functionality of that though, so for now I’ll stick to the same agent address in multiple dnas. Is there some reason why you can’t do that here?

Hi @guillemcordoba!! As always, thank you for spending time in answering questions :grin:

Actually, if that is possible, that would be what we want to do. I checked the social triangulation zome (I assumed that this also follow the pattern you mentioned) to see how it was being done and I just want to clarify a few things as to how agents are being validated in this zome.

So in this particular code block in validate_agent,

            let agent_address = validation_data.package.chain_header.provenances()[0].source();

            match members::is_valid_member(&agent_address)? {
                true => Ok(()),
                false => Err(format!("Validation Error: Agent {} is not valid since it does not comply with social triangulation conditions", agent_address))
            }

in the members:is_valid_member(), you are comparing the agent address you get from the provenance.source() to the address included in the “initial_members” in DNA property. But isn’t it that the agent address you get from the provenance.source() is the agent address of the source chain of this newly created DNA? I feel like I’m missing something important here or I am remarkably wrong since I can’t seem to figure out;

  1. If you are comparing the agent address obtained from the provenance.source() to the address found in the property DNA, how can you set the agent addresses in the property of DNA when the DNA has not yet been instantiated (considering that in social triangulation, the agent address you get from the provenance.source() doesn’t exist yet at the time you are instantiating the new DNA?) and therefore the agent has no agent address yet?

  2. I’m thinking if we could use the Social Triangulation in our case as well by basically having Alice and Bob’s agent_addresses in the initial_members. But then which agent address should we include in the DNA property considering that Alice and Bob only have their agent address from the lobby DNA? I’m assuming that if we have the agent address of Alice and Bob from the lobby DNA, the validate_agent() function in social triangulation will fail since the agent_address obtained from the provenance.source() will be the agent_address in the newly created DNA (in our case the private communication DNA) and it will be compared to the agent_address found in “initial_members” of DNA property which is the agent address from the lobby DNA. I’m assuming that every DNA that the conductor will spawn will create a different agent_address per DNA (since 1 source chain per DNA) or is it that there will be different source chain per DNA but then the agent address will be the same?

I tried to clone a new DNA and call a function that returns the agent address from the newly cloned DNA and compare it with the agent address from the other DNA (lobby DNA) and found out that they were the same!

I mistakenly thought that every DNA will have a different agent address but it seems like this isn’t the case. The case I guess is that there will be different source chain per DNA in the same conductor but then the agent_address of each of those DNA will be the same :smiley: This is amazing! So my questions above is already answered. Thank you.

Just one last question @guillemcordoba. We are thinking of using the social triangulation in our private communication DNA. We only want up to two (Alice who craeted the DNA and Bob who Alice wants to talk to) participants (which will be included in the “initial_memebers”). Now, is there a possible concern that the vouching system will be misused and Alice or Bob will invite others to join the Chat? (e.g. if Alice and Bob’s conductor gets hacked) Or can this be solved by having the "necessary_vouches" count to 3 so that there is no way for any other agent than Alice and Bob to join the private comm DNA since there will never be 3 vouches?

P.S. I feel like this topic is already out of scope of the original topic so please feel free to fork this topic to another thread if necessary hehe

Hum so yes, in the add instance code you can specify which agent you want to be bounded to the dna. If you’re using my cloneDna helper function, it actually needs the agentId to be passed in. You can get the agent list with the admin interface of the conductor also.

About the social triangulation, I wouldn’t recommend it. Both mechanisms are fundamentally different, and we could get the social triangulation to work in this case but then we may need to develop some checks also, and block some calls. Also I have to refactor the social triangulation zome into two, so moving on the development may no longer fit your use case.

I think this functionality is so small that is much better to develop an “allowed_members” zome, that needs the property “allowed_members” and only checks the dna property when validating the agent. This seems to be perfect for another reusable zome for the open-dev group :D?

Hehehe I like the idea you are proposing!! @guillemcordoba
Actually, an “allowed_members” zome seem perfect for our use case and yes, it would be lovely if others would be able to use it as well! I think it won’t take too much time so I’ll work on it right away! :smiley:

1 Like