You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/pages/build/dht-operations.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@ An agent receives **DHT operations**, which are requests for them to transform [
7
7
:::
8
8
9
9
!!! info Validating actions instead of DHT operations
10
-
**This is an advanced topic.** Writing validation rules that checks DHT operations requires understanding Holochain's data model. Until you have a reason to write validation rules at this level of granularity, we recommend letting the [scaffolding tool](/get-started/3-forum-app-tutorial/) generate a `validate` callback for you, which calls out to [stub functions](/build/validate-callback/#create-boilerplate-code-with-the-scaffolding-tool) that validate the _actions_ that create, update, or delete your application's entry and link types, and makes opinionated but sensible choices about which groups of authorities should validate what portions of the op data. The following information is presented for people who have a specific need to further reduce overall validation overhead across the network.
10
+
**This is an advanced topic.** Writing validation rules that check DHT operations requires understanding Holochain's data model. Until you have a reason to write validation rules at this level of granularity, we recommend letting the [scaffolding tool](/get-started/3-forum-app-tutorial/) generate a `validate` callback for you, which calls out to [stub functions](/build/validate-callback/#create-boilerplate-code-with-the-scaffolding-tool) that validate the _actions_ that create, update, or delete your application's entry and link types, and makes opinionated but sensible choices about which groups of authorities should validate what portions of the op data. The following information is presented for people who have a specific need to further reduce overall validation overhead across the network.
11
11
!!!
12
12
13
13
## What is a DHT operation?
@@ -38,7 +38,7 @@ While the following info describes the way Holochain should work [as formally sp
* System validation: Check for non-monotonic sequence indices and timestamps in adjacent actions, and detect [source chain forks](/resources/glossary/#fork-source-chain).
41
+
* System validation: Check for non-monotonic sequence indices and timestamps in the chain of actions, and detect [source chain forks](/resources/glossary/#fork-source-chain).
42
42
* Effect: Append the action to a replica of the author's source chain.
* Basis addresses: entry and action hashes of the _old_ entry being updated
57
57
* Contents: action and entry <!--TODO: system validation? -->
58
-
* Effect: Mark an entry creation action as being replaced by a new one, pointing the the entry and action that replace it. **An entry and its creation action can have multiple actions updating them.**
58
+
* Effect: Mark an entry creation action as being replaced by a new one, pointing to the entry and action that replace it. **An entry and its creation action can have multiple actions updating them.**
Copy file name to clipboardExpand all lines: src/pages/build/entries.md
+12-4Lines changed: 12 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -339,9 +339,9 @@ You can use any of these identifiers as a field in your entry types to model a m
339
339
340
340
### As a single record
341
341
342
-
Get a record by calling [`hdk::entry::get`](https://docs.rs/hdk/latest/hdk/entry/fn.get.html) with the hash of either its entry creation action. The return value is an <code>Option<[holochain_integrity_types::record::Record](https://docs.rs/holochain_integrity_types/latest/holochain_integrity_types/record/struct.Record.html)></code> wrapped in an `ExternResult`.
342
+
Get an entry as a record by calling [`hdk::entry::get`](https://docs.rs/hdk/latest/hdk/entry/fn.get.html) with the hash of the entry creation action. The return value is an <code>Option<[holochain_integrity_types::record::Record](https://docs.rs/holochain_integrity_types/latest/holochain_integrity_types/record/struct.Record.html)></code> wrapped in an `ExternResult`. If the record is invalid or missing, the option will be `None`.
343
343
344
-
You can also pass an _entry hash_ to `get`, and the record returned will contain the _oldest live_ entry creation action that wrote it.
344
+
You can also pass an _entry hash_ to `get`, and the record returned will contain the _oldest-timestamped, valid, live_ entry creation action that wrote it.
345
345
346
346
```rust
347
347
usehdk::prelude::*;
@@ -387,7 +387,11 @@ match maybe_record {
387
387
388
388
#### Records
389
389
390
-
To get a record and all the updates, deletes, and outbound links associated with its action, as well as its current validation status, call [`hdk::entry::get_details`](https://docs.rs/hdk/latest/hdk/entry/fn.get_details.html) with an _action hash_. You'll receive an <code>Option<[holochain_zome_types::metadata::Details::Record](https://docs.rs/holochain_zome_types/latest/holochain_zome_types/metadata/enum.Details.html)></code> wrapped in an `ExternResult`; this enum variant contains a [`RecordDetails`](https://docs.rs/holochain_zome_types/latest/holochain_zome_types/metadata/struct.RecordDetails.html).
390
+
To get a record and all the updates and deletes associated with its action, as well as its current validation status, call [`hdk::entry::get_details`](https://docs.rs/hdk/latest/hdk/entry/fn.get_details.html) with an _action hash_. You'll receive an <code>Option<[holochain_zome_types::metadata::Details::Record](https://docs.rs/holochain_zome_types/latest/holochain_zome_types/metadata/enum.Details.html)></code> wrapped in an `ExternResult`; this enum variant contains a [`RecordDetails`](https://docs.rs/holochain_zome_types/latest/holochain_zome_types/metadata/struct.RecordDetails.html).
391
+
392
+
!!! info Invalid data or metadata
393
+
The record will be returned even if it's invalid; check the `validation_status` field. Only valid updates and deletes will be returned.
394
+
!!!
391
395
392
396
```rust
393
397
usehdk::prelude::*;
@@ -418,7 +422,11 @@ match maybe_details {
418
422
419
423
#### Entries
420
424
421
-
To get an entry and all the deletes and updates that operated on it (or rather, that operated on the entry creation actions that produced it), _as well as_ all its entry creation actions and its current status on the DHT, pass an _entry hash_ to [`hdk::entry::get_details`](https://docs.rs/hdk/latest/hdk/entry/fn.get_details.html). You'll receive an <code>Option<[`holochain_zome_types::metadata::Details::Entry`](https://docs.rs/holochain_zome_types/latest/holochain_zome_types/metadata/enum.Details.html)></code> wrapped in an `ExternResult`; this enum variant contains an [`EntryDetails`](https://docs.rs/holochain_zome_types/latest/holochain_zome_types/metadata/struct.EntryDetails.html).
425
+
To get an entry and all of its creation actions (both creates and updates), as well as all the valid deletes and updates that operated on it (or rather, that operated on the entry creation actions that produced it), pass an _entry hash_ to [`hdk::entry::get_details`](https://docs.rs/hdk/latest/hdk/entry/fn.get_details.html). You'll receive an <code>Option<[`holochain_zome_types::metadata::Details::Entry`](https://docs.rs/holochain_zome_types/latest/holochain_zome_types/metadata/enum.Details.html)></code> wrapped in an `ExternResult`; this enum variant contains an [`EntryDetails`](https://docs.rs/holochain_zome_types/latest/holochain_zome_types/metadata/struct.EntryDetails.html).
426
+
427
+
!!! info Invalid data or metadata
428
+
The entry will be returned even if all of its creation actions are invalid; check the [`actions`](https://docs.rs/holochain_zome_types/latest/holochain_zome_types/metadata/struct.EntryDetails.html#structfield.actions) field for valid creation actions and [`rejected_actions`](https://docs.rs/holochain_zome_types/latest/holochain_zome_types/metadata/struct.EntryDetails.html#structfield.rejected_actions) for invalid ones. Only valid deletes and updates will be returned. Note that currently [`entry_dht_status`](https://docs.rs/holochain_zome_types/latest/holochain_zome_types/metadata/struct.EntryDetails.html#structfield.entry_dht_status) is only `Live` or `Dead`, which only takes valid creation and deletion actions into account. All other entry DHT status variants are unused.
Copy file name to clipboardExpand all lines: src/pages/build/identifiers.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -28,16 +28,16 @@ The four-byte DHT location is calculated from the 32 bytes of the hash and is us
28
28
29
29
There are also a couple of composite types, [`AnyDhtHash`](https://docs.rs/holo_hash/latest/holo_hash/type.AnyDhtHash.html) and [`AnyLinkableHash`](https://docs.rs/holo_hash/latest/holo_hash/type.AnyLinkableHash.html).
30
30
31
-
Here's an overview of the five types above, plus two composite types:
31
+
Here's an overview of the five types above, plus the two composite types:
32
32
33
-
*`DnaHash` is the hash of the DNA bundle (including any DNA modifiers passed in at installation or cloning time), and is the [unique identifier for the network](/build/working-with-data/#storage-locations-and-privacy).
33
+
*`DnaHash` is the hash of the DNA bundle (including any DNA modifiers passed in at installation or cloning time), and is the [unique identifier for the DNA's network](/build/working-with-data/#storage-locations-and-privacy).
34
34
*`AgentPubKey` is the public key of a participant in a network.
35
35
*`ActionHash` is the hash of a structure called an [action](/build/working-with-data/#entries-actions-and-records-primary-data) that records a participant's act of storing or changing private or shared data.
36
36
*`EntryHash` is the hash of an arbitrary blob of bytes called an [entry](/build/entries/), which contains application or system data. (Note: there's a special system entry called [`Agent`](https://docs.rs/holochain_zome_types/latest/holochain_zome_types/enum.Entry.html#variant.Agent), which holds the agent's public key; the hash function returns the public key itself, _not_ its hash.)
37
37
*`ExternalHash` is the ID of a resource that exists outside the database, such as the hash of an IPFS resource or the public key of an Ethereum wallet. Holochain doesn't care about its value, as long as it's 32 bytes long. There's no content stored at the address; it simply serves as an anchor to attach [links](/build/links-paths-and-anchors/) to.
38
38
* Composite types --- if one of the types above is eligible, it can be converted into one of these two types via the `.into()` method. Functions that take the below types will implicitly convert from the above types.
39
39
*`AnyDhtHash` is the hash of any kind of addressable content (actions, entries, and agent public keys). Any
40
-
*`AnyLinkableHash` is the hash of anything that can be linked to or from (that is, all of the above).
40
+
*`AnyLinkableHash` is the hash of anything that can be linked to or from (that is, all of the above, or `AnyDhtHash` + `ExternalHash`).
41
41
42
42
## Getting hashes
43
43
@@ -86,7 +86,7 @@ if let Action::Update(action_data) = action {
86
86
87
87
### Entry
88
88
89
-
To get the hash of an entry, first construct an instance of the entry type that you [defined in the integrity zome](/build/entries/#define-an-entry-type), then pass it through the [`hdk::hash::hash_entry`](https://docs.rs/hdk/latest/hdk/hash/fn.hash_entry.html) function. (You don't actually have to write the entry to a source chain to get the entry hash.)
89
+
To get the hash of an entry, first construct an instance of the entry type that you [defined in the integrity zome](/build/entries/#define-an-entry-type), then pass it through the [`hdk::hash::hash_entry`](https://docs.rs/hdk/latest/hdk/hash/fn.hash_entry.html) function. (You don't actually have to write the entry to a source chain to get its hash.)
90
90
91
91
```rust
92
92
usehdk::hash::*;
@@ -189,7 +189,7 @@ let ipfs_movie_poster_hash = ExternalHash::from_raw_32(vec.
192
+
In every application, there is one global hash that everyone knows, and that's the hash of the DNA itself. You can get it by calling [`hdk::info::dna_info`](https://docs.rs/hdk/latest/hdk/info/fn.dna_info.html).
193
193
194
194
```rust
195
195
usehdk::prelude::*;
@@ -201,7 +201,7 @@ let dna_hash = dna_info()?.hash;
201
201
202
202
### In DHT data
203
203
204
-
To reference an address in your entry data, define a field in your entry that can hold the right kind of address. The HDK will take care of serialization and deserialization for you. The following entry types have fields that reference other DHT data.
204
+
To reference an address in your entry data, define a field in your entry type that can hold the right kind of address. The HDK will take care of serialization and deserialization for you. The following entry types have fields that reference other DHT data.
Copy file name to clipboardExpand all lines: src/pages/build/links-paths-and-anchors.md
+8-4Lines changed: 8 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -100,7 +100,7 @@ let delete_link_action_hash = delete_link(
100
100
);
101
101
```
102
102
103
-
A link is considered ["dead"](/build/working-with-data/#deleted-dead-data) (deleted but retrievable if asked for explicitly) once its creation action has at least one delete-link action associated with it. As with entries, dead links can still be retrieved with[`hdk::entry::get_details`](https://docs.rs/hdk/latest/hdk/entry/fn.get_details.html) or[`hdk::link::get_link_details`](https://docs.rs/hdk/latest/hdk/link/fn.get_link_details.html) (see next section).
103
+
A link is live as long as its creation action is valid and there are no valid delete-link actions associated with it. Otherwise, it's considered ["dead"](/build/working-with-data/#deleted-dead-data). As with entries, dead links can still be retrieved with [`hdk::link::get_link_details`](https://docs.rs/hdk/latest/hdk/link/fn.get_link_details.html) (see next section).
104
104
105
105
### Deleting a link, under the hood
106
106
@@ -119,7 +119,7 @@ At this point, the action hasn't been persisted to the source chain. Read the [z
119
119
120
120
## Retrieve links
121
121
122
-
Get all the _live_ (undeleted) links attached to a hash with the [`hdk::link::get_links`](https://docs.rs/hdk/latest/hdk/link/fn.get_links.html) function. The input is complicated, so use [`hdk::link::builder::GetLinksInputBuilder`](https://docs.rs/hdk/latest/hdk/link/builder/struct.GetLinksInputBuilder.html) to build it.
122
+
Get all the live links attached to a hash with the [`hdk::link::get_links`](https://docs.rs/hdk/latest/hdk/link/fn.get_links.html) function. The input is complicated, so use [`hdk::link::builder::GetLinksInputBuilder`](https://docs.rs/hdk/latest/hdk/link/builder/struct.GetLinksInputBuilder.html) to build it.
123
123
124
124
```rust
125
125
usehdk::prelude::*;
@@ -148,7 +148,7 @@ let movies_in_1960s_by_director = get_links(
148
148
)?;
149
149
```
150
150
151
-
To get all live _and deleted_ links, along with any deletion actions, use [`hdk::link::get_link_details`](https://docs.rs/hdk/latest/hdk/link/fn.get_link_details.html).
151
+
To get all live _and deleted_ links (where ), along with any deletion actions, use [`hdk::link::get_link_details`](https://docs.rs/hdk/latest/hdk/link/fn.get_link_details.html).
152
152
153
153
```rust
154
154
usehdk::prelude::*;
@@ -162,6 +162,10 @@ let movies_plus_deleted = get_link_details(
162
162
)?;
163
163
```
164
164
165
+
!!! info Invalid links
166
+
There is no way to retrieve invalid link creation or deletion actions from a base.
167
+
!!!
168
+
165
169
### Count links
166
170
167
171
If all you need is a _count_ of matching links, use [`hdk::link::count_links`](https://docs.rs/hdk/latest/hdk/link/fn.count_links.html). It has a different input with more options for querying (we'll likely update the inputs of `get_links` and `count_links` to match in the future).
@@ -185,7 +189,7 @@ let number_of_reviews_written_by_me_in_last_month = count_links(
185
189
```
186
190
187
191
!!! info Links are counted locally
188
-
Currently `count_links` retrieves all link hashes from the remote peer, then counts them locally. So it is less network traffic than a `get_links` request, but more network traffic than just sending an integer.
192
+
Currently `count_links` retrieves all links from the remote peer, then counts them locally. As with `get_links`, only live links are included.
!!! info This may not catch all validation failures
172
172
`must_get_valid_record` checks for validation success or failure on the [`StoreRecord` DHT operation](/build/dht-operations/#store-record). Validation code for other DHT operations produced from the same action may have executed and failed.
173
173
174
-
In the future, we intend to introduce 'warrants', a feature which will allow validators to communicate failures to each other for related data. Until then, if any of your validation code uses `must_get_valid_record` to retrieve a dependency, we recommend that the dependency's validation code for the `StoreRecord` operation cover all possible checks.
174
+
[**Warrants**](/resources/glossary/#warrant) allow a validator to communicate news of an invalid DHT operation to non-authorities. But because they're not guaranteed to be co-located with the failed op, or even guaranteed to be delivered at all, they can't be used in a validation callback, which must work with a closed, deterministic set of data. If you absolutely need `must_get_valid_record` to fail for _all_ possible validity issues for a dependency, make sure the dependency's validation code for the `StoreRecord` operation covers all possible checks.
0 commit comments