Skip to content

Commit

Permalink
Reworded explanation of calculating namespace when IgnoreMaxNamespace…
Browse files Browse the repository at this point in the history
… is set (#134)

<!--
Please read and fill out this form before submitting your PR.

Please make sure you have reviewed our contributors guide before
submitting your
first PR.
-->

## Overview

<!-- 
Please provide an explanation of the PR, including the appropriate
context,
background, goal, and rationale. If there is an issue with this
information,
please provide a tl;dr and link the issue. 
-->
This PR rephrases the explanation on how the namespace range is
calculated when the parameter `IgnoreMaxNamespace` is set. If merged, it
will close #133 .

I tried to simplify sentences explaining the logic and add a precise
expression at the end of the explanation.

[rendered
document](https://github.com/ivan-gavran/nmt/blob/ivan/ignoreMaxNsExplanation/docs/nmt-lib.md)

## Checklist

<!-- 
Please complete the checklist to ensure that the PR is ready to be
reviewed.

IMPORTANT:
PRs should be left in Draft until the below checklist is completed.
-->

- [ ] New and updated code has appropriate documentation
- [ ] New and updated code has new and/or updated testing
- [ ] Required CI checks are passing
- [ ] Visual proof for any user facing features like CLI or
documentation updates
- [x] Linked issues closed with keywords

---------

Co-authored-by: Evan Forbes <42654277+evan-forbes@users.noreply.github.com>
  • Loading branch information
ivan-gavran and evan-forbes authored Mar 15, 2023
1 parent dbeab9e commit 25711ba
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 12 deletions.
14 changes: 8 additions & 6 deletions docs/nmt-lib.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,18 @@ idSize := tree.NamespaceSize() // outputs 1

### Ignore Max Namespace

If the NMT is configured with `IgnoreMaxNamespace` set to true, then the calculation of the namespace ID range of non-leaf nodes in the [namespace hash function](./spec/nmt.md#namespaced-hash) will change slightly.
That is, when determining the upper limit of the namespace ID range for a tree node `n`, with children `l` and `r`, the maximum possible namespace ID, equivalent to `NamespaceIDSize()` bytes of `0xFF`, or `2^NamespaceIDSize()-1`,
should be omitted if feasible (in the preceding code example with the ID size of `1` byte, the maximum possible namespace ID would be `0xFF`).
This is achieved by taking the maximum value among the namespace IDs available in the range of node's left and right children (i.e., `n.maxNs = max(l.minNs, l.maxNs , r.minNs, r.maxNs))`, which is not equal to the maximum possible namespace ID value.
If such a namespace ID does not exist, the `maxNs` is calculated as normal, i.e., `n.maxNs = max(l.maxNs , r.maxNs)`.
If the NMT is configured with `IgnoreMaxNamespace` set to true (the flag is explained [here](#nmt-initialization-and-configuration)), then the calculation of the namespace ID range of non-leaf nodes in the [namespace hash function](./spec/nmt.md#namespaced-hash) will change slightly.
That is, when determining the upper limit of the namespace ID range for a tree node, the maximum possible namespace `maxPossibleNamespace` should not be taken into account.
(In the preceding code example with the ID size of `1` byte, the value of `maxPossibleNamespace` is $2^8-1 = 0xFF$.)

Concretely, for a node `n` with children `l` and `r`, the namespace ID is the largest namespace value from `l` and `r` smaller than `maxPossibleNamespace`, if such a namespace ID exists.
Otherwise, if all candidate values are equal to `maxPossibleNamespace`, the namespace ID of `n` is set to `maxPossibleNamespace`.
Precisely, if a set `C` $= \bigl \lbrace$ `ns` $\in \lbrace$`l.minNs`, `l.maxNs`, `r.minNs`, `r.maxNs` $\rbrace:$ `ns` $<$ `maxPossibleNamespace` $\bigr \rbrace$ is not empty, `n.maxNs = max(C)`. If `C` is empty, `n.maxNs = maxPossibleNamespace`.

## Add Leaves

Data items are added to the tree using the `Push` method.
Data items should be prefixed with namespaces of size set out for the NMT (i.e., `tree.NamespaceSize()`) and added in ascending order of their namespace IDs to avoid errors during the `Push` process.
Data items should be prefixed with namespaces of size set out for the NMT (i.e., `tree.NamespaceSize()`) and added in ascending order of their namespace IDs to avoid errors during the `Push` process.
Non-compliance with either of these requirements cause `Push` to fail.

```go
Expand Down
10 changes: 4 additions & 6 deletions hasher.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,12 +224,10 @@ func (n *Hasher) ValidateNodes(left, right []byte) error {
// is set to true, the calculation of the namespace ID range of the node
// slightly changes. In this case, when setting the upper range, the maximum
// possible namespace ID (i.e., 2^NamespaceIDSize-1) should be ignored if
// possible. This is achieved by taking the maximum value among the namespace
// IDs available in the range of its left and right children (i.e.,
// max(left.minNID, left.maxNID , right.minNID, right.maxNID)), which is not
// equal to the maximum possible namespace ID value. If such a namespace ID does
// not exist, the maximum NID is calculated as normal, i.e., "res.maxNID =
// max(left.maxNID , right.maxNID).
// possible. This is achieved by taking the maximum value among only those namespace
// IDs available in the range of its left and right children that are not
// equal to the maximum possible namespace ID value. If all the namespace IDs are equal
// to the maximum possible value, then the maximum possible value is used.
func (n *Hasher) HashNode(left, right []byte) []byte {
h := n.baseHasher
h.Reset()
Expand Down

0 comments on commit 25711ba

Please sign in to comment.