How to force a particular DNA to be present in a bridge configuration?

I haven’t seen this done yet, and can see many applications where it may be necessary (eg. reliable group permissions checks against actions in related DNAs).

I expect the logic to be something like:

  • DNA requiring specific network bridge implements some configuration (perhaps simply zome attributes) to specify the allowable DNA hash for the bridge.
  • Bridge genesis callback is coded to check the hash of the bridged network against the configured ID and abort if there is a mismatch.

This should enable use-cases like “I have this economic network but only resource types defined within this other external specification DNA should be allowable within the network”. Without the above restrictions, users could simply bridge any specification network they like and start recording events about resources which the network does not know how to deal with.

There are implications here for deterministic cross-DNA validation; ping @pauldaoust

The constraints are defined by the DNA (well, the individual zomes in the DNA that require bridges) and are apparently already enforced: Bridge config/runtime checks by lucksus · Pull Request #1461 · holochain/holochain-rust · GitHub Ironically, this is also the cause of your frustration with two-way bridges :sweat_smile:

Here are the rules:

  • A zome can define a bridge dependency by giving it a handle and referring to either:
    • a specific DNA hash, or
    • a ‘trait’ (interface or contract) that the DNA should satisfy
  • The conductor checks that the configured bridge with that same handle actually satisfies the dependency — you have to trust your conductor, but that’s a foundational assumption anyway.

There was some talk about a capability validation callback that would let your DNA determine whether to allow a dependent DNA to bridge to it, but I think this is backwards to what you’re asking about — it’s more about access control than dependency satisfaction.

You know, one consequence of this discovery is that I don’t know anymore if bridges can be defined at runtime. Have you tested this @pospi? I think I’m gonna give it a go — instantiate a DNA, define a bridge that isn’t specified in the DNA JSON, try to call it.

That sounds like what I need, except I need the ability to do this dynamically. Like maybe I have an increasingly expanding set of collaboration networks that I want to permission in to this one; I want to be able to keep whitelisting DNA hashes that are allowed to be bound.

I have never been able to get the required bridge configuration to work- the conductor always errors at me, and the bridging config is definitely present. I think it may also not work with tests because they use the admin API to set up the bridges, rather than the config parser. In any case, when I use optional my multi-DNA setups have always worked fine.

Hm, sounds like a bug. Do you have an open issue for that one yet?

DHT, Freesig, Art, and I are collecting a list of things that we think are crucial for real-world apps. I’ve already recorded this one — do you think I’ve captured the essence of the need and the feature?

Runtime bridging is not allowed? How to define a bridge dependency of “I want to bridge to n of this kind of DNA”? ( optional flag implied; no handle) Use case: a HoloREA space depends on zero or more ontology DNAs that all satisfy the trait "product_ontology" . Maybe this should be baked into the DNA, and adding another ontology should require a DNA upgrade… But this puts the onus on potentially non-technical people who don’t know how to open up a DNA JSON file and twiddle with bridge definitions.

You know, in the interim, for rapid prototyping purposes, you certainly could bake it into the DNA in ways that wouldn’t require users to become Rust experts. Here’s how it might look:

  • Define your ontology DNA dependencies (I assume they all expose the same API, right?) in two places:

    • The zome.json file that lists all bridges
      {
        "bridges": [
          {
            "presence": "optional",
            "handle": "google-taxonomy",
            "reference": {
              "traits": { "product_taxonomy" }
            }
          },
          {
            "presence": "optional",
            "handle": "gpc-taxonomy",
            "reference": {
              "traits": { "product_taxonomy" }
            }
          }
        ]
      }
      
    • A key/value pair in the DNA’s properties that lists out the product taxonomy bridges so your DNA can iterate through them
      "properties": {
          "product_taxonomy_bridges": [ "google-product-taxonomy", "gpc-product-taxonomy" ]
      }
      
  • Whenever you need to access this unknown number of taxonomy dependencies in your zome code, you just iterate through that prop:

    let taxonomies = hdk::property("product_taxonomy_bridges")
        .try_into<Vec<String>>()?
    let categories = taxonomies
        .filter_map(|b| { hdk::call(b, "categories", hdk::PUBLIC_TOKEN, "get_categories", {}) );
    

    (warning: almost guaranteed not to compile)

    This is not what you’re looking for, I acknowledge, but at least it can be implemented now, and without forcing others to learn Rust?

Yeah, nice! That looks workable (: I’ll let you know how it goes once we get to implementing it…