diff options
author | pukkamustard <pukkamustard@posteo.net> | 2020-10-19 16:14:55 +0200 |
---|---|---|
committer | pukkamustard <pukkamustard@posteo.net> | 2020-10-19 16:17:10 +0200 |
commit | 2d05cf02bb136c742020e8c50d3717a8fb40a67f (patch) | |
tree | 3168b9347e360004394d237093fdb00463d30afb /doc | |
parent | 7c877f729c489414c60dce6866b44f1df0829d84 (diff) |
docs -> doc
Diffstat (limited to 'doc')
30 files changed, 5556 insertions, 0 deletions
diff --git a/doc/cache-vocabulary.ttl b/doc/cache-vocabulary.ttl new file mode 100644 index 0000000..01f644d --- /dev/null +++ b/doc/cache-vocabulary.ttl @@ -0,0 +1,30 @@ +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix dcterms: <http://purl.org/dc/terms/> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix voaf: <http://purl.org/vocommons/voaf#> . + +<> + dcterms:title "Cache Vocabulary"@en ; + a voaf:Vocabulary . + +<#Cache> + a rdfs:Class ; + rdfs:label "Cache" ; + rdfs:subClassOf dcterms:ProvenanceStatement . + +<#creator> + a rdf:Property ; + rdfs:label "Creator" ; + rdfs:comment "The entity that created the cache" ; + rdfs:subPropertyOf dcterms:creator . + +<#cachedAt> + a rdf:Property ; + rdfs:label "Date Cached" ; + rdfs:subPropertyOf dcterms:created . + +<#source> + a rdf:Property ; + rdfs:label "Source" ; + rdfs:comment "The source of the cache." ; + rdfs:subPropertyOf dcterms:source . diff --git a/doc/eris-cache.org b/doc/eris-cache.org new file mode 100644 index 0000000..138b27b --- /dev/null +++ b/doc/eris-cache.org @@ -0,0 +1,53 @@ +# SPDX-FileCopyrightText: 2020 pukkamustard <pukkamustard@posteo.net> +# +# SPDX-License-Identifier: CC-BY-SA-4.0 +#+TITLE: ERIS Cache +#+AUTHOR: pukkamustard +#+HTML_HEAD: <style>body {margin: 40px; font-family: sans-serif;} #content { line-height: 1.6; font-size: 16px; color: #222; max-width: 800px;margin: 40px auto;} pre.src {overflow: auto;}</style> +#+PROPERTY: header-args:scheme :session *eris-cache-model-repl* :eval never-export +#+OPTIONS: toc:nil + +#+BEGIN_abstract +An extension to the W3C PROVenance Interchange Ontology to describe the activity of content-addressed caching with the ERIS encoding. +#+END_abstract + +#+TOC: headlines 2 + +* Introduction + +By content-addressing RDF data we can increase the robustness of systems as the content is decoupled from a single location where it is hosted [cite:ContentAddressableRDF2020]. + +A lot of content is already published using location-addressed identifiers (URLs). Such content can be made content-addressable. This improves the availability of the location-addressed content and may be seen as a content-addressed cache. + +We propose a vocabulary to describe the original source of the content-addressed cache as well as other circumstances that describe the creation of the cache as an extension to the W3C PROV-O ontology [cite:lebo2013prov]. + +The proposed ontology is tied to the ERIS encoding scheme [cite:ERIS_2020]. + +* Vocabulary + +#+BEGIN_SRC ttl :exports code :tangle eris-cache.ttl +@prefix ec: <http://purl.org/eris/cache#> . +@prefix prov: <http://www.w3.org/ns/prov#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . + +<http://purl.org/eris/cache#> + a owl:Ontology ; + rdfs:label "ERIS Cache Vocabulary"@en ; + rdfs:comment "An extension to the W3C PROVenance Interchange Ontology to describe the Activity of content-addressed caching with the ERIS encoding."@en . + +ec:CreateCache + a rdfs:Class ; + rdfs:label "CreateCache" ; + rdfs:comment "The activity of creating an ERIS encoded, content-addressed cache of some content."; + rdfs:subClassOf prov:Activity . +#+END_SRC + + +bibliography:refs.bib + +#+BEGIN_EXPORT html +<p> +<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" property="dct:title" rel="dct:type">ERIS Cache</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://openengiadina.net/" property="cc:attributionName" rel="cc:attributionURL">openEngiadina</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>. +</p> +#+END_EXPORT diff --git a/doc/eris.org b/doc/eris.org new file mode 100644 index 0000000..e07d1f0 --- /dev/null +++ b/doc/eris.org @@ -0,0 +1,728 @@ +# SPDX-FileCopyrightText: 2020 pukkamustard <pukkamustard@posteo.net> +# +# SPDX-License-Identifier: CC-BY-SA-4.0 +#+TITLE: An Encoding for Robust Immutable Storage +#+SUBTITLE: 11. June 2020 (v0.1) +#+AUTHOR: pukkamustard +#+KEYWORDS: Content-addressable Storage, ActivityPub, RDF, GNUNet, P2P, Datashards +#+HTML_HEAD: <style>body {margin: 40px; font-family: sans-serif;} #content { line-height: 1.6; font-size: 16px; color: #222; max-width: 800px;margin: 40px auto;} pre.src {overflow: auto;} blockquote {text-align: right; margin-left: 30%; max-width: 70%; font-style: italic;}</style> +#+PROPERTY: header-args:dot :cmdline -Nfontname=sans-serif -Tsvg :eval never-export :exports results +#+PROPERTY: header-args:scheme :session *eris-repl* :eval never-export +#+OPTIONS: toc:nil + +#+BEGIN_abstract +We present an Encoding for Robust Immutable Storage (ERIS) that can be used with a content-addressable storage to encode arbitrary content into a set of uniformly sized encrypted blocks such that the content can only be reassembled to the original content given a /read capability/. + +Additionally, a /verification capability/ can be derived from the /read capability/ that can be used to enumerate blocks required to reassemble the content and verify the integrity of blocks without being able to read the content. This allows peers to cache the content whit plausible deniability of being able to read the content. + +We illustrate how ERIS can be used to build as a building block for robust, decentralized applications and demonstrate how ERIS can leverage existing peer-to-peer technology (such as IPFS). +#+END_abstract + +#+TOC: headlines 3 + +* Introduction + +#+BEGIN_QUOTE +The one so like the other + +As could not be distinguish'd but by names. + +--- William Shakespeare, Comedy of Errors +#+END_QUOTE + +Unavailability of content on computer networks is a major cause for reduced reliability of networked services [cite:Polleres_Kamdar_Fernández_Tudorache_Musen_2020]. + +Availability can be increased by caching content on multiple peers. However most content on the Internet is identified by its location. Caching location-addressed content is complicated as the content receives a new location. + +An alternative to identifying content by its location is to identify content by its content itself. This is called content-addressing. The hash of some content is computed and used as an unique identifier for the content. + +Content-addressed content is much easier to cache as the content is completely decoupled from any physical location. It is much easier to ensure availability of content-addressed content than it is for location-addressed content. Systems like [[https://ipfs.io/][IPFS]] use content-addressing for exactly this reason. + +Authenticity of content is automatically ensured with content-addressing (when using a cryptographic hash) as the identifier of the content can be computed and be checked to match the requested identifier. + +However, naive content-addressing has certain drawbacks: + +- Large content is stored as a large blob. In order to optimize storage and network operations it is better to split up content into smaller uniformly sized blocks and reassemble blocks when needed. +- Confidentiality: Content is readable by all peers involved in transporting, caching and storing content. + +We propose ERIS, a scheme that addresses the issues with naive content-addressing that we hope may provide a robust foundation for storing immutable content. + +** Requirements + +The requirements for the ERIS are: + +- Availability of content: Content can be replicated and cached. +- Authenticity: Authenticity of content can be verified. +- Plausible deniability for peers: Peers that transport, store and cache data blocks can do this without being able to read the content. +- URN reference: Content can be reference with a single URN. +- Simplicity: The encoding should be as simple as possible in order to allow correct implementation on various platforms and in various languages. + +** Scope + +#+BEGIN_QUOTE +A concept is tolerated inside the microkernel only if moving it outside the kernel, i.e. permitting competing implementations, would prevent the implementation of the system’s required functionality. + +--- Jochen Liedtke, On μ-Kernel Construction [cite:liedtke1995micro] +#+END_QUOTE + +ERIS describes how arbitrary content (sequence of bytes) can be encoded into a set of uniformly sized blocks and an identifier with which the content can be decoded from the set of blocks. + +ERIS does not prescribe how the blocks should be stored or transported over network. The only requirement is that a block can be referenced and accessed (if available) by the hash value of the contents of the block. In section [[storage-and-transport][Storage and Transport]] we show how existing technology (including IPFS) can be used to store and transport blocks. + +There is also no support for grouping content or mutating content. In section [[namespaces][Namespaces]] we describe how such functionality can be implemented on top of ERIS. + +The lack of certain functionalities is intentional. ERIS is an attempt to find a minimal common basis on which higher functionality can be built. Lacking functionality in ERIS is an acknowledgment that there are many ways of implementing such functionality at a different layer that may be optimized for certain use-cases. In section [[applications][Applications]] we illustrate how such functionality may be implemented using ERIS. + +* ERIS encoding +<<eris-encoding>> + +The scheme we propose defines an encoding of content into uniformly sized content-addressed, encrypted data blocks and a reference (an URN) that can used to reassemble the blocks to the original content. We call the reference that can be used to reassemble the blocks the /read capability/. + +Given the read capability and the encrypted data blocks the original content can be decoded. + +From the read capability a /verification capability/ can be deterministically derived. The verification capability allows holder to enumerate all blocks required to reassemble the content and verify the integrity of the blocks. The verification capability can not be used to decode the unencrypted content. The verification capability allows plausible deniable caching of content. + +An optional /convergence secret/ can be specified when encoding the content. This provides (optional) protection from certain attacks (see [[convergence-secret][Convergence secret]]). + +#+BEGIN_SRC dot :file images/eris-overview.svg :exports results +digraph { + rankdir = "LR"; + content [shape=box]; + + encode [label="encode"]; + decode [label="decode"]; + + content -> encode; + content -> decode [dir=back]; + + c_secret [label="convergence secret\n(optional)", shape="box"]; + + read_cap [shape="box",label="read capability"]; + blocks [shape="box",label="data blocks\n(encrypted)"]; + + c_secret -> encode; + + encode -> read_cap; + encode -> blocks; + + decode -> read_cap [dir=back]; + decode -> blocks [dir=back]; + + verify_cap [shape="box",label="verification capability"]; + read_cap -> verify_cap [label="derive"]; + + verify [label="verify"]; + + verify_cap -> verify; + blocks -> verify; + + list_of_blocks [label="list of references\nto data blocks"]; + verify -> list_of_blocks; +} +#+END_SRC + +#+CAPTION: Overview of ERIS +#+ATTR_HTML: :style width: 150%; transform: translateX(-50%); margin-left: 50%; +#+RESULTS: +[[file:images/eris-overview.svg]] + +** Preliminaries +*** Cryptographic primitives +<<crypto>> + +Following cryptographic primitives are used by ERIS: + +- Cryptographic hash function :: BLAKE2b [cite:aumasson2013blake2,saarinen2015blake2] with output size of 256 bit (32 byte) +- Symmetric Key Cypher :: ChaCha20 IETF variant [cite:nir2015chacha20] +- Padding algorithm :: According to ISO/IEC 7816-4 +- Key derivation :: Using keyed and salted BLAKE2b. Derived key is ~BLAKE2b(key=key, message={}, salt=subkey_id, personal=ctx)~. + +The cryptographic primitives are readily available in libraries for many platforms and programming languages (e.g. [[https://doc.libsodium.org/][libsodium]]). + +*** Content-addressable storage +<<cas>> + +For storage of blocks we rely on a content-addressable storage which provides two functions: + +- ~cas-put!(block)~ :: Stores a 4kB ~block~ of data and returns a reference such that ~ref = BLAKE2b(block)~. +- ~cas-get(ref)~ :: Given a reference returns a block of data that was previously stored, such that ~ref = BLAKE2b(block)~. If there is no block stored for the reference then throw an error. + +A content-addressable storage can be implemented with a hash-map (in-memory), a key-value store (e.g. LevelDB), a relational database or using systems like IPFS (see [[storage-and-transport][Storage and Transport]]). + +** Read and verification key + +ERIS uses two keys to encrypt content: + +- read key :: The key used to encrypt the content. The read key is ~BLAKE2b(content)~. If a convergence secret is given the read key is ~BLAKE2b(content, key=covergence-secret)~ (using keyed hashing). +- verification key :: Derived from the read key using the subkey id ~1~ and personalization context set to the UTF-8 encoding of the string ~"eris.key"~. + +*** Convergence Secret +<<convergence-secret>> + +Using the hash of the content as key is called /convergent encryption/. + +Because the hash of the content is deterministically computed from the content, the key will be the same when the same content is encoded twice. This results in deduplication. + +However convergent encryption suffers from two known attacks: The Confirmation Of A File Attack and The Learn-The-Remaining-Information Attack [cite:Zooko2008]. + +A defense against both attacks is to use a /convergence secret/. This results in different keys and different URNs when encoding the same content with different convergence secret. + +In section [[namespaces][Namespaces]] we describe how convergence secrets can be used. + +** Encoding + +The encoding process takes the content (as sequence of bytes), the read key and the verification key and returns a /root reference/ (32 bytes) and a /level/ count (positive integer with maximum value 12) which denotes the height of the Merkle tree. + +The encoding process is: + +1. Content is first padded (see [[crypto][Cryptographic Primitives]]) to a multiple of 4kB. +2. Content is then encoded with the symmetric key cypher using the ~read key~ and nonce set to ~0~. If content is larger than 256 GB use nonce ~0~ for first 256 GB and increment nonce for successive chunks of 256 GB. +3. Encrypted content is split into blocks of size 4kB. The blocks holding encrypted content are called /data blocks/. +4. Store data blocks in content-addressable storage and get /data block references/. +5. Combine the data block references in a Merkle tree and return the reference to the root node (root reference) and the height of the Merkle tree (level). + +The construction of the Merkle tree is described in the following section. + +*** Merkle tree + +After encrypting the content and placing the data blocks in the content-addressable storage we may have a large number of data block references. To retrieve the content we need all these references, which is impractical. Merkle trees allow us to hold a single reference that will allow us to discover all data block references. + +The idea is to store references to data blocks in nodes of a tree. The nodes are themselves stored in the content-addressable storage and can be referenced and accessed in the same way data blocks can be referenced and accessed. + +For illustration purposes we will show Merkle tree with arity two (two child references) the ERIS scheme uses arity 128. + +If the content fits in one single data block (content smaller than 4kB) then return the data block reference and level 0. + +If there are multiple data blocks combine them in a Merkle tree of arity 128. If there are less than 128 child nodes to be collected in a node the node is filled with null references (32 bytes of zeroes). The size of a node is always exactly 4kB (128 32 byte references). + +Nodes of the Merkle tree are encrypted using the verification key and a nonce derived from the position of the node in the tree. + +Encrypted nodes are stored in the content-addressable storage and references are placed in a node in the next higher level. + +Note that encrypted nodes are indistinguishable from encrypted data blocks. We will refer to encrypted nodes and encrypted data blocks as /blocks/. + +The Merkle tree is constructed until there is a single node on a level. This is the root reference. Note that the root reference is always the first of its level. + +#+BEGIN_SRC dot :file images/eris-merkle-1.svg :exports results +digraph { + + compound=true; + + subgraph cluster__level_0 { + style=dotted; + label="level 0\n(data blocks)"; + labeljust="l"; + + block_7 [shape=box,color=lightblue,style=filled,label="block-7"]; + block_6 [shape=box,color=lightblue,style=filled,label="block-6"]; + block_5 [shape=box,color=lightblue,style=filled,label="block-5"]; + block_4 [shape=box,color=lightblue,style=filled,label="block-4"]; + block_3 [shape=box,color=lightblue,style=filled,label="block-3"]; + block_2 [shape=box,color=lightblue,style=filled,label="block-2"]; + block_1 [shape=box,color=lightblue,style=filled,label="block-1"]; + block_0 [shape=box,color=lightblue,style=filled,label="block-0"]; + }; + + subgraph cluster__level_1 { + style=dotted; + label="level 1"; + labeljust="l"; + node_1_3 [shape=box,color=yellow,style=filled,label="node-1-3"]; + node_1_2 [shape=box,color=yellow,style=filled,label="node-1-2"]; + node_1_1 [shape=box,color=yellow,style=filled,label="node-1-1"]; + node_1_0 [shape=box,color=yellow,style=filled,label="node-1-0"]; + }; + + node_1_0 -> block_0; + node_1_0 -> block_1; + + node_1_1 -> block_2; + node_1_1 -> block_3; + + node_1_2 -> block_4; + node_1_2 -> block_5; + + node_1_3 -> block_6; + node_1_3 -> block_7; + + subgraph cluster__level_2 { + label="level 2"; + labeljust="l"; + style=dotted; + node_2_1 [shape=box,color=yellow,style=filled,label="node-2-1"]; + node_2_0 [shape=box,color=yellow,style=filled,label="node-2-0"]; + }; + + node_2_0 -> node_1_0; + node_2_0 -> node_1_1; + + node_2_1 -> node_1_2; + node_2_1 -> node_1_3; + + subgraph cluster__level_3 { + style=dotted; + label="level 3"; + labeljust="l"; + node_3_0 [shape=box,color=yellow,style=filled,label="node-3-0"]; + } + + node_3_0 -> node_2_0; + node_3_0 -> node_2_1; + +} +#+END_SRC + +#+CAPTION: Merkle tree +#+RESULTS: +[[file:images/eris-merkle-1.svg]] + +*** Nonce from position +<<nonce>> + +We identify the position of a node in the Merkle tree with the level and the count of nodes in the level (e.g. ~node-1-2~ is the third node from left on level one). + +We can encode the path from the root to a node by describing which child reference we have to follow. For example to reach ~node-1-1~ from the root node (~node-3-0~) the path is: left, right. If we use 0 for left and 1 for right: ~(0,1)~. + +All nodes at level 1 have a path of length two from the root: ~(0,0)~ for ~node-0-0~ or ~(1,0)~ for ~node-1-3~. + +Notice that the path to a leaf node is the base-2 encoding of the count in the level: ~node-1-3~ has count 3 which in binary (base-2) is ~(1,1)~ - the path to reach ~node-1-3~ from the root. + +For internal nodes (not at level 0) the same thing. To reach node ~node-2-1~ we take the path ~(1)~ which is the base-2 encoding of it's count in the level. + +However we have the problem of distinguishing ~(1)~ (~node-2-1~) from ~(0,1)~ (~node-1-1~). We solve this by introducing an additional variable ~X~ that denotes a path not taken yet. We can now encode all nodes to a fixed size: + +- ~node-1-1~: ~(0,1)~ +- ~node-1-3~: ~(1,1)~ +- ~node-2-1~: ~(1,X)~ +- ~node-2-0~: ~(0,X)~ +- ~node-3-0~: ~(X,X)~ + +This "path" can be encoded into a nonce that we can use for encrypting the nodes. + +In ERIS there are at most 128 child references per node, the path to a node can be computed by base-128 encoding the count of a node in a level. We use the value ~255~ as ~X~ and a maximum path length of 12. This sequence of 12 integers can be directly mapped to a 12 byte nonce. + +For example in ERIS (with Merkle tree of arity 128): + +- ~node-1-1~: ~(0,0,0,0,0,0,0,0,0,0,0,1)~ +- ~node-5-3~: ~(0,0,0,0,0,0,0,3,255,255,255,255)~ +- ~node-4-3042~: ~(0,0,0,0,0,0,0,23,98,255,255,255)~ +- ~node-8-294~: ~(0,0,0,2,38,255,255,255,255,255,255,255)~ + +The nonce directly identifies the position and is thus not reused. + +Note that the encoding is not efficient (values between 127 and 255 are not used) and limits the size of the Merkle tree and thus the size of the content that can be encoded with ERIS (see [[limits][Limits on size of content]]). + +*** Second preimage attack + +By encrypting the node using a nonce computed from the position of the node, we +implicitly encode the position of the node into the hash reference of a node. + +This prevents a node to be reused at an unforeseen position, preventing a [[https://en.wikipedia.org/wiki/Merkle_tree#Second_preimage_attack][second preimage attack]]. + +*** Two-pass encoding + +We have illustrated an algorithm that encrypts the entire content (or 256 GB chunks) in one go. This is not always possible (content may be larger than memory). + +ERIS can also be implemented as a two-pass streaming algorithm. + +In the first pass the read key is computed (using BLAKE2b). + +In the second pass 4 kB blocks of data are encrypted (setting the initial block counter appropriately), stored in the content-addressable storage and added to the Merkle tree. + +Unfortunately ERIS requires two passes over the content (as opposed to one single pass). This is a major drawback ERIS has. + +Two-pass encoding is implemented in the [[https://gitlab.com/openengiadina/data-model/][Guile implementation]]. + +** URN + +To read and/or verify content following information is required: + +- The root reference (as returned by the encode process) +- The level of the Merkle tree (as returned by the encode process) +- The read or verify key + +All this information can be packed in an URN, allowing ERIS encoded content to be referenced with a single identifier. We call such an identifier a /capability/ as it gives holder capability to read or verify the content. + +The root reference, level and key are encoded (with some additional information) to a /binary capability/ as follows: + +#+CAPTION: Binary capability encoding +| Byte offset | Content | Length (in bytes) | +|-------------+------------------------------------------------------+-------------------| +| 0 | version (~0x00~) | 1 | +| 1 | capability type (~0x00~ for read, ~0x01~ for verify) | 1 | +| 2 | level of root reference | 1 | +| 3 | root reference | 32 | +| 35 | read or verify key | 32 | + +The capability URN is: + +~urn:eris:X~ + +Where ~X~ is the Base32 encoding of the binary capability encoding. + +For example the read capability for the string "Hail ERIS!" is: + +#+BEGIN_SRC scheme :exports results +(use-modules (eris) + (web uri) + (eris cas) + (eris cas null) + (rnrs bytevectors)) + +(uri->string + (eris-put! (make-null-cas) + (string->utf8 "Hail ERIS!"))) +#+END_SRC + +#+RESULTS: +: urn:erisx:AAAAABM5XFVEHHR45X3YKU4ARK6MBHOZ4W22OTG5ME4NGO32H5P4SP3MCL3TK373WD53WSE6BOJACMNLBMKKFDKI25TAPP3SRY54QZ5WDX6Q + + +Note that we are currently using ~urn:erisx~ instead of ~urn:eris~ to denote experimental nature of the encoding. Once encoding is stabilized we will use ~urn:eris~. + +*** URN for blocks + +Individual blocks can also be addressed with an URN. + +There are many ways of doing this including: + +- [[https://tools.ietf.org/html/rfc6920][RFC 6920: Naming Things with Hashes]] +- [[https://multiformats.io/multihash/][Multihash]]: As used in IPFS +- [[https://github.com/w3c-ccg/hashlink][Hashlinks]]: Work by the W3C Credentials Community Group +- [[https://github.com/hash-uri/hash-uri][hash-uri]]: Another specification draft. + +ERIS does not specify a particular way of addressing blocks. + +Note however that the we can not reuse the specifications above as the ERIS URNs do not only hold the hash value of the content but other information necessary for decoding the content. + +** Decoding + +Given a read capability the content can be decoded by following child references of the nodes in the Merkle tree starting at the root. + +Note that the level (encoded in capability) is essential for decoding the content as the nonce for decrypting nodes is computed from the level and count of node in level. + +Integrity of content can be checked while decoding by re-computing the hash value of block and comparing them to the references. + +*** Random Access +<<random-access>> + +By decoding sub-trees specific ranges of the content can be decoded efficiently. This allows random read access to content. + +** Verifying + +The verification capability allows everything the read capability allows except decrypting of the data blocks and thus reading of the content. + +In particular a list of data blocks (and Merkle tree nodes) can be enumerated. This allows peers holding the verification capability to cache the content without being able to read it (plausible deniability for caching peers). + +The integrity of all blocks required to decrypt the content can be verified with the verification capability. + +** Limits on size of content +<<limits>> + +#+BEGIN_QUOTE +640K ought to be enough for anybody. + +--- Misattributed to Bill Gates +#+END_QUOTE + +The size of content that ERIS is able to encode is limited by the maximum depth of the Merkle tree. + +The maximum depth of the Merkle tree is 13 levels (including data block level). This is because for every internal node maps to a unique nonce of 12 bytes (see [[nonce][Nonce from position]]). + +The maximum size of content that ERIS can encode is thus $128^{13} \cdot 4 \mathrm{kB}$, more than $10^{20} \mathrm{GB}$. + +** On block size + +The block size of 4kB was chosen for following reasons: + +- Small content: Content smaller than 4kB still requires at least 4kB of storage as data block is padded to 4kB. A larger block size would make this worse. +- Reasonable overhead when encoding large files: The number of nodes required to combine data blocks into a single root reference is proportional to the number of references a node can hold. As nodes should be indistinguishable from data blocks they need to be the same size. Choosing 4kB (128 32 byte references) results in an overhead of less than 1% of the content size (see [[size-of-merkle-tree][Size of Merkle tree]]). + +Using multiple block sizes has also been considered. We believe that the additional complexity (in deterministically choosing the right block size) is not worth the storage efficiency. + +** Implementations and Demo + +Implementations of ERIS are available for following programming languages: + +- [[https://gitlab.com/openengiadina/data-model/][Guile]]: The initial implementation +- [[https://gitlab.com/openengiadina/js-eris][Javascript]] + +We have also implemented a JavaScript web application to demonstrate ERIS: [[https://openengiadina.gitlab.io/js-eris/index.html][Encoding for Robust Immutable Storage (ERIS)]]. + +* Applications +<<applications>> +** Storage and transport layers +<<storage-and-transport>> + +ERIS is agnostic of storage and transport layers for blocks and only requires the ability to store uniformly stored blocks and access blocks by their hash code (see [[cas][Content-addressable storage]]). + +Storage layers can be implemented with: + +- An in-memory hash-map. +- A key-value store (the [[https://gitlab.com/openengiadina/data-model/][Guile implementation]] uses LevelDB) +- A relational database +- IPFS + +Blocks may be transported over network via: + +- HTTP(S): A HTTP endpoint can be used to dereference blocks. +- Sneakernet: Blocks can be stored on a physical medium and transferred. +- Peer-to-Peer networks + +*** IPFS + +[[https://ipfs.io/][IPFS]] is an existing peer-to-peer network for sharing data. + +By default IPFS does not provide any security mechanism, in the sense that content published on the network is world-readable. Content is split up into blocks and tied together using a Merkle tree (called UnixFS). + +IPFS implementations also provide an interface to directly store and access blocks by their hash value - a content-addressable storage. + +ERIS can use the IPFS block API as a content-addressable storage and have blocks transported from peer to peer via IPFS transport mechanisms. In that sense ERIS can be used as a secure alternative to the IPFS default UnixFS encoding of content. + +This has been implemented and tested in the [[https://gitlab.com/openengiadina/data-model/-/blob/master/eris/cas/ipfs.scm][Guile]] and [[https://gitlab.com/openengiadina/js-eris/-/tree/master/examples/ipfs][JavaScript]] implementations of ERIS. + +** Metadata + +ERIS does not encode any metadata about the content. Metadata that references the content can be separately encoded and stored. + +#+CAPTION: Which animals are most like each other? +[[./images/duck-rabbit.png]] + +The image above can be encoded in ERIS and be referenced with the URN: + +#+BEGIN_SRC scheme :exports results +(use-modules (eris) + (web uri) + (eris cas) + (eris cas hash-table) + (rnrs bytevectors) + (rnrs io ports)) + +;; The underlying storage for our cas +(define backing-hash-table (make-hash-table)) + +;; Create a cas from the hash-table +(define my-cas (hash-table->cas backing-hash-table)) + +(uri->string + (call-with-input-file "./images/duck-rabbit.png" + (lambda (port) + (eris-put! my-cas + (get-bytevector-all port))) + #:binary #t)) + + +#+END_SRC + +#+RESULTS: +: urn:erisx:AAAADEQ445USOXW3JWYK255G4CQABSGYHAOQB7WA46APBTRBNWFAXAOPMK6OOYEN73BNFVWR6YNU6YN2SFQPRCUOHXSOPIZKCULJTR5XP5QQ + +Which could be referenced from encoding of metadata: + +#+BEGIN_SRC js +"image": { + "comment": "A duck.", + "href": "urn:erisx:AAAADEQ445USOXW3JWYK255G4CQABSGYHAOQB7WA46APBTRBNWFAXAOPMK6OOYEN73BNFVWR6YNU6YN2SFQPRCUOHXSOPIZKCULJTR5XP5QQ", + "mediaType": "image/png" +} +#+END_SRC + +#+RESULTS: + +Somebody might however disagree and think this is more appropriate metadata: + +#+BEGIN_SRC js +"image": { + "comment": "A rabbit.", + "href": "urn:erisx:AAAADEQ445USOXW3JWYK255G4CQABSGYHAOQB7WA46APBTRBNWFAXAOPMK6OOYEN73BNFVWR6YNU6YN2SFQPRCUOHXSOPIZKCULJTR5XP5QQ", + "mediaType": "image/png" +} +#+END_SRC + +Both are valid descriptions (metadata) of the image. By not supporting metadata in the content such ambiguities can be handled without duplicating the content itself. + +The format in which metadata is encoded is also not prescribed. We suggest using an RDF based description that is well adapted for content-addressing (see [[./content-addressable-rdf.org][Content-addressable RDF]]). + +** Authenticity of content + +ERIS can be used to ensure integrity of content. To ensure authenticity we propose using a RDF vocabulary for Ed25519 cryptographic keys and signatures: [[./rdf-signify.org][RDF signify]]. + +** Namespaces +<<namespaces>> + +Namespaces are groupings of content that themselves have an identifier. The members of a namespace may be dynamic. Namespaces are a fundamental building block for organizing content and building applications. + +There are many legitimate ways of implementing namespaces. ERIS does not provide a built-in mechanism. + +In the following we give an overview of some mechanism and illustrate how ERIS can be used. + +We believe that a key value of ERIS is the usability from very different namespace mechanisms. A collection of ERIS encoded content can be served from a HTTP server or be added to a Secure Scuttlebutt feed. By referencing the same content with the same identifier from different systems we can make content interoperable. + +*** Centralized server + +A dynamic namespace can be implemented with a HTTP server. + +A ~GET~ request to a certain URL (e.g. ~/collections/example~) returns a list of references to ERIS encoded content. The URL is the identifier of the namespace. + +The members of ~/collections/example~ can be modified with ~PUT~ and ~DELETE~ requests (potentially authenticated). + +The server maintains the list of members in a database. + +This is how very many HTTP services work (including ActivityPub). + +*** Hypercore and Scuttlebutt + +[[https://github.com/hypercore-protocol/hypercore][hypercore]] and [[https://scuttlebutt.nz/][Scuttlebutt]] provide a secure distributed append-only log. + +References to ERIS encoded content can be added to such logs. + +Hypercore and Scuttlebutt can also be used as storage and transport layer for blocks (add the blocks to the append-only logs). + +*** Commutative replicated data types + +Commutative replicated data types (CRDTs) are data containers where operations to modify the content naturally reach consistent states [cite:shapiro2011comprehensive]. + +There are many different CRDTs (e.g. a set or a register) with different characteristics. + +Together with the [[https://p2pcollab.net/#dromedar][P2PCollab]] project we intend to do further research in how CRDTs can be used for peer-to-peer collaboration. + +Previous work includes Dedalus [cite:alvaro2010dedalus] and Vegvisir [cite:karlsson2018vegvisir]. + +** Filesystem + +It is possible to encode an entire file system in ERIS by first packing the files and directories in an appropriate container and then encoding and storing. This would allow similar functionality to IPFS (which uses UnixFS). + +Individual files can be accessed efficiently as ERIS allows random read access to content (see [[random-access][Radon Access]]). + +Possible container formats include tar or SquashFS. + +* Related Work +** An Encoding for Censorship-Resistant Sharing (ECRS) + +ECRS [cite:Grothoff_2003] is the encoding used in the file-sharing application of [[https://gnunet.org/][GNUNet]]. ERIS is very much inspired by ECRS. + +Similar to ERIS, ECRS splits up content into uniform sized blocks (32kB) and combines them to a single root reference. + +Unlike ERIS, ECRS encrypts using the hash code of the block as a key (instead of a signle read key). Building the Merkle tree is simpler than in ERIS as there is no distinction between data blocks and tree nodes. However in addition to the reference to the block the key needs to be stored in a parent node (content-hash key). + +The reason for developing ERIS in contrast to just using ECRS is the verification capability. This allows blocks that are required to reassemble some content to be cached by a peer holding the verification capability, without being able to read the content. + +ECRS also provides two namespace mechanisms (SBlock and KBlock). Both mechanisms can be implemented with ERIS as well. + +** Datashards +<<datashards>> + +[[https://datashards.net/][Datashards]] is a secure storage foundation for the web. Work on ERIS was inspired by Datashards. It provides means for immutable as well as mutable storage. + +Datashards (immutable) splits encrypted content into uniformly sized blocks (called chunks) and combines them in a hash list. There is no verification capability for immutable storage. + +Mutability is implemented with an append-only log (similar to Hypercore and Scuttlebut). + +A key functionality ERIS shares with Datashards is the usability from the web by encoding capabilities as URNs. + +Datashards is still in development and in further work we hope to converge ideas and encoding. + +** Cryptosphere + +[[https://github.com/cryptosphere/cryptosphere][Cryptosphere]] was an experimental research project for securely publishing and distributing content based on Tahoe-LAFS and Freenet (among others). + +The key innovation in Cryptosphere is the "repair capability" which allows enumeration of all block required to reassemble content as well as verifying integrity. + +To enable the repair capability two (linked) Merkle trees are constructed, one allowing read capability and one allowing repair capability. + +The constructions of the tree is slightly more involved than in ERIS. + +** Other + +Other related projects include Tahoe-LAFS and Freenet. We refer the reader to the ECRS paper [cite:Grothoff_2003] which provides an excellent description and comparison. + +* Conclusion + +#+BEGIN_QUOTE +This is part of my reversing entropy plan - that hopefully will clear up the mess we're in. + +--- Joe Armstrong, [[https://joearms.github.io/published/2015-03-12-The_web_of_names.html][The web of names, hashes and UUIDs]] +#+END_QUOTE + +We present a scheme for encoding content that enables content-addressing, confidentiality and robustness. The key novelty is the verification capability that allows peers to cache the entire content without being able to read the content (as opposed to peers who do not hold any capability and only see uniformly sized blocks with random content). + +Furthermore we hope to motivate the usage of content-addressing for applications beyond peer-to-peer filesharing. ERIS is capable of encoding large files as well as small bits of content such as messages or notes on social media. In particular ERIS is useable with existing web technology and RDF (by providing an URN). Further work details how RDF can be made content-addressable with ERIS ([[./content-addressable-rdf.org][Content-Addressable RDF]]). + +We intend to implement the work presented in the context of the [[https://openengiadina.net/][openEngiadina]] project in order to enable offline-first and decentralized applications. + +Many thanks to Serge Wroclawski and Christopher Lemmer Webber (who are working on [[datashards][Datashards]]) for inspiring this work and discussions that shaped many aspects of ERIS. Thanks as well to TG (from [[https://p2pcollab.net/][P2PCollab]]) for the many pointers in the right directions. + +This work has been supported by the [[https://nlnet.nl/][NLNet Foundation]] trough the [[https://nlnet.nl/discovery/][NGI0 Discovery Fund]]. + +* Appendix +** Size of Merkle tree +<<size-of-merkle-tree>> + +How big is the Merkle tree in relation to the size of the content to be stored? This relation captures the storage overhead and the computational overhead of the Merkle tree. + +The parameters are: + +- $s_h$: size of the hash code +- $s_b$: block size +- $s_d$: size of the data to be stored + +To simplify the calculations we assume that the block size is always chosen as a multiple of $s_h$: + +$$ s_b = k s_h $$ + +Nodes in the Merkle tree have size $s_b$ and can hold at most $k$ child references. $k$ is the arity of the Merkle tree (in diagrams we have $k=2$). + +We also assume that the size of the data to be stored is a multiple of the block size: + +$$ s_d = n s_b $$ + +$n$ is the number of blocks the data is split into. + +For example the data we want to store is split up into 8 blocks ($n = 8$) and two child references fit into a block ($k = 2$): + +#+CAPTION: Merkle tree with 8 data blocks +[[./images/eris-merkle-1.svg]] + +We are interested in the number of nodes in the Merkle tree (the yellow boxes) in relation to the number of data blocks (white boxes). + +Let us call the number of nodes in the Merkle tree $m$. + +We can start counting the number of nodes in the Merkle tree from the top: + +$$ m = 1 + k + k^2 + k^3 ... + \frac{n}{k} $$ + +At the root level there is one node, at the level below $k$ and below $k^2$ - at every level we go down there are $k$ times more nodes. At the bottom level (level 0) there are $\frac{n}{k}$ nodes (this is also $log_k(n) - 1$). + +$m$ is a geometric serie and can be simplified: + +\begin{align*} + m &= 1 + k + k^2 + k^3 ... + \frac{n}{k} \\ + mk &= k + k^2 + k^3 + ... + \frac{n}{k} + n \\ + mk - m &= m(k - 1) = n - 1 \\ + m &= \frac{1}{k-1}(n-1) +\end{align*} + +The size of the Merkle tree is linearly proportional to $n$ with $\frac{1}{k}$. In big O notation: The size of the Merkle tree is $O(\frac{n}{k})$. + +If we choose a block size that fits exactly 2 child references ($k=2$), the Merkle tree will consist of at most half the number of data blocks - the storage overhead is 50%. + +Assuming $s_h = 32 \mathrm{B}$ ($256 \mathrm{bit}$) we have following block sizes and storage overheads: + +| $k$ | block size | overhead | +|-------+------------------+-----------| +| 2 | $64 \mathrm{B}$ | 50% | +| 32 | $1 \mathrm{kB}$ | 3.125% | +| 64 | $2 \mathrm{kB}$ | 1.6% | +| 128 | $4 \mathrm{kB}$ | 0.8% | +| 256 | $8 \mathrm{kB}$ | 0.4% | +| 512 | $16 \mathrm{kB}$ | 0.2% | +| 1024 | $32 \mathrm{kB}$ | 0.1% | +| 32000 | $1 \mathrm{MB}$ | 0.003125% | + +bibliography:refs.bib + +#+BEGIN_EXPORT html +<p> +<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" property="dct:title" rel="dct:type">An Encoding for Robust Immutable Storage</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://openengiadina.net/" property="cc:attributionName" rel="cc:attributionURL">openEngiadina</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>. +</p> +#+END_EXPORT diff --git a/doc/examples/cached-clowns.ttl b/doc/examples/cached-clowns.ttl new file mode 100644 index 0000000..6a30cea --- /dev/null +++ b/doc/examples/cached-clowns.ttl @@ -0,0 +1,23 @@ +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix schema: <https://schema.org/> . +@prefix as: <https://www.w3.org/ns/activitystreams> . +@prefix dcterms: <http://purl.org/dc/terms/> . +@prefix cache: <urn:erisx:AAAABDK5YTJKPC4O4AHTEDQBRLZXYCZO6E2NW6E5GCY4SRAQ5FLHI4BRZTILMJMLRA6VBDJ5XK7NGYSBJV47GKZTZXHTPV73THA2C4FLQJMA#> . + +<> + a as:Note ; + as:attributedTo <https://test.example/alice> ; + as:content "The clowns just went trough the loop!"@en ; + as:image <https://test.example/notes/1#image> ; + as:context <https://circus.show/performance-in-funky-town> ; + dcterms:provenance <#cache> . + +<#image> + a as:Image ; + as:url <https://test.example/images/1.jpg> . + +<#cache> + a cache:Cache ; + cache:created "2020-06-07"^^<http://www.w3.org/2001/XMLSchema#date> ; + cache:creator <https://inqlab.net/pukkamustard> ; + cache:source <https://test.example/note/1> . diff --git a/doc/examples/clowns.ttl b/doc/examples/clowns.ttl new file mode 100644 index 0000000..edab2b4 --- /dev/null +++ b/doc/examples/clowns.ttl @@ -0,0 +1,21 @@ +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix schema: <https://schema.org/> . +@prefix as: <https://www.w3.org/ns/activitystreams> . + +<https://test.example/notes/1> + <rdf:type> <as:Note> ; + <as:attributedTo> <https://test.example/alice> ; + <as:content> "The clowns just went trough the loop!"@en ; + <as:image> <https://test.example/notes/1#image> ; + <as:context> <https://circus.show/performance-in-funky-town> . + +<https://test.example/notes/1#image> + <rdf:type> <as:Image> ; + <as:url> <https://test.example/images/1.jpg> . + +<https://test.example/alice> + <rdf:type> <as:Person> . + +<https://circus.show/performance-in-funky-town> + <rdf:type> <schema:Event> ; + <schema:location> <https://circus.show/performance-in-funky-town#location> . diff --git a/doc/examples/ontology_v2.33.ttl b/doc/examples/ontology_v2.33.ttl new file mode 100644 index 0000000..c325b4a --- /dev/null +++ b/doc/examples/ontology_v2.33.ttl @@ -0,0 +1,985 @@ +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix : <http://www.lingvoj.org/ontology#> .
+@prefix xml: <http://www.w3.org/XML/1998/namespace> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix voaf: <http://purl.org/vocommons/voaf#> .
+@prefix dcterms: <http://purl.org/dc/terms/> .
+@prefix vann: <http://purl.org/vocab/vann/> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix schema: <http://schema.org/> .
+@prefix lode: <http://linkedevents.org/ontology/> .
+@prefix olca: <http://www.lingvoj.org/olca#> .
+@prefix lvont: <http://lexvo.org/ontology#> .
+@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
+@base <http://www.lingvoj.org/ontology> .
+
+### Vocabulary metadata ###
+
+<http://www.lingvoj.org/ontology>
+ a owl:Ontology;
+ a voaf:Vocabulary ;
+ rdfs:label "The Lingvoj Ontology"@en ;
+ dcterms:title "The Lingvoj Ontology"@en ;
+ rdfs:label "Ontología de lenguajes"@es ;
+ dcterms:title "Ontología de lenguajes"@es ;
+ rdfs:label "Ontologie des langues"@fr ;
+ dcterms:title "Ontologie des langues"@fr ;
+ rdfs:label "Taal Ontologie"@nl ;
+ dcterms:title "Taal Ontologie"@nl ;
+ rdfs:label "言語オントロジー"@ja ;
+ dcterms:title "言語オントロジー"@ja ;
+ rdfs:label "Ontologia de idiomas"@pt ;
+ dcterms:title "A Ontologia dos idiomas"@pt ;
+ dcterms:language <http://lexvo.org/id/iso639-3/eng>, <http://lexvo.org/id/iso639-3/spa>, <http://lexvo.org/id/iso639-3/fra>,<http://lexvo.org/id/iso639-3/nld>, <http://lexvo.org/id/iso639-3/jap>, <http://www.lexvo.org/id/iso639-3/por> ;
+ rdfs:comment "A vocabulary for describing the use of languages by people and organizations, their geographical scope and status as well as their usage in documents or during events"@en ;
+ rdfs:comment "Un vocabulaire pour décrire l'utilisation des langues par les personnes et les organisations, leur répartition géographique et leur statut, ainsi que leur usage dans les documents ou lors des événements"@fr ;
+ rdfs:comment "Un vocabulario para describir la utilización de lenguas por parte de personas y organizaciones, su ambito geográfico y su estatus, así como su utilización en documentos o durante eventos"@es ;
+ rdfs:comment "Een vokabular voor de beschrijving en het gebruik van talen door personen en organisaties, de geografische extensie en status en het gebruik ervan in documenten en tijdens evenmenten"@nl ;
+ rdfs:comment "人や組織による言語の使用、ドキュメント内やイベント期間中におけるその使用に加え、その地理的範囲と状況を記述するための語彙"@ja ;
+ rdfs:comment "Um vocabulário para descrever a utilização de idiomas por parte de pessoas ou organizações, o seu âmbito geográfico e seu estatuto, assim como a sua utilização em documentos ou durante eventos"@pt ;
+ vann:preferredNamespacePrefix "lingvo" ;
+ vann:preferredNamespaceUri "http://www.lingvoj.org/ontology#" ;
+ dcterms:creator <http://google.com/+BernardVatant> ;
+ dcterms:contributor <http://google.com/+MaríaPovedaVillalón> ;
+ dcterms:contributor <http://google.com/+RonaldPoell> ;
+ dcterms:contributor <https://plus.google.com/113072078430654119300> ;
+ dcterms:modified "2014-08-11";
+ dcterms:issued "2007-09-17";
+ skos:historyNote "v2.33 : Corrected minor typos, and added portuguese translations, provided by Mariana Curado Malta" ;
+ skos:historyNote "v2.32 : Added japanese translations, provided by Shuji Kamitsuna" ;
+ skos:historyNote "v2.31 : Added more translations, language metadata, fixed typos plus cosmetic changes in the .ttl file" ;
+ skos:historyNote "v2.3 : Added :LanguageResource class, subclasses and properties. Added properties :tag :officialIn :fromCountry" ;
+ skos:historyNote "v2.21 : Added dutch translations plus 'interpreter' property suggested by Ronald Poell, along with minor corrections" ;
+ skos:historyNote "v2.2 : Added spanish translations, provided by María Poveda Villalón" ;
+ skos:historyNote "v2.1 : Relaxed domain constraints on several properties, replaced by Ontology Loose Coupling Annotations" ;
+ rdfs:seeAlso <http://www.lingvoj.org/> ;
+ owl:versionIRI <http://www.lingvoj.org/ontology_v2.33.ttl> ;
+ owl:priorVersion <http://www.lingvoj.org/ontology_v2.32.ttl> ;
+ owl:incompatibleWith <http://www.lingvoj.org/ontology_v1.3.rdf> ;
+ owl:versionInfo "v2.33" .
+
+
+### Language Class ###
+
+:Lingvo
+ a owl:Class ;
+ rdfs:label "Sprache"@de , "Language"@en ,"Lingvo"@eo , "Lenguaje"@es , "Kieli"@fi , "Langue"@fr , "Linguaggio"@it , "言語"@ja , "Taal"@nl , "Språk"@no , "Jezyk"@pl , "Idioma"@pt , "Язык"@ru , "Språk"@sv , "Dil"@tr , "语言"@zh ;
+ rdfs:subClassOf <http://purl.org/dc/terms/LinguisticSystem> , <http://www.loc.gov/mads/rdf/v1#Language> ;
+ owl:equivalentClass <http://schema.org/Language>, <http://d-nb.info/standards/elementset/gnd#Language>, <http://purl.org/linguistics/gold/Language> , <http://www.ontotext.com/proton/protontop#Language> ;
+ lvont:somewhatSameAs <http://lexvo.org/ontology#Language> ;
+ vann:example <http://lexvo.org/id/iso639-3/fra>, <http://id.loc.gov/vocabulary/iso639-1/ja> ;
+ rdfs:comment "A language used in spoken or written human communication, or in which a resource is written or recorded. It is recommended to use instances defined on the basis of ISO 639 codes, such as those in examples"@en ;
+ rdfs:comment "Una lengua utilizada en la comunicación oral o escrita entre personas, o en la que se escribe o graba un recurso. Se recomienda el uso de las instancias definidas según los códigos ISO 639, como los que aparecen en los ejemplos"@es ;
+ rdfs:comment "Une langue utilisée dans la communication orale ou écrite entre humains, ou dans laquelle une ressource est écrite ou enregistrée. Il est recommandé d'utiliser des instances définies sur la base d'un code ISO 639, comme dans les exemples"@fr ;
+ rdfs:comment "Een taal gebruikt in geschreven of gesproken communicatie tussen mensen of in welke een bron is geschreven of opgenomen. Het is aan te raden instanties te gebruiken gedefinieerd op basis van de ISO 630 codes, zoals in deze voorbeelden"@nl ;
+ rdfs:comment "会話または記述による人間のコミュニケーションで使用される言語、または資源が記述または記録される言語。例にあるような、ISO 639コードに基づいて定義されたインスタンスを使用することが推奨される"@ja ;
+ rdfs:comment "Um idioma utilizado na comunicação oral ou escrita entre pessoas, ou na que se escreve ou grava um recurso. Recomenda-se a utilização das instâncias definidas segundo os códigos ISO 639, como os que aparecem nos excemplos"@pt .
+
+:tag
+ a owl:DatatypeProperty;
+ rdfs:label "language tag"@en ;
+ rdfs:label "tag de langue"@fr ;
+ rdfs:label "etiqueta"@es ;
+ rdfs:label "言語タグ"@ja ;
+ rdfs:label "taal tag"@nl ;
+ rdfs:label "tag de idioma"@pt ;
+ rdfs:comment "The tag to use for the language, for example as value of xml:lang. See https://tools.ietf.org/html/bcp47"@en ;
+ rdfs:comment "Le tag à utiliser pour la langue, par exemple comme valeur de xml:lang. Voir https://tools.ietf.org/html/bcp47"@fr ;
+ rdfs:comment "La etiqueta a utilizar para el lenguaje, por ejemplo como valor de xml:lang. Ver https://tools.ietf.org/html/bcp47"@es ;
+ rdfs:comment "例えばxml:langの値として、言語に用いるタグ。https://tools.ietf.org/html/bcp47を参照"@ja ;
+ rdfs:comment "A tag para ser usada, por exemplo como valor de xml:lang. Ver https://tools.ietf.org/html/bcp47"@pt ;
+ rdfs:subPropertyOf dcterms:identifier ;
+ rdfs:domain :Lingvo.
+
+### Properties used to describe the status of a language at a given date###
+
+:livingLanguage
+ a owl:DatatypeProperty;
+ rdfs:label "living language"@en ;
+ rdfs:label "lengua viva"@es ;
+ rdfs:label "langue vivante"@fr ;
+ rdfs:label "levende taal"@nl ;
+ rdfs:label "現用言語"@ja ;
+ rdfs:label "Idioma vivo"@pt;
+ rdfs:comment "The language has speakers at the given date"@en ;
+ rdfs:comment "La lengua tiene hablantes en la fecha dada"@es ;
+ rdfs:comment "La langue possède des locuteurs à la date indiquée"@fr ;
+ rdfs:comment "De taal wordt door mensen gesproken op het aangegeven moment"@nl ;
+ rdfs:comment "ある時点でその言語を話す人がいる"@ja ;
+ rdfs:comment "O idioma possui pessoas que o falam na data indicada"@pt ;
+ rdfs:domain :Lingvo ;
+ rdfs:range xsd:date .
+
+:endangeredLanguage
+ a owl:DatatypeProperty;
+ rdfs:label "endangered language"@en ;
+ rdfs:label "lengua en vías de extinción"@es ;
+ rdfs:label "langue menacée"@fr ;
+ rdfs:label "bedreigde taal"@nl ;
+ rdfs:label "絶滅危惧言語"@ja ;
+ rdfs:label "idioma em vias de extinção"@pt ;
+ rdfs:comment "The language is endangered at the given date"@en ;
+ rdfs:comment "La lengua está en vías de extinción en la fecha dada"@es ;
+ rdfs:comment "La langue est menacée à la date indiquée"@fr ;
+ rdfs:comment "De taal is bedreigd met uitsterven op de gegeven datum"@nl ;
+ rdfs:comment "ある時点でその言語は絶滅寸前である"@ja ;
+ rdfs:comment "O idioma está em vias de extinção na data indicada"@pt ;
+ rdfs:subPropertyOf :livingLanguage;
+ rdfs:domain :Lingvo ;
+ rdfs:range xsd:date .
+
+:extinctLanguage
+ a owl:DatatypeProperty;
+ rdfs:label "extinct language"@en ;
+ rdfs:label "lengua muerta"@es ;
+ rdfs:label "langue morte"@fr ;
+ rdfs:label "uitgestorven taal"@nl ;
+ rdfs:label "死語"@ja ;
+ rdfs:label "Idioma morto"@pt ;
+ rdfs:comment "The language has no longer any speaker at the given date"@en ;
+ rdfs:comment "La lengua no tiene ningún hablante en la fecha dada"@es ;
+ rdfs:comment "La langue n'a plus de locuteurs à la date indiquée"@fr ;
+ rdfs:comment "Er zijn geen mensen meer die deze taal spreken"@nl ;
+ rdfs:comment "ある時点でその言語を話す人はいなくなった"@ja ;
+ rdfs:comment "O idioma já não possui pessoas que o falam na data indicada"@pt ;
+ rdfs:domain :Lingvo ;
+ rdfs:range xsd:date .
+
+### Ability of a person to understand, speak, read or write a language ###
+
+:notUnderstood
+ a owl:ObjectProperty ;
+ rdfs:label "not understood"@en ;
+ rdfs:label "no comprendido"@es ;
+ rdfs:label "non comprise"@fr ;
+ rdfs:label "niet verstaan"@nl ;
+ rdfs:label "理解されない"@ja ;
+ rdfs:label "não compreendido"@pt;
+ rdfs:comment "The person does not understand at all the spoken language"@en ;
+ rdfs:comment "La persona no comprende la lengua hablada"@es ;
+ rdfs:comment "La personne ne comprend pas du tout la langue parlée"@fr ;
+ rdfs:comment "De persoon verstaat de taal in het geheel niet"@nl ;
+ rdfs:comment "その人はその話し言葉をまったく理解しない"@ja ;
+ rdfs:comment "A pessoa não compreende o idioma falado"@pt;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:notSpoken
+ a owl:ObjectProperty ;
+ rdfs:label "not spoken"@en ;
+ rdfs:label "no hablado"@es ;
+ rdfs:label "non parlée"@fr ;
+ rdfs:label "niet spreken"@nl ;
+ rdfs:label "話されない"@ja ;
+ rdfs:label "não falado"@pt ;
+ rdfs:comment "The person does not speak at all the language"@en ;
+ rdfs:comment "La persona no puede hablar la lengua"@es ;
+ rdfs:comment "La personne ne parle pas du tout la langue"@fr ;
+ rdfs:comment "De persoon spreekt de taal in het geheel niet"@nl ;
+ rdfs:comment "その人はその言語をまったく話さない"@ja ;
+ rdfs:comment "A pessoa não sabe falar o idioma"@pt ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:notRead
+ a owl:ObjectProperty ;
+ rdfs:label "not read"@en ;
+ rdfs:label "no leído"@es ;
+ rdfs:label "non lue"@fr ;
+ rdfs:label "niet lezen"@nl ;
+ rdfs:label "読まれない"@ja ;
+ rdfs:label "não lido"@pt ;
+ rdfs:comment "The person does not read at all the language"@en ;
+ rdfs:comment "La persona no puede leer la lengua"@es ;
+ rdfs:comment "La personne ne lit pas du tout la langue"@fr ;
+ rdfs:comment "De persoon leest de taal in het geheel niet"@nl ;
+ rdfs:comment "その人はその言語をまったく読まない"@ja ;
+ rdfs:comment "A pessoa não sabe ler o idioma"@pt ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:notWritten
+ a owl:ObjectProperty ;
+ rdfs:label "not written"@en ;
+ rdfs:label "no escrito"@es ;
+ rdfs:label "non écrite"@fr ;
+ rdfs:label "niet schrijven"@nl ;
+ rdfs:label "書かれない"@ja ;
+ rdfs:label "não escrito"@pt ;
+ rdfs:comment "The person does not write at all the language"@en ;
+ rdfs:comment "La persona no puede escribir la lengua"@es ;
+ rdfs:comment "La personne n'écrit pas du tout la langue"@fr ;
+ rdfs:comment "De persoon schrijft de taal in het geheel niet"@nl ;
+ rdfs:comment "その人はその言語をまったく書かない"@ja ;
+ rdfs:comment "A pessoa não sabe escrever no idioma"@pt ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:basicUnderstanding
+ a owl:ObjectProperty ;
+ rdfs:label "basic understanding"@en ;
+ rdfs:label "comprensión básica"@es ;
+ rdfs:label "compréhension élémentaire"@fr ;
+ rdfs:label "basis luisterniveau"@nl ;
+ rdfs:label "基礎的な理解"@ja ;
+ rdfs:label "entendimento básico"@pt ;
+ rdfs:comment "The person has a basic understanding of the spoken language"@en ;
+ rdfs:comment "La persona tiene un nivel básico de comprensión de la lengua hablada"@es ;
+ rdfs:comment "La personne a une compréhension élémentaire de la langue parlée"@fr ;
+ rdfs:comment "De persoon kan eenvoudige gesproken taal begrijpen"@nl ;
+ rdfs:comment "その人はその話し言語について基礎的な理解力を有している"@ja ;
+ rdfs:comment "A pessoa tem um nível de compreensão básico do idioma falado"@pt ;
+ dcterms:replaces :hasAbility1 ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:basicSpeaking
+ a owl:ObjectProperty ;
+ rdfs:label "basic speaking"@en ;
+ rdfs:label "expresión oral básica"@es ;
+ rdfs:label "expression élémentaire"@fr ;
+ rdfs:label "basis spraakniveau"@nl ;
+ rdfs:label "基礎的な会話"@ja ;
+ rdfs:label "expressão oral básica"@pt ;
+ rdfs:comment "The person can speak the language at a basic level"@en ;
+ rdfs:comment "La persona puede hablar la lengua a un nivel básico"@es ;
+ rdfs:comment "La personne parle la langue à un niveau élémentaire"@fr ;
+ rdfs:comment "De persoon kan eenvoudige taal spreken"@nl ;
+ rdfs:comment "その人はその言語を基礎レベルで話すことができる"@ja ;
+ rdfs:comment "A pessoa consegue falar o idioma a um nível básico"@pt ;
+ dcterms:replaces :hasAbility1 ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:basicReading
+ a owl:ObjectProperty ;
+ rdfs:label "basic reading"@en ;
+ rdfs:label "lectura básica"@es ;
+ rdfs:label "lecture élémentaire"@fr ;
+ rdfs:label "basis leesniveau"@nl ;
+ rdfs:label "基礎的な読解"@ja ;
+ rdfs:label "leitura básica"@pt ;
+ rdfs:comment "The person can read the language at a basic level"@en ;
+ rdfs:comment "La persona puede leer la lengua a un nivel básico"@es ;
+ rdfs:comment "La personne lit la langue à un niveau élémentaire"@fr ;
+ rdfs:comment "De persoon kan eenvoudige taal lezen"@nl ;
+ rdfs:comment "その人はその言語を基礎レベルで読むことができる"@ja ;
+ rdfs:comment "A pessoa consegue ler o idioma a um nível básico"@pt ;
+ dcterms:replaces :hasAbility1 ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:basicWriting
+ a owl:ObjectProperty ;
+ rdfs:label "basic writing"@en ;
+ rdfs:label "escritura básica"@es ;
+ rdfs:label "écriture élémentaire"@fr ;
+ rdfs:label "basis schrijfniveau"@nl ;
+ rdfs:label "基礎的な記述"@ja ;
+ rdfs:label "escrita básica"@pt ;
+ rdfs:comment "The person can write the language at a basic level"@en ;
+ rdfs:comment "La persona puede escribir la lengua a un nivel básico"@es ;
+ rdfs:comment "La personne écrit la langue à un niveau élémentaire"@fr ;
+ rdfs:comment "De persoon kan eenvoudige taal schrijven"@nl ;
+ rdfs:comment "その人はその言語を基礎レベルで書くことができる"@ja ;
+ rdfs:comment "A pessoa consegue escrever o idioma a um nível básico"@pt ;
+ dcterms:replaces :hasAbility1 ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:intermediateUnderstanding
+ a owl:ObjectProperty ;
+ rdfs:label "intermediate understanding"@en ;
+ rdfs:label "comprensión intermedia"@es ;
+ rdfs:label "compréhension moyenne"@fr ;
+ rdfs:label "voertaal"@nl ;
+ rdfs:label "中級の理解"@ja ;
+ rdfs:label "compreensão intermédia"@pt ;
+ rdfs:comment "The person has an intermediate understanding of the spoken language"@en ;
+ rdfs:comment "La persona tiene un nivel intermedio de comprensión de la lengua hablada"@es ;
+ rdfs:comment "La personne a une compréhension moyenne de la langue parlée"@fr ;
+ rdfs:comment "De persoon begrijpt de gesproken taal op een gemiddeld niveau"@nl ;
+ rdfs:comment "その人はその話し言葉について中級レベルの理解力を有している"@ja ;
+ rdfs:comment "A pessoa possui um nível intermédio de compreensão do idioma falado"@pt ;
+ dcterms:replaces :hasAbility2 ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:intermediateSpeaking
+ a owl:ObjectProperty ;
+ rdfs:label "intermediate speaking"@en ;
+ rdfs:label "nivel oral intermedio"@es ;
+ rdfs:label "expression moyenne"@fr ;
+ rdfs:label "gemiddeld spraakniveau"@nl ;
+ rdfs:label "中級の会話"@ja ;
+ rdfs:label "nivel oral intermédio"@pt ;
+ rdfs:comment "The person can speak the language at an intermediate level"@en ;
+ rdfs:comment "La persona puede hablar la lengua a un nivel intermedio"@es ;
+ rdfs:comment "La personne parle la langue à un niveau moyen"@fr ;
+ rdfs:comment "De persoon spreekt de taal op een gemiddeld niveau"@nl ;
+ rdfs:comment "その人はその言語を中級レベルで話すことができる"@ja ;
+ rdfs:comment "A pessoa consegue falar o idioma a um nível intermédio"@pt ;
+ dcterms:replaces :hasAbility2 ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:intermediateReading
+ a owl:ObjectProperty ;
+ rdfs:label "intermediate reading"@en ;
+ rdfs:label "lecture moyenne"@fr ;
+ rdfs:label "nivel de lectura intermedio"@es ;
+ rdfs:label "gemiddeld leesniveau"@nl ;
+ rdfs:label "中級の読解"@ja ;
+ rdfs:label "leitura intermédia"@pt ;
+ rdfs:comment "The person can read the language at a intermediate level"@en ;
+ rdfs:comment "La persona puede leer la lengua a un nivel intermedio"@es ;
+ rdfs:comment "La personne lit la langue à un niveau moyen"@fr ;
+ rdfs:comment "De persoon leest de taal op een gemiddeld niveau"@nl ;
+ rdfs:comment "その人はその言語を中級レベルで読むことができる"@ja ;
+ rdfs:comment "A pessoa consegue ler o idioma a um nível intermédio"@pt ;
+ dcterms:replaces :hasAbility2 ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:intermediateWriting
+ a owl:ObjectProperty ;
+ rdfs:label "intermediate writing"@en ;
+ rdfs:label "nivel escrito intermedio"@es ;
+ rdfs:label "écriture moyenne"@fr ;
+ rdfs:label "gemiddeld schrijfniveau"@nl ;
+ rdfs:label "中級の記述"@ja ;
+ rdfs:label "escrita intermédia"@pt ;
+ rdfs:comment "The person can write the language at an intermediate level"@en ;
+ rdfs:comment "La persona puede escribir la lengua a un nivel intermedio"@es ;
+ rdfs:comment "La personne écrit la langue à un niveau moyen"@fr ;
+ rdfs:comment "De persoon schrijft de taal op een gemiddeld niveau"@nl ;
+ rdfs:comment "その人はその言語を中級レベルで書くことができる"@ja ;
+ rdfs:comment "A pessoa consegue escrever o idioma com um nível intermédio"@pt ;
+ dcterms:replaces :hasAbility2 ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:advancedUnderstanding
+ a owl:ObjectProperty ;
+ rdfs:label "advanced understanding"@en ;
+ rdfs:label "buena comprensión"@es ;
+ rdfs:label "bonne compréhension"@fr ;
+ rdfs:label "goed luisterniveau"@nl ;
+ rdfs:label "高度な理解"@ja ;
+ rdfs:label "compreensão avançada"@pt ;
+ rdfs:comment "The person has an advanced understanding of the spoken language"@en ;
+ rdfs:comment "La persona tiene un nivel avanzado de comprensión de la lengua hablada"@es ;
+ rdfs:comment "La personne a une bonne compréhension de la langue parlée"@fr ;
+ rdfs:comment "De persoon kan de gesproken taal goed begrijpen"@nl ;
+ rdfs:comment "その人はその話し言葉について高度な理解力を有している"@ja ;
+ rdfs:comment "A pessoa possui uma compreensão avançada do idioma falado"@pt ;
+ dcterms:replaces :hasAbility3 ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:advancedSpeaking
+ a owl:ObjectProperty ;
+ rdfs:label "advanced speaking"@en ;
+ rdfs:label "buena expresión oral"@es ;
+ rdfs:label "bonne expression"@fr ;
+ rdfs:label "goed spraakniveau"@nl ;
+ rdfs:label "高度な会話"@ja ;
+ rdfs:label "boa expressão oral"@pt ;
+ rdfs:comment "The person can speak the language at an advanced level"@en ;
+ rdfs:comment "La persona puede hablar la lengua a un nivel avanzado"@es ;
+ rdfs:comment "La personne parle la langue à un bon niveau"@fr ;
+ rdfs:comment "De persoon kan de taal goed spreken"@nl ;
+ rdfs:comment "その人はその言語を上級レベルで話すことができる"@ja ;
+ rdfs:comment "A pessoa consegue falar o idioma a um nível avançado"@pt ;
+ dcterms:replaces :hasAbility3 ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:advancedReading
+ a owl:ObjectProperty ;
+ rdfs:label "advanced reading"@en ;
+ rdfs:label "buen nivel de lectura"@es ;
+ rdfs:label "bon niveau de lecture"@fr ;
+ rdfs:label "goed leesniveau"@nl ;
+ rdfs:label "高度な読解"@ja ;
+ rdfs:label "leitura avançada"@pt ;
+ rdfs:comment "The person can read the language at an advanced level"@en ;
+ rdfs:comment "La persona puede leer la lengua a un nivel avanzado"@es ;
+ rdfs:comment "La personne lit la langue à un bon niveau"@fr ;
+ rdfs:comment "De persoon kan de taal goed lezen"@nl ;
+ rdfs:comment "その人はその言語を上級レベルで読むことができる"@ja ;
+ rdfs:comment "A pessoa consegue ler o idioma a um nível avançado"@pt ;
+ dcterms:replaces :hasAbility3 ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:advancedWriting
+ a owl:ObjectProperty ;
+ rdfs:label "advanced writing"@en ;
+ rdfs:label "buen nivel de escritura"@es ;
+ rdfs:label "bon niveau d'écriture"@fr ;
+ rdfs:label "goed schrijfniveau"@nl ;
+ rdfs:label "高度な記述"@ja ;
+ rdfs:label "escrita avançada"@pt ;
+ rdfs:comment "The person can write the language at an advanced level"@en ;
+ rdfs:comment "La persona puede escribir la lengua a un nivel avanzado"@es ;
+ rdfs:comment "La personne écrit la langue à un bon niveau"@fr ;
+ rdfs:comment "De persoon kan de taal goed schrijven"@nl ;
+ rdfs:comment "その人はその言語を上級レベルで書くことができる"@ja ;
+ rdfs:comment "A pessoa consegue escrever o idioma a um nível avançado"@pt ;
+ dcterms:replaces :hasAbility3 ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:expertUnderstanding
+ a owl:ObjectProperty ;
+ rdfs:label "expert understanding"@en ;
+ rdfs:label "comprensión excelente"@es ;
+ rdfs:label "excellente compréhension"@fr ;
+ rdfs:label "uitstekend luisterniveau"@nl ;
+ rdfs:label "専門家レベルの理解"@ja ;
+ rdfs:label "compreensão a um nível de especialista"@pt ;
+ rdfs:comment "The person has an expert understanding of the spoken language"@en ;
+ rdfs:comment "La persona tiene un nivel experto de comprensión de la lengua hablada"@es ;
+ rdfs:comment "La personne a une excellente compréhension de la langue parlée"@fr ;
+ rdfs:comment "De persoon kan de gesproken taal uitstekend begrijpen"@nl ;
+ rdfs:comment "その人はその話し言葉について専門家レベルの理解力を有している"@ja ;
+ rdfs:comment "A pessoa tem um nível de especialista do idioma falado"@pt ;
+ dcterms:replaces :hasAbility4 ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:expertSpeaking
+ a owl:ObjectProperty ;
+ rdfs:label "expert speaking"@en ;
+ rdfs:label "expresión oral excelente"@es ;
+ rdfs:label "excellente expression"@fr ;
+ rdfs:label "uitstekend spraakniveau"@nl ;
+ rdfs:label "専門家レベルの会話"@ja ;
+ rdfs:label "expressão oral a um nível de especialista"@pt ;
+ rdfs:comment "The person can speak the language at an expert level"@en ;
+ rdfs:comment "La persona puede hablar la lengua a un nivel experto"@es ;
+ rdfs:comment "La personne parle la langue à niveau excellent"@fr ;
+ rdfs:comment "De persoon kan de taal uitstekend spreken"@nl ;
+ rdfs:comment "その人はその言語を専門家レベルで話すことができる"@ja ;
+ rdfs:comment "A pessoa consegue falar o idioma a um nível de especialista"@pt ;
+ dcterms:replaces :hasAbility4 ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:expertReading
+ a owl:ObjectProperty ;
+ rdfs:label "expert reading"@en ;
+ rdfs:label "nivel de lectura excelente"@es ;
+ rdfs:label "excellente lecture"@fr ;
+ rdfs:label "uitstekend leesniveau"@nl ;
+ rdfs:label "専門家レベルの読解"@ja ;
+ rdfs:label "leitura a um nível de especialista"@pt ;
+ rdfs:comment "The person can read the language at a expert level"@en ;
+ rdfs:comment "La persona puede leer en la lengua a un nivel experto"@es ;
+ rdfs:comment "La personne lit la langue à un niveau excellent"@fr ;
+ rdfs:comment "De persoon kan de taal uitstekend lezen"@nl ;
+ rdfs:comment "その人はその言語を専門家レベルで読むことができる"@ja ;
+ dcterms:replaces :hasAbility4;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:expertWriting
+ a owl:ObjectProperty ;
+ rdfs:label "expert writing"@en ;
+ rdfs:label "nivel de escritura excelente"@es ;
+ rdfs:label "excellente écriture"@fr ;
+ rdfs:label "uitstekend schrijfniveau"@nl ;
+ rdfs:label "専門家レベルの記述"@ja ;
+ rdfs:label "escrita a um nível de especialista"@pt ;
+ rdfs:comment "The person can write the language at an expert level"@en ;
+ rdfs:comment "La persona puede escribir la lengua a un nivel experto"@es ;
+ rdfs:comment "La personne écrit la langue à un niveau excellent"@fr ;
+ rdfs:comment "De persoon kan de taal uitstekend schrijven"@nl ;
+ rdfs:comment "その人はその言語を専門家レベルで書くことができる"@ja ;
+ rdfs:comment "A pessoa consegue escrever o idioma a um nível de especialista"@pt ;
+ dcterms:replaces :hasAbility4 ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+:nativeLanguage
+ a owl:ObjectProperty ;
+ rdfs:label "native language"@en ;
+ rdfs:label "母国語"@ja ;
+ rdfs:label "lengua materna"@es ;
+ rdfs:label "langue maternelle"@fr ;
+ rdfs:label "moedertaal"@nl ;
+ rdfs:label "idioma mãe"@pt ;
+ rdfs:comment "This property is independent of the level of fluency, reading or writing ability"@en ;
+ rdfs:comment "Esta propiedad es independiente de el nivel de fluidez o de las habilidades de lectura o escritura"@es ;
+ rdfs:comment "Cette propriété est indépendante du niveau de langue parlée, lue ou écrite"@fr ;
+ rdfs:comment "Deze eigenschap is onafhankelijk van het niveau van spreken, lezen of schrijven"@nl ;
+ rdfs:comment "このプロパティーは、流暢さ、読解力、記述能力のレベルに依存しない"@ja ;
+ rdfs:comment "Esta propriedade é independente do nível de fluência, de leitura ou de escrita"@pt ;
+ dcterms:replaces :hasNativeLanguage ;
+ rdfs:range :Lingvo ;
+ rdfs:domain foaf:Person .
+
+### Properties describing the use of languages by various entities ###
+
+:communicationLanguage
+ a owl:ObjectProperty ;
+ rdfs:label "communication language"@en ;
+ rdfs:label "lenguaje de comunicación"@es ;
+ rdfs:label "langue de communication"@fr ;
+ rdfs:label "kommunikation taal"@nl ;
+ rdfs:label "コミュニケーション言語"@ja ;
+ rdfs:label "idioma de comunicação"@pt ;
+ rdfs:comment "A language used for external communication"@en ;
+ rdfs:comment "Una lengua utilizada para la comunicación externa"@es ;
+ rdfs:comment "Une langue utilisée pour la communication externe"@fr ;
+ rdfs:comment "Een taal gebruikt voor externe communicatie"@nl ;
+ rdfs:comment "外部とのコミュニケーションに用いる言語"@ja ;
+ rdfs:comment "Um idioma utilizado para a comunicação externa"@pt ;
+ dcterms:replaces :hasCommunicationLanguage;
+ rdfs:range :Lingvo ;
+ olca:domainIncludes foaf:Organization;
+ olca:domainIncludes foaf:Project.
+
+:workingLanguage
+ a owl:ObjectProperty ;
+ rdfs:label "working language"@en ;
+ rdfs:label "lenguaje de trabajo"@es ;
+ rdfs:label "langue de travail"@fr ;
+ rdfs:label "werktaal"@nl ;
+ rdfs:label "実用言語"@ja ;
+ rdfs:label "idioma de trabalho"@pt ;
+ rdfs:comment "A language the project or organization uses for internal communication"@en ;
+ rdfs:comment "Una lengua que el proyecto o la organización utiliza para comunicación interna"@es ;
+ rdfs:comment "Une langue utilisée par l'organisation ou le projet pour sa communication interne"@fr ;
+ rdfs:comment "De taal gebruikt voor interne communicatie door een organisatie of binnen een project"@nl ;
+ rdfs:comment "プロジェクトや組織が内部コミュニケーションに用いる言語"@ja ;
+ rdfs:comment "O idioma que o projecto ou organização usa para a comunicação interna"@pt ;
+ dcterms:replaces :hasWorkingLanguage ;
+ rdfs:range :Lingvo ;
+ olca:domainIncludes foaf:Organization ;
+ olca:domainIncludes foaf:Project.
+
+:officialLanguage
+ a owl:ObjectProperty ;
+ rdfs:label "official language"@en ;
+ rdfs:label "lengua oficial"@es ;
+ rdfs:label "langue officielle"@fr ;
+ rdfs:label "officiële taal"@nl ;
+ rdfs:label "公用語"@ja ;
+ rdfs:label "idioma oficial"@pt ;
+ rdfs:comment "An official language of a country, project, organization or event"@en ;
+ rdfs:comment "Una lengua oficial en un país, proyecto, organización o evento"@es ;
+ rdfs:comment "Une langue officielle d'un pays, d'une organisation, d'un projet ou d'un événement"@fr ;
+ rdfs:comment "De officiële taal van een land, organisatie, prject of evenement"@nl ;
+ rdfs:comment "国、プロジェクト、組織やイベントの公用語"@ja ;
+ rdfs:comment "Um idioma oficial de um país, projecto, organização ou evento"@pt ;
+ rdfs:range :Lingvo ;
+ owl:inverseOf :officialIn ;
+ olca:similarProperty <http://www.telegraphis.net/ontology/geography/geography#officialLanguage>;
+ olca:domainIncludes foaf:Organization;
+ olca:domainIncludes foaf:Project;
+ olca:domainIncludes lode:Event;
+ olca:domainIncludes schema:Place.
+
+:officialIn
+ a owl:ObjectProperty ;
+ rdfs:label "official language of"@en ;
+ rdfs:label "lengua oficial de"@es ;
+ rdfs:label "langue officielle de"@fr ;
+ rdfs:label "officiële taal"@nl;
+ rdfs:label "~の公用語"@ja ;
+ rdfs:label "idioma oficial de"@pt ;
+ rdfs:domain :Lingvo ;
+ owl:inverseOf :officialLanguage ;
+ olca:rangeIncludes foaf:Organization;
+ olca:rangeIncludes foaf:Project;
+ olca:rangeIncludes lode:Event;
+ olca:rangeIncludes schema:Place.
+
+:spokenLanguage
+ a owl:ObjectProperty ;
+ rdfs:label "spoken language"@en ;
+ rdfs:label "lengua hablada"@es ;
+ rdfs:label "langue parlée"@fr ;
+ rdfs:label "gesproken taal"@nl ;
+ rdfs:label "話し言葉"@ja ;
+ rdfs:label "idioma falado"@pt ;
+ rdfs:comment "A language which is spoken in some place or event"@en ;
+ rdfs:comment "Una lengua que se habla en algún lugar o evento"@es ;
+ rdfs:comment "Une langue parlée dans un lieu ou lors d'un événement"@fr ;
+ rdfs:comment "Een taal gesproken op een bepaalde plek of tijdens een evenement"@nl ;
+ rdfs:comment "ある場所やイベントで話される言語"@ja ;
+ rdfs:comment "O idioma que é falado num determinado lugar ou evento"@pt ;
+ rdfs:range :Lingvo ;
+ olca:domainIncludes foaf:Organization;
+ olca:domainIncludes foaf:Project;
+ olca:domainIncludes lode:Event;
+ olca:domainIncludes schema:Place.
+
+:fromCountry
+ a owl:ObjectProperty ;
+ rdfs:label "from country"@en ;
+ rdfs:label "país de origen"@es ;
+ rdfs:label "pays d'origine"@fr ;
+ rdfs:label "land van herkomst"@nl ;
+ rdfs:label "起源の国"@ja ;
+ rdfs:label "do país"@pt ;
+ rdfs:comment "Country of origin of the language"@en ;
+ rdfs:comment "País de origen de la lengua"@es ;
+ rdfs:comment "Pays d'origine de la langue"@fr ;
+ rdfs:comment "Land van herkomst van de taal"@nl ;
+ rdfs:comment "言語の起源の国"@ja ;
+ rdfs:comment "País de origem do idioma"@pt ;
+ rdfs:domain :Lingvo ;
+ rdfs:range schema:Country.
+
+:mainLanguage
+ a owl:ObjectProperty ;
+ rdfs:label "main language"@en ;
+ rdfs:label "lengua principal"@es ;
+ rdfs:label "langue principale"@fr ;
+ rdfs:label "hoofdtaal"@nl ;
+ rdfs:label "主要言語"@ja ;
+ rdfs:label "Idioma principal"@pt ;
+ rdfs:comment "The main language used in the place or language resource "@en ;
+ rdfs:comment "Una lengua ampliamente hablada en un lugar (país, región, ciudad...)"@es ;
+ rdfs:comment "La langue principale utilisée dans le lieu ou la ressource linguistique"@fr ;
+ rdfs:comment "De meest gebruikte taal op deze plek (land, regio, stad ...)"@nl ;
+ rdfs:comment "その場所または言語資源で用いられる主要言語"@ja ;
+ rdfs:comment "O idioma principal utilizado num local ou recurso linguístico"@pt ;
+ rdfs:range :Lingvo ;
+ olca:domainIncludes schema:Place;
+ olca:domainIncludes :LanguageResource.
+
+:regionalLanguage
+ a owl:ObjectProperty ;
+ rdfs:label "regional language"@en ;
+ rdfs:label "lengua regional"@es ;
+ rdfs:label "langue régionale"@fr ;
+ rdfs:label "streektaal"@nl ;
+ rdfs:label "地方言語"@ja ;
+ rdfs:label "idioma regional"@pt ;
+ rdfs:comment "A language spoken in a region of a country"@en ;
+ rdfs:comment "Una lengua hablada en una región o un país"@es ;
+ rdfs:comment "Une langue parlée dans une région d'un pays"@fr ;
+ rdfs:comment "Een taal gesproken in bepaalde streek van een land"@nl ;
+ rdfs:comment "ある国のある地域で話される言語"@ja ;
+ rdfs:comment "Um idioma falado num região de um país"@pt ;
+ rdfs:range :Lingvo ;
+ olca:domainIncludes schema:Country.
+
+:minorityLanguage
+ a owl:ObjectProperty ;
+ rdfs:label "minority language"@en ;
+ rdfs:label "lengua minoritaria"@es ;
+ rdfs:label "langue minoritaire"@fr ;
+ rdfs:label "minderheidstaal"@nl ;
+ rdfs:label "少数言語"@ja ;
+ rdfs:label "idioma minoritário"@pt ;
+ rdfs:comment "A language spoken by a minority in some country, but not necessarily in a specific region"@en ;
+ rdfs:comment "Un lengua hablada por una minoría en algún país, pero no necesariamente en una región específica"@es ;
+ rdfs:comment "Une langue parlée par une minorité dans un pays, mais pas nécessairement dans une région spécifique"@fr ;
+ rdfs:comment "Een taal die door een minderheid van de bevolking van een land gesproken wordt, maar niet noodzakelijkerwijs in een specifieke regio"@nl ;
+ rdfs:comment "ある国の少数の人々(必ずしも特定地域ではない)が話す言語"@ja ;
+ rdfs:comment "O idioma falado por uma minoria num país, mas não necessariamente numa região específica"@pt ;
+ rdfs:range :Lingvo ;
+ olca:domainIncludes schema:Country.
+
+:historicalLanguage
+ a owl:ObjectProperty ;
+ rdfs:label "historical language"@en ;
+ rdfs:label "lengua histórica"@es ;
+ rdfs:label "langue historique"@fr ;
+ rdfs:label "historische taal"@nl ;
+ rdfs:label "歴史的言語"@ja ;
+ rdfs:label "idioma histórico"@pt ;
+ rdfs:comment "A language spoken in the past in this place, but not used anymore"@en ;
+ rdfs:comment "Una lengua hablada en el pasado en este lugar, pero ya no se utiliza"@es ;
+ rdfs:comment "Une langue parlée dans le passé dans ce lieu, mais plus utilisée aujourd'hui"@fr ;
+ rdfs:comment "Een taal die vroeger in dit gebied gesproken werd, maar wordt nu niet meer gebruikt"@nl ;
+ rdfs:comment "この場所で過去に話されていたが、もはや用いられていない言語"@ja ;
+ rdfs:comment "Um idioma falado no passado num determinado lugar, não sendo já utilizado no presente"@pt ;
+ rdfs:range :Lingvo ;
+ olca:domainIncludes schema:Place.
+
+### Class and properties used to document the translation of a resource ###
+
+:Translation
+ a owl:Class ;
+ rdfs:label "Translation"@en ;
+ rdfs:label "Traducción"@es ;
+ rdfs:label "Traduction"@fr ;
+ rdfs:label "Vertaling"@nl ;
+ rdfs:label "翻訳"@ja ;
+ rdfs:label "Tradução"@pt ;
+ rdfs:comment "Description of a Translation should include original resource, translated resource, original language and target language. It might also include translator(s) and translation date, and relevant other information using properties inherited from the generic Event class"@en ;
+ rdfs:comment "La descripción de una Traducción debe incluir la fuente original, la fuente traducida, la lengua original y la lengua de destino. También puede incluir el o los traductor(es) , la fecha de traducción y otra información relevante utilizando propiedades heredadas de la clase generica Event"@es ;
+ rdfs:comment "La description d'une Traduction inclut au minimum la ressource originale, la ressource traduite, la langue d'origine et la langue cible. Elle peut aussi inclure le(s) traducteur(s), la date de traduction, et toute autre information pertinente utilisant les propriétés de la classe générique Evénement"@fr ;
+ rdfs:comment "De beschrijving of een vertaling zou de oorspronkelijke bron, de vertaalde bron, de brontaal en de doeltaal moeten bevatten. Het kan ook de vertaler(s), de vertaaldatum en andere relevante informatie, gebruik makend van de eigenschappen geërfd van de generieke Event klasse, bevatten"@nl ;
+ rdfs:comment "Translation(翻訳)の記述には、元の資源、翻訳後の資源、元の言語および翻訳先の言語が含まれているべきである。さらに、それには、翻訳者と翻訳日、そして、汎用的なEventクラスから継承されたプロパティーを用いた、関連するその他の情報が含まれるかもしれない"@ja ;
+ rdfs:comment "Descrição de uma tradução deverá inclrui o recurso original, o recurso traduzido, o idioma original e o idioma de destino. Também pode incluir o(s)/a(s) tradutore(s)/tradutora(s), a data de tradução e outra informação relevante utilizando propriedades herdadas da classe genérica Event"@pt ;
+ rdfs:subClassOf lode:Event;
+ olca:expectedProperty dcterms:date;
+ vann:example <http://www.lingvoj.org/translations/w3c-recs.rdf#translation-css1-en-to-bg>.
+
+:originalLanguage
+ a owl:ObjectProperty ;
+ rdfs:label "original language"@en ;
+ rdfs:label "lengua original"@es ;
+ rdfs:label "langue d'origine"@fr ;
+ rdfs:label "oorspronkelijke taal"@nl ;
+ rdfs:label "元の言語"@ja ;
+ rdfs:label "idioma original"@pt ;
+ rdfs:comment "The language of the original ressource"@en ;
+ rdfs:comment "La langue de la ressource originale"@fr ;
+ rdfs:comment "De taal van de de bron"@nl ;
+ rdfs:comment "La lengua de la fuente original"@es ;
+ rdfs:comment "元の資源の言語"@ja ;
+ rdfs:comment "O idioma do recurso original"@pt ;
+ rdfs:range :Lingvo ;
+ rdfs:domain :Translation .
+
+:targetLanguage
+ a owl:ObjectProperty ;
+ rdfs:label "target language"@en ;
+ rdfs:label "lengua destino"@es ;
+ rdfs:label "langue cible"@fr ;
+ rdfs:label "doeltaal"@nl ;
+ rdfs:label "翻訳先の言語"@ja ;
+ rdfs:label "idioma destino"@pt ;
+ rdfs:comment "The language of the translated ressource"@en ;
+ rdfs:comment "La lengua de la fuente traducida"@es ;
+ rdfs:comment "La langue de la ressource traduite"@fr ;
+ rdfs:comment "De taal waarin de bron vertaald is"@nl ;
+ rdfs:comment "翻訳後の資源の言語"@ja ;
+ rdfs:comment "O idioma do recurso traduzido"@pt ;
+ rdfs:range :Lingvo ;
+ rdfs:domain :Translation .
+
+:originalResource
+ a owl:ObjectProperty ;
+ rdfs:label "original resource"@en ;
+ rdfs:label "recurso original"@es ;
+ rdfs:label "ressource originale"@fr ;
+ rdfs:label "oorspronkelijke bron"@nl ;
+ rdfs:label "元の資源"@ja ;
+ rdfs:label "recurso original"@pt ;
+ rdfs:comment "The resource which is translated"@en ;
+ rdfs:comment "La fuente que se traduce"@es ;
+ rdfs:comment "La ressource qui est traduite"@fr ;
+ rdfs:comment "De vertaalde bron"@nl ;
+ rdfs:comment "翻訳元の資源"@ja ;
+ rdfs:comment "o recurso que se traduz"@pt ;
+ rdfs:domain :Translation .
+
+:translatedResource
+ a owl:ObjectProperty ;
+ rdfs:label "translated resource"@en ;
+ rdfs:label "recurso traducido"@es ;
+ rdfs:label "ressource traduite"@fr ;
+ rdfs:label "vertaalde bron"@nl ;
+ rdfs:label "翻訳後の資源"@ja ;
+ rdfs:label "recurso traduzido"@pt ;
+ rdfs:comment "The resource which is the result of the translation"@en ;
+ rdfs:comment "La fuente que resulta de la traducción"@es ;
+ rdfs:comment "La ressource qui est le résultat de la traduction"@fr ;
+ rdfs:comment "Het resultaat van de vertaling"@nl ;
+ rdfs:comment "翻訳の結果である資源"@ja ;
+ rdfs:comment "O recurso que é o resultado da tradução"@pt ;
+ rdfs:domain :Translation .
+
+:translator
+ a owl:ObjectProperty ;
+ rdfs:label "translator"@en ;
+ rdfs:label "traductor"@es ;
+ rdfs:label "traducteur"@fr ;
+ rdfs:label "vertaler"@nl ;
+ rdfs:label "翻訳者"@ja ;
+ rdfs:label "tradutor"@pt ;
+ rdfs:comment "An agent (person, organization or sofware) responsible of the translation"@en ;
+ rdfs:comment "Un agente (persona, organización o software) responsable de la traducción"@es ;
+ rdfs:comment "Un agent (personne, organisation ou logiciel) responsable de la traduction"@fr ;
+ rdfs:comment "De agent (persoon, organisatie of applicatie) verantwoordelijk voor de vertaling"@nl ;
+ rdfs:comment "翻訳に責任を持つエージェント(人、組織またはソフトウェア)"@ja ;
+ rdfs:comment "um agente (pessoa, organização ou programa) responsável pela tradução"@pt ;
+ rdfs:domain :Translation ;
+ rdfs:range foaf:Agent.
+
+:interpreter
+ a owl:ObjectProperty ;
+ rdfs:label "interpreter"@en ;
+ rdfs:label "intérprete"@es ;
+ rdfs:label "interprète"@fr ;
+ rdfs:label "tolk"@nl ;
+ rdfs:label "通訳者"@ja ;
+ rdfs:label "interprete"@pt ;
+ rdfs:comment "An agent (person or software) responsible of a real-time oral translation"@en ;
+ rdfs:comment "Un agente (persona, organización o software) responsable de la interpretación oral"@es ;
+ rdfs:comment "Un agent (personne ou logiciel) responsable de la traduction orale en temps réel"@fr ;
+ rdfs:comment "De agent (persoon of applicatie) verantwoordelijk voor het tolken"@nl ;
+ rdfs:comment "即時の通訳に責任を持つエージェント(人またはソフトウェア)"@ja ;
+ rdfs:comment "Um agente (pessoa ou programa) responsável por uma tradução oral em tempo real"@pt ;
+ rdfs:subPropertyOf :translator ;
+ rdfs:domain :Translation ;
+ rdfs:range foaf:Agent.
+
+### Language resources ###
+
+:LanguageResource
+ a owl:Class ;
+ rdfs:label "Language resource"@en ;
+ rdfs:label "Recurso lingüístico"@es ;
+ rdfs:label "Ressource linguistique"@fr ;
+ rdfs:label "Taal bron"@nl ;
+ rdfs:label "言語資源"@ja ;
+ rdfs:label "Recurso linguístico"@pt ;
+ rdfs:comment "Dictionaries, thesauri, language courses, translation services, etc."@en ;
+ rdfs:comment "Dictionnaires, thesaurus, cours de langue, services de traduction, etc."@fr ;
+ rdfs:comment "Woordenboeken, thesauri, taalcursussen, vertaaldiensten, etc."@nl ;
+ rdfs:comment "Diccionarios, tesauros, cursos de idiomas, servicios de traducción, etc."@es ;
+ rdfs:comment "辞書、シソーラス、言語コース、翻訳サービスなど"@ja ;
+ rdfs:comment "Dicionários, tesauros, cursos de idiomas, serviços de tradução, etc."@pt ;
+ rdfs:seeAlso <http://www.language-archives.org/documents/faq.html#2>.
+
+:resourceType
+ a owl:ObjectProperty ;
+ rdfs:label "resource type"@en ;
+ rdfs:label "tipo de recurso"@es ;
+ rdfs:label "type de ressource"@fr ;
+ rdfs:label "bron type"@nl ;
+ rdfs:label "資源の種類"@ja ;
+ rdfs:label "tipo de recurso"@pt ;
+ rdfs:comment "A concept defining the type of the language resource"@en ;
+ rdfs:comment "Un concepto que define el tipo de recurso lingüístico"@es ;
+ rdfs:comment "Un concept définissant le type de la ressource linguistique"@fr ;
+ rdfs:comment "Een concept van het definiëren van de aard van de taal bron"@nl ;
+ rdfs:comment "言語資源の種類を定義する概念"@ja ;
+ rdfs:comment "Um conceito que define o tipo de recuso linguístico"@pt ;
+ rdfs:domain :LanguageResource ;
+ rdfs:range skos:Concept.
+
+:supportedLanguage
+ a owl:ObjectProperty ;
+ rdfs:label "supported language"@en ;
+ rdfs:label "idioma soportado"@es ;
+ rdfs:label "langue supportée"@fr ;
+ rdfs:label "ondersteunde taal"@nl ;
+ rdfs:label "サポートされている言語 "@ja ;
+ rdfs:label "idioma suportado"@pt ;
+ rdfs:comment "A language supported by the language resource"@en ;
+ rdfs:comment "Un idioma soportado por el recurso lingüístico"@es ;
+ rdfs:comment "Une langue supportée par la ressource linguistique"@fr ;
+ rdfs:comment "Een taal die wordt ondersteund door de taal bron"@nl ;
+ rdfs:comment "言語資源でサポートされている言語"@ja ;
+ rdfs:comment "Um idioma suportado pelo recurso linguístico"@pt ;
+ rdfs:domain :LanguageResource ;
+ rdfs:range :Lingvo.
+
+:supportingResource
+ a owl:ObjectProperty ;
+ rdfs:label "support resource"@en ;
+ rdfs:label "recurso soportado"@es ;
+ rdfs:label "ressource support"@fr ;
+ rdfs:label "ondersteunende bron"@nl ;
+ rdfs:label "サポート資源"@ja ;
+ rdfs:label "recurso suportado"@pt ;
+ rdfs:comment "A language resource for this language"@en ;
+ rdfs:comment "Un recurso lingüístico para este idioma"@es ;
+ rdfs:comment "Une ressource linguistique pour cette langue"@fr ;
+ rdfs:comment "Een taal bron voor deze taal"@nl ;
+ rdfs:comment "この言語の言語資源"@ja ;
+ rdfs:comment "Um recurso linguístico para este idioma"@pt ;
+ owl:inverseOf :supportedLanguage ;
+ rdfs:domain :Lingvo ;
+ rdfs:range :LanguageResource.
+
+### Deprecated properties ###
+
+### Properties defining ISO codes defined in versions prior to 2.0 are deprecated. Use those defined by lexvo.org instead ###
+
+:iso1
+ rdfs:isDefinedBy <http://www.lingvoj.org/ontology_v1.3.rdf> ;
+ owl:deprecated "true"^^xsd:boolean;
+ dcterms:isReplacedBy <http://lexvo.org/ontology#iso639P1Code>.
+
+:iso2b
+ rdfs:isDefinedBy <http://www.lingvoj.org/ontology_v1.3.rdf> ;
+ owl:deprecated "true"^^xsd:boolean;
+ dcterms:isReplacedBy <http://lexvo.org/ontology#iso639P2BCode>.
+
+:iso2t
+ rdfs:isDefinedBy <http://www.lingvoj.org/ontology_v1.3.rdf> ;
+ owl:deprecated "true"^^xsd:boolean;
+ dcterms:isReplacedBy <http://lexvo.org/ontology#iso639P2TCode>.
+
+:iso3
+ rdfs:isDefinedBy <http://www.lingvoj.org/ontology_v1.3.rdf> ;
+ owl:deprecated "true"^^xsd:boolean;
+ dcterms:isReplacedBy <http://lexvo.org/ontology#iso639P3Code>.
+
+### Properties describing language level of a person, replaced by more specific ones ###
+
+:hasAbility1
+ rdfs:isDefinedBy <http://www.lingvoj.org/ontology_v1.3.rdf> ;
+ owl:deprecated "true"^^xsd:boolean;
+ dcterms:isReplacedBy :basicUnderstanding, :basicSpeaking, :basicReading, :basicWriting.
+
+:hasAbility2
+ rdfs:isDefinedBy <http://www.lingvoj.org/ontology_v1.3.rdf> ;
+ owl:deprecated "true"^^xsd:boolean;
+ dcterms:isReplacedBy :intermediateUnderstanding, :intermediateSpeaking, :intermediateReading, :intermediateWriting.
+
+:hasAbility3
+ rdfs:isDefinedBy <http://www.lingvoj.org/ontology_v1.3.rdf> ;
+ owl:deprecated "true"^^xsd:boolean;
+ dcterms:isReplacedBy :advancedUnderstanding, :advancedSpeaking, :advancedReading, :advancedWriting.
+
+:hasAbility4
+ rdfs:isDefinedBy <http://www.lingvoj.org/ontology_v1.3.rdf> ;
+ owl:deprecated "true"^^xsd:boolean;
+ dcterms:isReplacedBy :expertUnderstanding, :expertSpeaking, :expertReading, :expertWriting.
+
+:hasAbility5
+ rdfs:isDefinedBy <http://www.lingvoj.org/ontology_v1.3.rdf> ;
+ owl:deprecated "true"^^xsd:boolean.
+
+### Change of URIs to meet best practice - trimming the initial "has" ###
+
+:hasNativeLanguage
+ rdfs:isDefinedBy <http://www.lingvoj.org/ontology_v1.3.rdf> ;
+ owl:deprecated "true"^^xsd:boolean;
+ dcterms:isReplacedBy :nativeLanguage.
+
+:hasCommunicationLanguage
+ rdfs:isDefinedBy <http://www.lingvoj.org/ontology_v1.3.rdf> ;
+ owl:deprecated "true"^^xsd:boolean;
+ dcterms:isReplacedBy :communicationLanguage.
+
+:hasWorkingLanguage
+ rdfs:isDefinedBy <http://www.lingvoj.org/ontology_v1.3.rdf> ;
+ owl:deprecated "true"^^xsd:boolean;
+ dcterms:isReplacedBy :workingLanguage.
+
+### Deprecated properties for the Translation class ###
+
+:original_resource
+ rdfs:isDefinedBy <http://www.lingvoj.org/ontology_v1.3.rdf> ;
+ owl:deprecated "true"^^xsd:boolean;
+ dcterms:isReplacedBy :originalResource.
+
+:originalTitle
+ rdfs:isDefinedBy <http://www.lingvoj.org/ontology_v1.3.rdf> ;
+ owl:deprecated "true"^^xsd:boolean;
+ rdfs:comment "The original title is a property of the original resource (use dcterms:title) and not a property of the Translation itself"@en;
+ rdfs:comment "Le titre original est une propriété de la ressource originale (utiliser dcterms:title) et non une propriété de la Traduction elle-même"@fr;
+ rdfs:comment "原タイトルは、Translation(翻訳)自体のプロパティーではなく、元の資源のプロパティー(dcterms:titleを使用)"@ja.
+
+:translatedTitle
+ rdfs:isDefinedBy <http://www.lingvoj.org/ontology_v1.3.rdf> ;
+ owl:deprecated "true"^^xsd:boolean;
+ rdfs:comment "The translated title is a property of the translated resource (use dcterms:title) and not a property of the Translation itself"@en;
+ rdfs:comment "Le titre traduit est une propriété de la ressource traduite (utiliser dcterms:title) et non une propriété de la Traduction elle-même"@fr;
+ rdfs:comment "翻訳タイトルは、Translation(翻訳)自体のプロパティーではなく、翻訳された資源のプロパティー(dcterms:titleを使用)"@ja.
diff --git a/doc/examples/pub-key-no-iri.ttl b/doc/examples/pub-key-no-iri.ttl new file mode 100644 index 0000000..b072799 --- /dev/null +++ b/doc/examples/pub-key-no-iri.ttl @@ -0,0 +1,10 @@ +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . +@prefix signify: <urn:blake2b:YJP3KTOL7ZJW5JNIOMTSR4PB4H55ANXKC2AQOBVKSOYEKG5HKNTA> . +@prefix dcterms: <http://purl.org/dc/terms/>. + +<> + a signify:PublicKey ; + rdf:value "PSmong1yo6WCrNRi+Qrqfp6XoD5vHeKh31QxptEdDx0="^^xsd:base64Binary ; + dcterms:created "2020-06-08"^^xsd:date ; + dcterms:description "A public key I created as an example." . diff --git a/doc/examples/pub-key.ttl b/doc/examples/pub-key.ttl new file mode 100644 index 0000000..6880408 --- /dev/null +++ b/doc/examples/pub-key.ttl @@ -0,0 +1,10 @@ +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . +@prefix signify: <urn:blake2b:YJP3KTOL7ZJW5JNIOMTSR4PB4H55ANXKC2AQOBVKSOYEKG5HKNTA> . +@prefix dcterms: <http://purl.org/dc/terms/>. + +<urn:blake2b:MV7FAV6EI7M6RX6LBYS2KDT6GHIV54THO4QBKN7FQKVYB6GTMP5A> + a signify:PublicKey ; + rdf:value "PSmong1yo6WCrNRi+Qrqfp6XoD5vHeKh31QxptEdDx0="^^xsd:base64Binary ; + dcterms:created "2020-06-08"^^xsd:date ; + dcterms:description "A public key I created as an example." . diff --git a/doc/examples/sec-key-no-iri.ttl b/doc/examples/sec-key-no-iri.ttl new file mode 100644 index 0000000..fc3c97b --- /dev/null +++ b/doc/examples/sec-key-no-iri.ttl @@ -0,0 +1,8 @@ +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . +@prefix signify: <urn:blake2b:YJP3KTOL7ZJW5JNIOMTSR4PB4H55ANXKC2AQOBVKSOYEKG5HKNTA> . + +<> + a signify:SecretKey ; + rdf:value "YHSjgbH1p94vUw/6y1Cd618jep3jKNLV1rfK1ur7u0s9KaieDXKjpYKs1GL5Cup+npegPm8d4qHfVDGm0R0PHQ=="^^xsd:base64Binary ; + signify:publicKey <urn:blake2b:MV7FAV6EI7M6RX6LBYS2KDT6GHIV54THO4QBKN7FQKVYB6GTMP5A> . diff --git a/doc/examples/sec-key.ttl b/doc/examples/sec-key.ttl new file mode 100644 index 0000000..29876ab --- /dev/null +++ b/doc/examples/sec-key.ttl @@ -0,0 +1,8 @@ +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . +@prefix signify: <urn:blake2b:YJP3KTOL7ZJW5JNIOMTSR4PB4H55ANXKC2AQOBVKSOYEKG5HKNTA> . + +<urn:blake2b:6FMYHCWYWLTVK34T7HVS7KWE6DQZD7PQTFLM6Y6WBSBDZEJFPLZQ> + a signify:SecretKey ; + rdf:value "YHSjgbH1p94vUw/6y1Cd618jep3jKNLV1rfK1ur7u0s9KaieDXKjpYKs1GL5Cup+npegPm8d4qHfVDGm0R0PHQ=="^^xsd:base64Binary ; + signify:publicKey <urn:blake2b:MV7FAV6EI7M6RX6LBYS2KDT6GHIV54THO4QBKN7FQKVYB6GTMP5A> . diff --git a/doc/examples/sig-no-iri.ttl b/doc/examples/sig-no-iri.ttl new file mode 100644 index 0000000..1ba0a94 --- /dev/null +++ b/doc/examples/sig-no-iri.ttl @@ -0,0 +1,9 @@ +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . +@prefix signify: <urn:blake2b:YJP3KTOL7ZJW5JNIOMTSR4PB4H55ANXKC2AQOBVKSOYEKG5HKNTA> . + +<> + a signify:Signature ; + signify:message <urn:blake2b:FBRTEWJUSPW2EDMMITZKWAB5TDBOVT2VOLWWIRUFZFBR72YADB2Q> ; + rdf:value "13F7cubffmND/8wN+90zWyTiZiEoXWj5D8k61GFswP50ndGG3gLqgkaqwl/ahP/c8UvqXuX3vlTHdXUtXaOBDA=="^^xsd:base64Binary ; + signify:publicKey <urn:blake2b:MV7FAV6EI7M6RX6LBYS2KDT6GHIV54THO4QBKN7FQKVYB6GTMP5A> . diff --git a/doc/images/data-blocks.svg b/doc/images/data-blocks.svg new file mode 100644 index 0000000..a0cc95c --- /dev/null +++ b/doc/images/data-blocks.svg @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.42.3 (20191010.1750) + --> +<!-- Title: %3 Pages: 1 --> +<svg width="710pt" height="76pt" + viewBox="0.00 0.00 710.00 76.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 72)"> +<title>%3</title> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-72 706,-72 706,4 -4,4"/> +<g id="clust1" class="cluster"> +<title>cluster__level_0</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="8,-8 8,-60 694,-60 694,-8 8,-8"/> +</g> +<!-- block_7 --> +<g id="node1" class="node"> +<title>block_7</title> +<polygon fill="lightblue" stroke="lightblue" points="686,-52 618,-52 618,-16 686,-16 686,-52"/> +<text text-anchor="middle" x="652" y="-30.3" font-family="Times,serif" font-size="14.00">block-7</text> +</g> +<!-- block_6 --> +<g id="node2" class="node"> +<title>block_6</title> +<polygon fill="lightblue" stroke="lightblue" points="600,-52 532,-52 532,-16 600,-16 600,-52"/> +<text text-anchor="middle" x="566" y="-30.3" font-family="Times,serif" font-size="14.00">block-6</text> +</g> +<!-- block_5 --> +<g id="node3" class="node"> +<title>block_5</title> +<polygon fill="lightblue" stroke="lightblue" points="514,-52 446,-52 446,-16 514,-16 514,-52"/> +<text text-anchor="middle" x="480" y="-30.3" font-family="Times,serif" font-size="14.00">block-5</text> +</g> +<!-- block_4 --> +<g id="node4" class="node"> +<title>block_4</title> +<polygon fill="lightblue" stroke="lightblue" points="428,-52 360,-52 360,-16 428,-16 428,-52"/> +<text text-anchor="middle" x="394" y="-30.3" font-family="Times,serif" font-size="14.00">block-4</text> +</g> +<!-- block_3 --> +<g id="node5" class="node"> +<title>block_3</title> +<polygon fill="lightblue" stroke="lightblue" points="342,-52 274,-52 274,-16 342,-16 342,-52"/> +<text text-anchor="middle" x="308" y="-30.3" font-family="Times,serif" font-size="14.00">block-3</text> +</g> +<!-- block_2 --> +<g id="node6" class="node"> +<title>block_2</title> +<polygon fill="lightblue" stroke="lightblue" points="256,-52 188,-52 188,-16 256,-16 256,-52"/> +<text text-anchor="middle" x="222" y="-30.3" font-family="Times,serif" font-size="14.00">block-2</text> +</g> +<!-- block_1 --> +<g id="node7" class="node"> +<title>block_1</title> +<polygon fill="lightblue" stroke="lightblue" points="170,-52 102,-52 102,-16 170,-16 170,-52"/> +<text text-anchor="middle" x="136" y="-30.3" font-family="Times,serif" font-size="14.00">block-1</text> +</g> +<!-- block_0 --> +<g id="node8" class="node"> +<title>block_0</title> +<polygon fill="lightblue" stroke="lightblue" points="84,-52 16,-52 16,-16 84,-16 84,-52"/> +<text text-anchor="middle" x="50" y="-30.3" font-family="Times,serif" font-size="14.00">block-0</text> +</g> +</g> +</svg> diff --git a/doc/images/duck-rabbit.png b/doc/images/duck-rabbit.png Binary files differnew file mode 100644 index 0000000..0fc02b4 --- /dev/null +++ b/doc/images/duck-rabbit.png diff --git a/doc/images/eris-merkle-1.svg b/doc/images/eris-merkle-1.svg new file mode 100644 index 0000000..1f96b1c --- /dev/null +++ b/doc/images/eris-merkle-1.svg @@ -0,0 +1,208 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.42.3 (20191010.1750) + --> +<!-- Title: %3 Pages: 1 --> +<svg width="710pt" height="363pt" + viewBox="0.00 0.00 710.00 363.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 359)"> +<title>%3</title> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-359 706,-359 706,4 -4,4"/> +<g id="clust1" class="cluster"> +<title>cluster__level_0</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="8,-8 8,-98 694,-98 694,-8 8,-8"/> +<text text-anchor="middle" x="62" y="-82.8" font-family="Times,serif" font-size="14.00">level 0</text> +<text text-anchor="middle" x="62" y="-67.8" font-family="Times,serif" font-size="14.00">(data blocks)</text> +</g> +<g id="clust2" class="cluster"> +<title>cluster__level_1</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="156,-106 156,-181 546,-181 546,-106 156,-106"/> +<text text-anchor="middle" x="188" y="-165.8" font-family="Times,serif" font-size="14.00">level 1</text> +</g> +<g id="clust3" class="cluster"> +<title>cluster__level_2</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="254,-189 254,-264 448,-264 448,-189 254,-189"/> +<text text-anchor="middle" x="286" y="-248.8" font-family="Times,serif" font-size="14.00">level 2</text> +</g> +<g id="clust4" class="cluster"> +<title>cluster__level_3</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="303,-272 303,-347 399,-347 399,-272 303,-272"/> +<text text-anchor="middle" x="335" y="-331.8" font-family="Times,serif" font-size="14.00">level 3</text> +</g> +<!-- block_7 --> +<g id="node1" class="node"> +<title>block_7</title> +<polygon fill="lightblue" stroke="lightblue" points="686,-52 618,-52 618,-16 686,-16 686,-52"/> +<text text-anchor="middle" x="652" y="-30.3" font-family="sans-serif" font-size="14.00">block-7</text> +</g> +<!-- block_6 --> +<g id="node2" class="node"> +<title>block_6</title> +<polygon fill="lightblue" stroke="lightblue" points="600,-52 532,-52 532,-16 600,-16 600,-52"/> +<text text-anchor="middle" x="566" y="-30.3" font-family="sans-serif" font-size="14.00">block-6</text> +</g> +<!-- block_5 --> +<g id="node3" class="node"> +<title>block_5</title> +<polygon fill="lightblue" stroke="lightblue" points="514,-52 446,-52 446,-16 514,-16 514,-52"/> +<text text-anchor="middle" x="480" y="-30.3" font-family="sans-serif" font-size="14.00">block-5</text> +</g> +<!-- block_4 --> +<g id="node4" class="node"> +<title>block_4</title> +<polygon fill="lightblue" stroke="lightblue" points="428,-52 360,-52 360,-16 428,-16 428,-52"/> +<text text-anchor="middle" x="394" y="-30.3" font-family="sans-serif" font-size="14.00">block-4</text> +</g> +<!-- block_3 --> +<g id="node5" class="node"> +<title>block_3</title> +<polygon fill="lightblue" stroke="lightblue" points="342,-52 274,-52 274,-16 342,-16 342,-52"/> +<text text-anchor="middle" x="308" y="-30.3" font-family="sans-serif" font-size="14.00">block-3</text> +</g> +<!-- block_2 --> +<g id="node6" class="node"> +<title>block_2</title> +<polygon fill="lightblue" stroke="lightblue" points="256,-52 188,-52 188,-16 256,-16 256,-52"/> +<text text-anchor="middle" x="222" y="-30.3" font-family="sans-serif" font-size="14.00">block-2</text> +</g> +<!-- block_1 --> +<g id="node7" class="node"> +<title>block_1</title> +<polygon fill="lightblue" stroke="lightblue" points="170,-52 102,-52 102,-16 170,-16 170,-52"/> +<text text-anchor="middle" x="136" y="-30.3" font-family="sans-serif" font-size="14.00">block-1</text> +</g> +<!-- block_0 --> +<g id="node8" class="node"> +<title>block_0</title> +<polygon fill="lightblue" stroke="lightblue" points="84,-52 16,-52 16,-16 84,-16 84,-52"/> +<text text-anchor="middle" x="50" y="-30.3" font-family="sans-serif" font-size="14.00">block-0</text> +</g> +<!-- node_1_3 --> +<g id="node9" class="node"> +<title>node_1_3</title> +<polygon fill="yellow" stroke="yellow" points="538,-150 458,-150 458,-114 538,-114 538,-150"/> +<text text-anchor="middle" x="498" y="-128.3" font-family="sans-serif" font-size="14.00">node-1-3</text> +</g> +<!-- node_1_3->block_7 --> +<g id="edge8" class="edge"> +<title>node_1_3->block_7</title> +<path fill="none" stroke="black" d="M538.17,-125.82C560.68,-121.36 588.29,-113.11 609,-98 622,-88.51 632.34,-73.84 639.63,-61.04"/> +<polygon fill="black" stroke="black" points="642.75,-62.62 644.38,-52.15 636.58,-59.32 642.75,-62.62"/> +</g> +<!-- node_1_3->block_6 --> +<g id="edge7" class="edge"> +<title>node_1_3->block_6</title> +<path fill="none" stroke="black" d="M511.14,-113.99C515.01,-108.89 519.22,-103.25 523,-98 531.81,-85.75 541.3,-71.92 549.11,-60.35"/> +<polygon fill="black" stroke="black" points="552.05,-62.25 554.73,-52 546.24,-58.35 552.05,-62.25"/> +</g> +<!-- node_1_2 --> +<g id="node10" class="node"> +<title>node_1_2</title> +<polygon fill="yellow" stroke="yellow" points="440,-150 360,-150 360,-114 440,-114 440,-150"/> +<text text-anchor="middle" x="400" y="-128.3" font-family="sans-serif" font-size="14.00">node-1-2</text> +</g> +<!-- node_1_2->block_5 --> +<g id="edge6" class="edge"> +<title>node_1_2->block_5</title> +<path fill="none" stroke="black" d="M421.2,-113.68C426.61,-108.85 432.23,-103.43 437,-98 447.1,-86.5 456.84,-72.55 464.49,-60.7"/> +<polygon fill="black" stroke="black" points="467.53,-62.45 469.9,-52.12 461.61,-58.71 467.53,-62.45"/> +</g> +<!-- node_1_2->block_4 --> +<g id="edge5" class="edge"> +<title>node_1_2->block_4</title> +<path fill="none" stroke="black" d="M398.93,-113.84C398.03,-99.5 396.74,-78.81 395.7,-62.22"/> +<polygon fill="black" stroke="black" points="399.18,-61.78 395.06,-52.01 392.19,-62.21 399.18,-61.78"/> +</g> +<!-- node_1_1 --> +<g id="node11" class="node"> +<title>node_1_1</title> +<polygon fill="yellow" stroke="yellow" points="342,-150 262,-150 262,-114 342,-114 342,-150"/> +<text text-anchor="middle" x="302" y="-128.3" font-family="sans-serif" font-size="14.00">node-1-1</text> +</g> +<!-- node_1_1->block_3 --> +<g id="edge4" class="edge"> +<title>node_1_1->block_3</title> +<path fill="none" stroke="black" d="M303.07,-113.84C303.97,-99.5 305.26,-78.81 306.3,-62.22"/> +<polygon fill="black" stroke="black" points="309.81,-62.21 306.94,-52.01 302.82,-61.78 309.81,-62.21"/> +</g> +<!-- node_1_1->block_2 --> +<g id="edge3" class="edge"> +<title>node_1_1->block_2</title> +<path fill="none" stroke="black" d="M280.8,-113.68C275.39,-108.85 269.77,-103.43 265,-98 254.9,-86.5 245.16,-72.55 237.51,-60.7"/> +<polygon fill="black" stroke="black" points="240.39,-58.71 232.1,-52.12 234.47,-62.45 240.39,-58.71"/> +</g> +<!-- node_1_0 --> +<g id="node12" class="node"> +<title>node_1_0</title> +<polygon fill="yellow" stroke="yellow" points="244,-150 164,-150 164,-114 244,-114 244,-150"/> +<text text-anchor="middle" x="204" y="-128.3" font-family="sans-serif" font-size="14.00">node-1-0</text> +</g> +<!-- node_1_0->block_1 --> +<g id="edge2" class="edge"> +<title>node_1_0->block_1</title> +<path fill="none" stroke="black" d="M190.86,-113.99C186.99,-108.89 182.78,-103.25 179,-98 170.19,-85.75 160.7,-71.92 152.89,-60.35"/> +<polygon fill="black" stroke="black" points="155.76,-58.35 147.27,-52 149.95,-62.25 155.76,-58.35"/> +</g> +<!-- node_1_0->block_0 --> +<g id="edge1" class="edge"> +<title>node_1_0->block_0</title> +<path fill="none" stroke="black" d="M163.83,-125.82C141.32,-121.36 113.71,-113.11 93,-98 80,-88.51 69.66,-73.84 62.37,-61.04"/> +<polygon fill="black" stroke="black" points="65.42,-59.32 57.62,-52.15 59.25,-62.62 65.42,-59.32"/> +</g> +<!-- node_2_1 --> +<g id="node13" class="node"> +<title>node_2_1</title> +<polygon fill="yellow" stroke="yellow" points="440,-233 360,-233 360,-197 440,-197 440,-233"/> +<text text-anchor="middle" x="400" y="-211.3" font-family="sans-serif" font-size="14.00">node-2-1</text> +</g> +<!-- node_2_1->node_1_3 --> +<g id="edge12" class="edge"> +<title>node_2_1->node_1_3</title> +<path fill="none" stroke="black" d="M427.34,-196.87C434.57,-192 442.24,-186.51 449,-181 457.72,-173.89 466.68,-165.49 474.52,-157.72"/> +<polygon fill="black" stroke="black" points="477.38,-159.8 481.92,-150.23 472.4,-154.88 477.38,-159.8"/> +</g> +<!-- node_2_1->node_1_2 --> +<g id="edge11" class="edge"> +<title>node_2_1->node_1_2</title> +<path fill="none" stroke="black" d="M400,-196.82C400,-186.19 400,-172.31 400,-160.2"/> +<polygon fill="black" stroke="black" points="403.5,-160.15 400,-150.15 396.5,-160.15 403.5,-160.15"/> +</g> +<!-- node_2_0 --> +<g id="node14" class="node"> +<title>node_2_0</title> +<polygon fill="yellow" stroke="yellow" points="342,-233 262,-233 262,-197 342,-197 342,-233"/> +<text text-anchor="middle" x="302" y="-211.3" font-family="sans-serif" font-size="14.00">node-2-0</text> +</g> +<!-- node_2_0->node_1_1 --> +<g id="edge10" class="edge"> +<title>node_2_0->node_1_1</title> +<path fill="none" stroke="black" d="M302,-196.82C302,-186.19 302,-172.31 302,-160.2"/> +<polygon fill="black" stroke="black" points="305.5,-160.15 302,-150.15 298.5,-160.15 305.5,-160.15"/> +</g> +<!-- node_2_0->node_1_0 --> +<g id="edge9" class="edge"> +<title>node_2_0->node_1_0</title> +<path fill="none" stroke="black" d="M274.66,-196.87C267.43,-192 259.76,-186.51 253,-181 244.28,-173.89 235.32,-165.49 227.48,-157.72"/> +<polygon fill="black" stroke="black" points="229.6,-154.88 220.08,-150.23 224.62,-159.8 229.6,-154.88"/> +</g> +<!-- node_3_0 --> +<g id="node15" class="node"> +<title>node_3_0</title> +<polygon fill="yellow" stroke="yellow" points="391,-316 311,-316 311,-280 391,-280 391,-316"/> +<text text-anchor="middle" x="351" y="-294.3" font-family="sans-serif" font-size="14.00">node-3-0</text> +</g> +<!-- node_3_0->node_2_1 --> +<g id="edge14" class="edge"> +<title>node_3_0->node_2_1</title> +<path fill="none" stroke="black" d="M361.39,-279.82C368.08,-268.76 376.9,-254.18 384.43,-241.75"/> +<polygon fill="black" stroke="black" points="387.44,-243.52 389.62,-233.15 381.45,-239.9 387.44,-243.52"/> +</g> +<!-- node_3_0->node_2_0 --> +<g id="edge13" class="edge"> +<title>node_3_0->node_2_0</title> +<path fill="none" stroke="black" d="M340.61,-279.82C333.92,-268.76 325.1,-254.18 317.57,-241.75"/> +<polygon fill="black" stroke="black" points="320.55,-239.9 312.38,-233.15 314.56,-243.52 320.55,-239.9"/> +</g> +</g> +</svg> diff --git a/doc/images/eris-overview.svg b/doc/images/eris-overview.svg new file mode 100644 index 0000000..9edd3c1 --- /dev/null +++ b/doc/images/eris-overview.svg @@ -0,0 +1,137 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.42.3 (20191010.1750) + --> +<!-- Title: %3 Pages: 1 --> +<svg width="1021pt" height="102pt" + viewBox="0.00 0.00 1020.56 102.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 98)"> +<title>%3</title> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-98 1016.56,-98 1016.56,4 -4,4"/> +<!-- content --> +<g id="node1" class="node"> +<title>content</title> +<polygon fill="none" stroke="black" points="110.5,-92 41.5,-92 41.5,-56 110.5,-56 110.5,-92"/> +<text text-anchor="middle" x="76" y="-70.3" font-family="sans-serif" font-size="14.00">content</text> +</g> +<!-- encode --> +<g id="node2" class="node"> +<title>encode</title> +<ellipse fill="none" stroke="black" cx="232.55" cy="-20" rx="43.59" ry="18"/> +<text text-anchor="middle" x="232.55" y="-16.3" font-family="sans-serif" font-size="14.00">encode</text> +</g> +<!-- content->encode --> +<g id="edge1" class="edge"> +<title>content->encode</title> +<path fill="none" stroke="black" d="M110.53,-62.28C133.65,-54.2 164.56,-43.4 189.36,-34.74"/> +<polygon fill="black" stroke="black" points="190.59,-38.02 198.87,-31.42 188.28,-31.41 190.59,-38.02"/> +</g> +<!-- decode --> +<g id="node3" class="node"> +<title>decode</title> +<ellipse fill="none" stroke="black" cx="232.55" cy="-74" rx="43.59" ry="18"/> +<text text-anchor="middle" x="232.55" y="-70.3" font-family="sans-serif" font-size="14.00">decode</text> +</g> +<!-- content->decode --> +<g id="edge2" class="edge"> +<title>content->decode</title> +<path fill="none" stroke="black" d="M120.65,-74C142.04,-74 167.7,-74 188.95,-74"/> +<polygon fill="black" stroke="black" points="120.53,-70.5 110.53,-74 120.53,-77.5 120.53,-70.5"/> +</g> +<!-- read_cap --> +<g id="node5" class="node"> +<title>read_cap</title> +<polygon fill="none" stroke="black" points="432.09,-38 313.09,-38 313.09,-2 432.09,-2 432.09,-38"/> +<text text-anchor="middle" x="372.59" y="-16.3" font-family="sans-serif" font-size="14.00">read capability</text> +</g> +<!-- encode->read_cap --> +<g id="edge4" class="edge"> +<title>encode->read_cap</title> +<path fill="none" stroke="black" d="M276.47,-20C284.86,-20 293.86,-20 302.86,-20"/> +<polygon fill="black" stroke="black" points="302.98,-23.5 312.98,-20 302.98,-16.5 302.98,-23.5"/> +</g> +<!-- blocks --> +<g id="node6" class="node"> +<title>blocks</title> +<polygon fill="none" stroke="black" points="421.59,-94 323.59,-94 323.59,-56 421.59,-56 421.59,-94"/> +<text text-anchor="middle" x="372.59" y="-78.8" font-family="sans-serif" font-size="14.00">data blocks</text> +<text text-anchor="middle" x="372.59" y="-63.8" font-family="sans-serif" font-size="14.00">(encrypted)</text> +</g> +<!-- encode->blocks --> +<g id="edge5" class="edge"> +<title>encode->blocks</title> +<path fill="none" stroke="black" d="M264.53,-32.34C279.22,-38.2 297.25,-45.38 314.3,-52.17"/> +<polygon fill="black" stroke="black" points="313.05,-55.44 323.64,-55.89 315.64,-48.94 313.05,-55.44"/> +</g> +<!-- decode->read_cap --> +<g id="edge6" class="edge"> +<title>decode->read_cap</title> +<path fill="none" stroke="black" d="M274.49,-57.98C290.51,-51.72 308.97,-44.5 325.46,-38.05"/> +<polygon fill="black" stroke="black" points="272.91,-54.84 264.87,-61.75 275.46,-61.36 272.91,-54.84"/> +</g> +<!-- decode->blocks --> +<g id="edge7" class="edge"> +<title>decode->blocks</title> +<path fill="none" stroke="black" d="M286.11,-74.38C298.28,-74.47 311.17,-74.56 323.16,-74.65"/> +<polygon fill="black" stroke="black" points="286.12,-70.88 276.09,-74.31 286.07,-77.88 286.12,-70.88"/> +</g> +<!-- c_secret --> +<g id="node4" class="node"> +<title>c_secret</title> +<polygon fill="none" stroke="black" points="152,-38 0,-38 0,0 152,0 152,-38"/> +<text text-anchor="middle" x="76" y="-22.8" font-family="sans-serif" font-size="14.00">convergence secret</text> +<text text-anchor="middle" x="76" y="-7.8" font-family="sans-serif" font-size="14.00">(optional)</text> +</g> +<!-- c_secret->encode --> +<g id="edge3" class="edge"> +<title>c_secret->encode</title> +<path fill="none" stroke="black" d="M152.01,-19.49C160.98,-19.54 169.98,-19.6 178.55,-19.66"/> +<polygon fill="black" stroke="black" points="178.72,-23.16 188.74,-19.72 178.77,-16.16 178.72,-23.16"/> +</g> +<!-- verify_cap --> +<g id="node7" class="node"> +<title>verify_cap</title> +<polygon fill="none" stroke="black" points="679.09,-44 514.09,-44 514.09,-8 679.09,-8 679.09,-44"/> +<text text-anchor="middle" x="596.59" y="-22.3" font-family="sans-serif" font-size="14.00">verification capability</text> +</g> +<!-- read_cap->verify_cap --> +<g id="edge8" class="edge"> +<title>read_cap->verify_cap</title> +<path fill="none" stroke="black" d="M432.21,-21.58C454.13,-22.18 479.58,-22.86 503.78,-23.52"/> +<polygon fill="black" stroke="black" points="503.97,-27.02 514.06,-23.8 504.16,-20.03 503.97,-27.02"/> +<text text-anchor="middle" x="473.09" y="-26.8" font-family="Times,serif" font-size="14.00">derive</text> +</g> +<!-- verify --> +<g id="node8" class="node"> +<title>verify</title> +<ellipse fill="none" stroke="black" cx="752.49" cy="-50" rx="36.29" ry="18"/> +<text text-anchor="middle" x="752.49" y="-46.3" font-family="sans-serif" font-size="14.00">verify</text> +</g> +<!-- blocks->verify --> +<g id="edge10" class="edge"> +<title>blocks->verify</title> +<path fill="none" stroke="black" d="M421.73,-72.51C485.12,-69.13 600.03,-62.61 698.09,-55 700.92,-54.78 703.83,-54.54 706.77,-54.29"/> +<polygon fill="black" stroke="black" points="707.09,-57.78 716.75,-53.41 706.48,-50.81 707.09,-57.78"/> +</g> +<!-- verify_cap->verify --> +<g id="edge9" class="edge"> +<title>verify_cap->verify</title> +<path fill="none" stroke="black" d="M679.5,-38.77C689.09,-40.27 698.59,-41.75 707.38,-43.12"/> +<polygon fill="black" stroke="black" points="706.92,-46.59 717.34,-44.67 707.99,-39.67 706.92,-46.59"/> +</g> +<!-- list_of_blocks --> +<g id="node9" class="node"> +<title>list_of_blocks</title> +<ellipse fill="none" stroke="black" cx="919.22" cy="-50" rx="93.18" ry="26.74"/> +<text text-anchor="middle" x="919.22" y="-53.8" font-family="sans-serif" font-size="14.00">list of references</text> +<text text-anchor="middle" x="919.22" y="-38.8" font-family="sans-serif" font-size="14.00">to data blocks</text> +</g> +<!-- verify->list_of_blocks --> +<g id="edge11" class="edge"> +<title>verify->list_of_blocks</title> +<path fill="none" stroke="black" d="M789.23,-50C797.3,-50 806.24,-50 815.56,-50"/> +<polygon fill="black" stroke="black" points="815.8,-53.5 825.8,-50 815.8,-46.5 815.8,-53.5"/> +</g> +</g> +</svg> diff --git a/doc/images/fragment-graph.svg b/doc/images/fragment-graph.svg new file mode 100644 index 0000000..42a0f5a --- /dev/null +++ b/doc/images/fragment-graph.svg @@ -0,0 +1,187 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.40.1 (20161225.0304) + --> +<!-- Title: %3 Pages: 1 --> +<svg width="2420pt" height="358pt" + viewBox="0.00 0.00 2419.61 358.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 354)"> +<title>%3</title> +<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-354 2415.6125,-354 2415.6125,4 -4,4"/> +<g id="clust1" class="cluster"> +<title>cluster__alice</title> +<polygon fill="none" stroke="#000000" points="508.816,-122 508.816,-174 1629.6246,-174 1629.6246,-122 508.816,-122"/> +</g> +<g id="clust2" class="cluster"> +<title>cluster__note</title> +<polygon fill="none" stroke="#000000" points="8,-182 8,-342 2217.1257,-342 2217.1257,-182 8,-182"/> +</g> +<g id="clust3" class="cluster"> +<title>cluster__event</title> +<polygon fill="none" stroke="#000000" points="409.3749,-8 409.3749,-114 2403.6125,-114 2403.6125,-8 409.3749,-8"/> +</g> +<!-- alice --> +<g id="node1" class="node"> +<title>alice</title> +<ellipse fill="#00ffff" stroke="#00ffff" cx="644.8547" cy="-148" rx="128.0773" ry="18"/> +<text text-anchor="middle" x="644.8547" y="-144.3" font-family="sans-serif" font-size="14.00" fill="#000000">https://test.example/alice</text> +</g> +<!-- as:Person --> +<g id="node2" class="node"> +<title>as:Person</title> +<ellipse fill="none" stroke="#000000" cx="1565.7295" cy="-148" rx="55.7903" ry="18"/> +<text text-anchor="middle" x="1565.7295" y="-144.3" font-family="sans-serif" font-size="14.00" fill="#000000">as:Person</text> +</g> +<!-- alice->as:Person --> +<g id="edge1" class="edge"> +<title>alice->as:Person</title> +<path fill="none" stroke="#000000" d="M772.8984,-148C971.6946,-148 1347.5016,-148 1499.4703,-148"/> +<polygon fill="#000000" stroke="#000000" points="1499.5863,-151.5001 1509.5863,-148 1499.5863,-144.5001 1499.5863,-151.5001"/> +<text text-anchor="middle" x="1082.8691" y="-151.8" font-family="Times,serif" font-size="14.00" fill="#000000">rdf:type</text> +</g> +<!-- note_1 --> +<g id="node3" class="node"> +<title>note_1</title> +<ellipse fill="#00ffff" stroke="#00ffff" cx="157.6874" cy="-208" rx="141.8751" ry="18"/> +<text text-anchor="middle" x="157.6874" y="-204.3" font-family="sans-serif" font-size="14.00" fill="#000000">https://test.example/notes/1</text> +</g> +<!-- note_1->alice --> +<g id="edge3" class="edge"> +<title>note_1->alice</title> +<path fill="none" stroke="#000000" d="M258.6257,-195.3106C278.118,-192.8736 298.3806,-190.3495 317.3749,-188 390.8911,-178.9064 473.7081,-168.7919 537.6652,-161.009"/> +<polygon fill="#000000" stroke="#000000" points="538.2595,-164.4626 547.7636,-159.7804 537.4141,-157.5138 538.2595,-164.4626"/> +<text text-anchor="middle" x="358.3749" y="-191.8" font-family="Times,serif" font-size="14.00" fill="#000000">as:attributedTo</text> +</g> +<!-- as:Note --> +<g id="node4" class="node"> +<title>as:Note</title> +<ellipse fill="none" stroke="#000000" cx="1082.8691" cy="-208" rx="46.2923" ry="18"/> +<text text-anchor="middle" x="1082.8691" y="-204.3" font-family="sans-serif" font-size="14.00" fill="#000000">as:Note</text> +</g> +<!-- note_1->as:Note --> +<g id="edge2" class="edge"> +<title>note_1->as:Note</title> +<path fill="none" stroke="#000000" d="M299.4619,-208C506.943,-208 884.0743,-208 1026.436,-208"/> +<polygon fill="#000000" stroke="#000000" points="1026.6764,-211.5001 1036.6764,-208 1026.6763,-204.5001 1026.6764,-211.5001"/> +<text text-anchor="middle" x="644.8547" y="-211.8" font-family="Times,serif" font-size="14.00" fill="#000000">rdf:type</text> +</g> +<!-- note_content --> +<g id="node5" class="node"> +<title>note_content</title> +<polygon fill="none" stroke="#000000" points="1249.3691,-280 916.3691,-280 916.3691,-244 1249.3691,-244 1249.3691,-280"/> +<text text-anchor="middle" x="1082.8691" y="-258.3" font-family="sans-serif" font-size="14.00" fill="#000000">"The clowns just went trough the loop!"@en</text> +</g> +<!-- note_1->note_content --> +<g id="edge4" class="edge"> +<title>note_1->note_content</title> +<path fill="none" stroke="#000000" d="M277.6697,-217.6336C319.3505,-220.8273 366.4088,-224.2622 409.3749,-227 577.8013,-237.7322 770.0807,-247.4749 905.955,-253.9399"/> +<polygon fill="#000000" stroke="#000000" points="905.8938,-257.4408 916.0486,-254.4191 906.2258,-250.4487 905.8938,-257.4408"/> +<text text-anchor="middle" x="644.8547" y="-255.8" font-family="Times,serif" font-size="14.00" fill="#000000">as:content</text> +</g> +<!-- note_1_image --> +<g id="node6" class="node"> +<title>note_1_image</title> +<ellipse fill="none" stroke="#000000" cx="1082.8691" cy="-316" rx="173.5692" ry="18"/> +<text text-anchor="middle" x="1082.8691" y="-312.3" font-family="sans-serif" font-size="14.00" fill="#000000">https://test.example/note/1#image</text> +</g> +<!-- note_1->note_1_image --> +<g id="edge5" class="edge"> +<title>note_1->note_1_image</title> +<path fill="none" stroke="#000000" d="M212.5877,-224.7586C263.1877,-239.4798 340.6272,-260.188 409.3749,-271 574.8284,-297.0211 765.4616,-308.0135 901.5884,-312.6475"/> +<polygon fill="#000000" stroke="#000000" points="901.5937,-316.1495 911.7045,-312.9836 901.8262,-309.1534 901.5937,-316.1495"/> +<text text-anchor="middle" x="644.8547" y="-314.8" font-family="Times,serif" font-size="14.00" fill="#000000">as:image</text> +</g> +<!-- event --> +<g id="node9" class="node"> +<title>event</title> +<ellipse fill="#00ffff" stroke="#00ffff" cx="644.8547" cy="-88" rx="227.4596" ry="18"/> +<text text-anchor="middle" x="644.8547" y="-84.3" font-family="sans-serif" font-size="14.00" fill="#000000">https://circus.show/performance-in-funky-town</text> +</g> +<!-- note_1->event --> +<g id="edge8" class="edge"> +<title>note_1->event</title> +<path fill="none" stroke="#000000" d="M197.841,-190.5743C246.84,-170.0331 332.6553,-136.3739 409.3749,-118 434.4297,-111.9995 461.2899,-107.1407 487.5796,-103.2237"/> +<polygon fill="#000000" stroke="#000000" points="488.228,-106.6664 497.6226,-101.7682 487.2239,-99.7388 488.228,-106.6664"/> +<text text-anchor="middle" x="358.3749" y="-147.8" font-family="Times,serif" font-size="14.00" fill="#000000">as:context</text> +</g> +<!-- as:Image --> +<g id="node7" class="node"> +<title>as:Image</title> +<ellipse fill="none" stroke="#000000" cx="2042.0905" cy="-262" rx="53.8905" ry="18"/> +<text text-anchor="middle" x="2042.0905" y="-258.3" font-family="sans-serif" font-size="14.00" fill="#000000">as:Image</text> +</g> +<!-- note_1_image->as:Image --> +<g id="edge6" class="edge"> +<title>note_1_image->as:Image</title> +<path fill="none" stroke="#000000" d="M1209.4364,-303.6824C1237.0911,-301.2412 1266.2178,-298.8613 1293.4037,-297 1546.5106,-279.671 1848.3502,-268.4363 1977.8814,-264.0645"/> +<polygon fill="#000000" stroke="#000000" points="1978.1445,-267.5577 1988.0215,-263.7244 1977.9098,-260.5617 1978.1445,-267.5577"/> +<text text-anchor="middle" x="1565.7295" y="-300.8" font-family="Times,serif" font-size="14.00" fill="#000000">rdf:type</text> +</g> +<!-- https://test.example/images/1.jpg --> +<g id="node8" class="node"> +<title>https://test.example/images/1.jpg</title> +<ellipse fill="none" stroke="#000000" cx="2042.0905" cy="-316" rx="167.0704" ry="18"/> +<text text-anchor="middle" x="2042.0905" y="-312.3" font-family="sans-serif" font-size="14.00" fill="#000000">https://test.example/images/1.jpg</text> +</g> +<!-- note_1_image->https://test.example/images/1.jpg --> +<g id="edge7" class="edge"> +<title>note_1_image->https://test.example/images/1.jpg</title> +<path fill="none" stroke="#000000" d="M1256.5769,-316C1428.7449,-316 1691.1749,-316 1864.6377,-316"/> +<polygon fill="#000000" stroke="#000000" points="1864.8967,-319.5001 1874.8966,-316 1864.8966,-312.5001 1864.8967,-319.5001"/> +<text text-anchor="middle" x="1565.7295" y="-319.8" font-family="Times,serif" font-size="14.00" fill="#000000">as:url</text> +</g> +<!-- schema:Event --> +<g id="node10" class="node"> +<title>schema:Event</title> +<ellipse fill="none" stroke="#000000" cx="1565.7295" cy="-34" rx="76.8869" ry="18"/> +<text text-anchor="middle" x="1565.7295" y="-30.3" font-family="sans-serif" font-size="14.00" fill="#000000">schema:Event</text> +</g> +<!-- event->schema:Event --> +<g id="edge9" class="edge"> +<title>event->schema:Event</title> +<path fill="none" stroke="#000000" d="M810.5971,-75.6222C843.3156,-73.3117 877.4026,-70.9981 909.3345,-69 1114.0047,-56.1928 1354.7645,-44.12 1480.1011,-38.0611"/> +<polygon fill="#000000" stroke="#000000" points="1480.575,-41.5424 1490.3947,-37.5645 1480.2376,-34.5505 1480.575,-41.5424"/> +<text text-anchor="middle" x="1082.8691" y="-72.8" font-family="Times,serif" font-size="14.00" fill="#000000">rdf:type</text> +</g> +<!-- event_location --> +<g id="node11" class="node"> +<title>event_location</title> +<ellipse fill="none" stroke="#000000" cx="1565.7295" cy="-88" rx="272.1518" ry="18"/> +<text text-anchor="middle" x="1565.7295" y="-84.3" font-family="sans-serif" font-size="14.00" fill="#000000">https://circus.show/performance-in-funky-town#location</text> +</g> +<!-- event->event_location --> +<g id="edge10" class="edge"> +<title>event->event_location</title> +<path fill="none" stroke="#000000" d="M872.4867,-88C996.5489,-88 1151.2119,-88 1282.9547,-88"/> +<polygon fill="#000000" stroke="#000000" points="1283.2036,-91.5001 1293.2036,-88 1283.2035,-84.5001 1283.2036,-91.5001"/> +<text text-anchor="middle" x="1082.8691" y="-91.8" font-family="Times,serif" font-size="14.00" fill="#000000">schema:location</text> +</g> +<!-- schema:Place --> +<g id="node12" class="node"> +<title>schema:Place</title> +<ellipse fill="none" stroke="#000000" cx="2320.8691" cy="-34" rx="74.9875" ry="18"/> +<text text-anchor="middle" x="2320.8691" y="-30.3" font-family="sans-serif" font-size="14.00" fill="#000000">schema:Place</text> +</g> +<!-- event_location->schema:Place --> +<g id="edge11" class="edge"> +<title>event_location->schema:Place</title> +<path fill="none" stroke="#000000" d="M1750.9408,-74.7555C1906.927,-63.601 2122.6793,-48.1725 2238.8707,-39.8637"/> +<polygon fill="#000000" stroke="#000000" points="2239.3898,-43.3356 2249.1146,-39.1312 2238.8904,-36.3534 2239.3898,-43.3356"/> +<text text-anchor="middle" x="2042.0905" y="-68.8" font-family="Times,serif" font-size="14.00" fill="#000000">rdf:type</text> +</g> +<!-- event_location_name --> +<g id="node13" class="node"> +<title>event_location_name</title> +<polygon fill="none" stroke="#000000" points="2366.3691,-106 2275.3691,-106 2275.3691,-70 2366.3691,-70 2366.3691,-106"/> +<text text-anchor="middle" x="2320.8691" y="-84.3" font-family="sans-serif" font-size="14.00" fill="#000000">"The Tent"</text> +</g> +<!-- event_location->event_location_name --> +<g id="edge12" class="edge"> +<title>event_location->event_location_name</title> +<path fill="none" stroke="#000000" d="M1838.0854,-88C1993.7605,-88 2175.3685,-88 2264.9863,-88"/> +<polygon fill="#000000" stroke="#000000" points="2265.1914,-91.5001 2275.1914,-88 2265.1913,-84.5001 2265.1914,-91.5001"/> +<text text-anchor="middle" x="2042.0905" y="-91.8" font-family="Times,serif" font-size="14.00" fill="#000000">schema:name</text> +</g> +</g> +</svg> diff --git a/doc/images/merkle-size-1.svg b/doc/images/merkle-size-1.svg new file mode 100644 index 0000000..b10f4e5 --- /dev/null +++ b/doc/images/merkle-size-1.svg @@ -0,0 +1,207 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.42.3 (20191010.1750) + --> +<!-- Title: %3 Pages: 1 --> +<svg width="998pt" height="348pt" + viewBox="0.00 0.00 998.00 348.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 344)"> +<title>%3</title> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-344 994,-344 994,4 -4,4"/> +<g id="clust1" class="cluster"> +<title>cluster__data_blocks</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="8,-8 8,-83 982,-83 982,-8 8,-8"/> +<text text-anchor="middle" x="57" y="-67.8" font-family="Times,serif" font-size="14.00">data blocks</text> +</g> +<g id="clust2" class="cluster"> +<title>cluster__level_0</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="300,-91 300,-166 690,-166 690,-91 300,-91"/> +<text text-anchor="middle" x="332" y="-150.8" font-family="Times,serif" font-size="14.00">level 0</text> +</g> +<g id="clust3" class="cluster"> +<title>cluster__level_1</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="398,-174 398,-249 592,-249 592,-174 398,-174"/> +<text text-anchor="middle" x="430" y="-233.8" font-family="Times,serif" font-size="14.00">level 1</text> +</g> +<g id="clust4" class="cluster"> +<title>cluster__level_2</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="447,-257 447,-332 543,-332 543,-257 447,-257"/> +<text text-anchor="middle" x="479" y="-316.8" font-family="Times,serif" font-size="14.00">level 2</text> +</g> +<!-- data_block_7 --> +<g id="node1" class="node"> +<title>data_block_7</title> +<polygon fill="none" stroke="black" points="974,-52 870,-52 870,-16 974,-16 974,-52"/> +<text text-anchor="middle" x="922" y="-30.3" font-family="sans-serif" font-size="14.00">data-block-7</text> +</g> +<!-- data_block_6 --> +<g id="node2" class="node"> +<title>data_block_6</title> +<polygon fill="none" stroke="black" points="852,-52 748,-52 748,-16 852,-16 852,-52"/> +<text text-anchor="middle" x="800" y="-30.3" font-family="sans-serif" font-size="14.00">data-block-6</text> +</g> +<!-- data_block_5 --> +<g id="node3" class="node"> +<title>data_block_5</title> +<polygon fill="none" stroke="black" points="730,-52 626,-52 626,-16 730,-16 730,-52"/> +<text text-anchor="middle" x="678" y="-30.3" font-family="sans-serif" font-size="14.00">data-block-5</text> +</g> +<!-- data_block_4 --> +<g id="node4" class="node"> +<title>data_block_4</title> +<polygon fill="none" stroke="black" points="608,-52 504,-52 504,-16 608,-16 608,-52"/> +<text text-anchor="middle" x="556" y="-30.3" font-family="sans-serif" font-size="14.00">data-block-4</text> +</g> +<!-- data_block_3 --> +<g id="node5" class="node"> +<title>data_block_3</title> +<polygon fill="none" stroke="black" points="486,-52 382,-52 382,-16 486,-16 486,-52"/> +<text text-anchor="middle" x="434" y="-30.3" font-family="sans-serif" font-size="14.00">data-block-3</text> +</g> +<!-- data_block_2 --> +<g id="node6" class="node"> +<title>data_block_2</title> +<polygon fill="none" stroke="black" points="364,-52 260,-52 260,-16 364,-16 364,-52"/> +<text text-anchor="middle" x="312" y="-30.3" font-family="sans-serif" font-size="14.00">data-block-2</text> +</g> +<!-- data_block_1 --> +<g id="node7" class="node"> +<title>data_block_1</title> +<polygon fill="none" stroke="black" points="242,-52 138,-52 138,-16 242,-16 242,-52"/> +<text text-anchor="middle" x="190" y="-30.3" font-family="sans-serif" font-size="14.00">data-block-1</text> +</g> +<!-- data_block_0 --> +<g id="node8" class="node"> +<title>data_block_0</title> +<polygon fill="none" stroke="black" points="120,-52 16,-52 16,-16 120,-16 120,-52"/> +<text text-anchor="middle" x="68" y="-30.3" font-family="sans-serif" font-size="14.00">data-block-0</text> +</g> +<!-- node_0_3 --> +<g id="node9" class="node"> +<title>node_0_3</title> +<polygon fill="yellow" stroke="yellow" points="682,-135 602,-135 602,-99 682,-99 682,-135"/> +<text text-anchor="middle" x="642" y="-113.3" font-family="sans-serif" font-size="14.00">node-0-3</text> +</g> +<!-- node_0_3->data_block_7 --> +<g id="edge8" class="edge"> +<title>node_0_3->data_block_7</title> +<path fill="none" stroke="black" d="M682.04,-116.04C727.27,-114.73 802.24,-108.41 861,-83 874.31,-77.25 887.2,-67.85 897.68,-58.89"/> +<polygon fill="black" stroke="black" points="900.06,-61.46 905.19,-52.19 895.4,-56.24 900.06,-61.46"/> +</g> +<!-- node_0_3->data_block_6 --> +<g id="edge7" class="edge"> +<title>node_0_3->data_block_6</title> +<path fill="none" stroke="black" d="M682.45,-105.59C700.36,-100.14 721.33,-92.59 739,-83 751.24,-76.35 763.54,-67.25 773.86,-58.76"/> +<polygon fill="black" stroke="black" points="776.31,-61.27 781.67,-52.13 771.78,-55.93 776.31,-61.27"/> +</g> +<!-- node_0_2 --> +<g id="node10" class="node"> +<title>node_0_2</title> +<polygon fill="yellow" stroke="yellow" points="584,-135 504,-135 504,-99 584,-99 584,-135"/> +<text text-anchor="middle" x="544" y="-113.3" font-family="sans-serif" font-size="14.00">node-0-2</text> +</g> +<!-- node_0_2->data_block_5 --> +<g id="edge6" class="edge"> +<title>node_0_2->data_block_5</title> +<path fill="none" stroke="black" d="M575.83,-98.89C581.48,-96.11 587.36,-93.36 593,-91 603.37,-86.66 607.1,-88.33 617,-83 629.26,-76.39 641.57,-67.3 651.88,-58.8"/> +<polygon fill="black" stroke="black" points="654.33,-61.31 659.69,-52.17 649.8,-55.97 654.33,-61.31"/> +</g> +<!-- node_0_2->data_block_4 --> +<g id="edge5" class="edge"> +<title>node_0_2->data_block_4</title> +<path fill="none" stroke="black" d="M546.54,-98.82C548.12,-88.19 550.18,-74.31 551.97,-62.2"/> +<polygon fill="black" stroke="black" points="555.46,-62.56 553.46,-52.15 548.53,-61.53 555.46,-62.56"/> +</g> +<!-- node_0_1 --> +<g id="node11" class="node"> +<title>node_0_1</title> +<polygon fill="yellow" stroke="yellow" points="486,-135 406,-135 406,-99 486,-99 486,-135"/> +<text text-anchor="middle" x="446" y="-113.3" font-family="sans-serif" font-size="14.00">node-0-1</text> +</g> +<!-- node_0_1->data_block_3 --> +<g id="edge4" class="edge"> +<title>node_0_1->data_block_3</title> +<path fill="none" stroke="black" d="M443.46,-98.82C441.88,-88.19 439.82,-74.31 438.03,-62.2"/> +<polygon fill="black" stroke="black" points="441.47,-61.53 436.54,-52.15 434.54,-62.56 441.47,-61.53"/> +</g> +<!-- node_0_1->data_block_2 --> +<g id="edge3" class="edge"> +<title>node_0_1->data_block_2</title> +<path fill="none" stroke="black" d="M414.17,-98.89C408.52,-96.11 402.64,-93.36 397,-91 386.63,-86.66 382.9,-88.33 373,-83 360.74,-76.39 348.43,-67.3 338.12,-58.8"/> +<polygon fill="black" stroke="black" points="340.2,-55.97 330.31,-52.17 335.67,-61.31 340.2,-55.97"/> +</g> +<!-- node_0_0 --> +<g id="node12" class="node"> +<title>node_0_0</title> +<polygon fill="yellow" stroke="yellow" points="388,-135 308,-135 308,-99 388,-99 388,-135"/> +<text text-anchor="middle" x="348" y="-113.3" font-family="sans-serif" font-size="14.00">node-0-0</text> +</g> +<!-- node_0_0->data_block_1 --> +<g id="edge2" class="edge"> +<title>node_0_0->data_block_1</title> +<path fill="none" stroke="black" d="M307.55,-105.59C289.64,-100.14 268.67,-92.59 251,-83 238.76,-76.35 226.46,-67.25 216.14,-58.76"/> +<polygon fill="black" stroke="black" points="218.22,-55.93 208.33,-52.13 213.69,-61.27 218.22,-55.93"/> +</g> +<!-- node_0_0->data_block_0 --> +<g id="edge1" class="edge"> +<title>node_0_0->data_block_0</title> +<path fill="none" stroke="black" d="M307.96,-116.04C262.73,-114.73 187.76,-108.41 129,-83 115.69,-77.25 102.8,-67.85 92.32,-58.89"/> +<polygon fill="black" stroke="black" points="94.6,-56.24 84.81,-52.19 89.94,-61.46 94.6,-56.24"/> +</g> +<!-- node_1_1 --> +<g id="node13" class="node"> +<title>node_1_1</title> +<polygon fill="yellow" stroke="yellow" points="584,-218 504,-218 504,-182 584,-182 584,-218"/> +<text text-anchor="middle" x="544" y="-196.3" font-family="sans-serif" font-size="14.00">node-1-1</text> +</g> +<!-- node_1_1->node_0_3 --> +<g id="edge12" class="edge"> +<title>node_1_1->node_0_3</title> +<path fill="none" stroke="black" d="M571.34,-181.87C578.57,-177 586.24,-171.51 593,-166 601.72,-158.89 610.68,-150.49 618.52,-142.72"/> +<polygon fill="black" stroke="black" points="621.38,-144.8 625.92,-135.23 616.4,-139.88 621.38,-144.8"/> +</g> +<!-- node_1_1->node_0_2 --> +<g id="edge11" class="edge"> +<title>node_1_1->node_0_2</title> +<path fill="none" stroke="black" d="M544,-181.82C544,-171.19 544,-157.31 544,-145.2"/> +<polygon fill="black" stroke="black" points="547.5,-145.15 544,-135.15 540.5,-145.15 547.5,-145.15"/> +</g> +<!-- node_1_0 --> +<g id="node14" class="node"> +<title>node_1_0</title> +<polygon fill="yellow" stroke="yellow" points="486,-218 406,-218 406,-182 486,-182 486,-218"/> +<text text-anchor="middle" x="446" y="-196.3" font-family="sans-serif" font-size="14.00">node-1-0</text> +</g> +<!-- node_1_0->node_0_1 --> +<g id="edge10" class="edge"> +<title>node_1_0->node_0_1</title> +<path fill="none" stroke="black" d="M446,-181.82C446,-171.19 446,-157.31 446,-145.2"/> +<polygon fill="black" stroke="black" points="449.5,-145.15 446,-135.15 442.5,-145.15 449.5,-145.15"/> +</g> +<!-- node_1_0->node_0_0 --> +<g id="edge9" class="edge"> +<title>node_1_0->node_0_0</title> +<path fill="none" stroke="black" d="M418.66,-181.87C411.43,-177 403.76,-171.51 397,-166 388.28,-158.89 379.32,-150.49 371.48,-142.72"/> +<polygon fill="black" stroke="black" points="373.6,-139.88 364.08,-135.23 368.62,-144.8 373.6,-139.88"/> +</g> +<!-- node_2_0 --> +<g id="node15" class="node"> +<title>node_2_0</title> +<polygon fill="yellow" stroke="yellow" points="535,-301 455,-301 455,-265 535,-265 535,-301"/> +<text text-anchor="middle" x="495" y="-279.3" font-family="sans-serif" font-size="14.00">node-2-0</text> +</g> +<!-- node_2_0->node_1_1 --> +<g id="edge14" class="edge"> +<title>node_2_0->node_1_1</title> +<path fill="none" stroke="black" d="M505.39,-264.82C512.08,-253.76 520.9,-239.18 528.43,-226.75"/> +<polygon fill="black" stroke="black" points="531.44,-228.52 533.62,-218.15 525.45,-224.9 531.44,-228.52"/> +</g> +<!-- node_2_0->node_1_0 --> +<g id="edge13" class="edge"> +<title>node_2_0->node_1_0</title> +<path fill="none" stroke="black" d="M484.61,-264.82C477.92,-253.76 469.1,-239.18 461.57,-226.75"/> +<polygon fill="black" stroke="black" points="464.55,-224.9 456.38,-218.15 458.56,-228.52 464.55,-224.9"/> +</g> +</g> +</svg> diff --git a/doc/images/node-nonce-position-2.svg b/doc/images/node-nonce-position-2.svg new file mode 100644 index 0000000..360b331 --- /dev/null +++ b/doc/images/node-nonce-position-2.svg @@ -0,0 +1,208 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.42.3 (20191010.1750) + --> +<!-- Title: %3 Pages: 1 --> +<svg width="710pt" height="363pt" + viewBox="0.00 0.00 710.00 363.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 359)"> +<title>%3</title> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-359 706,-359 706,4 -4,4"/> +<g id="clust1" class="cluster"> +<title>cluster__level_0</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="8,-8 8,-98 694,-98 694,-8 8,-8"/> +<text text-anchor="middle" x="62" y="-82.8" font-family="Times,serif" font-size="14.00">level 0</text> +<text text-anchor="middle" x="62" y="-67.8" font-family="Times,serif" font-size="14.00">(data blocks)</text> +</g> +<g id="clust2" class="cluster"> +<title>cluster__level_1</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="160,-106 160,-181 542,-181 542,-106 160,-106"/> +<text text-anchor="middle" x="192" y="-165.8" font-family="Times,serif" font-size="14.00">level 1</text> +</g> +<g id="clust3" class="cluster"> +<title>cluster__level_2</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="256,-189 256,-264 446,-264 446,-189 256,-189"/> +<text text-anchor="middle" x="288" y="-248.8" font-family="Times,serif" font-size="14.00">level 2</text> +</g> +<g id="clust4" class="cluster"> +<title>cluster__level_3</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="304,-272 304,-347 398,-347 398,-272 304,-272"/> +<text text-anchor="middle" x="336" y="-331.8" font-family="Times,serif" font-size="14.00">level 3</text> +</g> +<!-- block_7 --> +<g id="node1" class="node"> +<title>block_7</title> +<polygon fill="lightblue" stroke="lightblue" points="686,-52 618,-52 618,-16 686,-16 686,-52"/> +<text text-anchor="middle" x="652" y="-30.3" font-family="Times,serif" font-size="14.00">block-7</text> +</g> +<!-- block_6 --> +<g id="node2" class="node"> +<title>block_6</title> +<polygon fill="lightblue" stroke="lightblue" points="600,-52 532,-52 532,-16 600,-16 600,-52"/> +<text text-anchor="middle" x="566" y="-30.3" font-family="Times,serif" font-size="14.00">block-6</text> +</g> +<!-- block_5 --> +<g id="node3" class="node"> +<title>block_5</title> +<polygon fill="lightblue" stroke="lightblue" points="514,-52 446,-52 446,-16 514,-16 514,-52"/> +<text text-anchor="middle" x="480" y="-30.3" font-family="Times,serif" font-size="14.00">block-5</text> +</g> +<!-- block_4 --> +<g id="node4" class="node"> +<title>block_4</title> +<polygon fill="lightblue" stroke="lightblue" points="428,-52 360,-52 360,-16 428,-16 428,-52"/> +<text text-anchor="middle" x="394" y="-30.3" font-family="Times,serif" font-size="14.00">block-4</text> +</g> +<!-- block_3 --> +<g id="node5" class="node"> +<title>block_3</title> +<polygon fill="lightblue" stroke="lightblue" points="342,-52 274,-52 274,-16 342,-16 342,-52"/> +<text text-anchor="middle" x="308" y="-30.3" font-family="Times,serif" font-size="14.00">block-3</text> +</g> +<!-- block_2 --> +<g id="node6" class="node"> +<title>block_2</title> +<polygon fill="lightblue" stroke="lightblue" points="256,-52 188,-52 188,-16 256,-16 256,-52"/> +<text text-anchor="middle" x="222" y="-30.3" font-family="Times,serif" font-size="14.00">block-2</text> +</g> +<!-- block_1 --> +<g id="node7" class="node"> +<title>block_1</title> +<polygon fill="lightblue" stroke="lightblue" points="170,-52 102,-52 102,-16 170,-16 170,-52"/> +<text text-anchor="middle" x="136" y="-30.3" font-family="Times,serif" font-size="14.00">block-1</text> +</g> +<!-- block_0 --> +<g id="node8" class="node"> +<title>block_0</title> +<polygon fill="lightblue" stroke="lightblue" points="84,-52 16,-52 16,-16 84,-16 84,-52"/> +<text text-anchor="middle" x="50" y="-30.3" font-family="Times,serif" font-size="14.00">block-0</text> +</g> +<!-- node_1_3 --> +<g id="node9" class="node"> +<title>node_1_3</title> +<polygon fill="lightgrey" stroke="lightgrey" points="534,-150 456,-150 456,-114 534,-114 534,-150"/> +<text text-anchor="middle" x="495" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-3</text> +</g> +<!-- node_1_3->block_7 --> +<g id="edge8" class="edge"> +<title>node_1_3->block_7</title> +<path fill="none" stroke="black" d="M534.09,-126.45C557.58,-122.17 587.06,-113.89 609,-98 622.03,-88.56 632.38,-73.89 639.66,-61.08"/> +<polygon fill="black" stroke="black" points="642.78,-62.65 644.41,-52.18 636.61,-59.36 642.78,-62.65"/> +</g> +<!-- node_1_3->block_6 --> +<g id="edge7" class="edge"> +<title>node_1_3->block_6</title> +<path fill="none" stroke="black" d="M510.17,-113.81C514.43,-108.8 518.99,-103.26 523,-98 532.15,-86 541.67,-72.2 549.42,-60.58"/> +<polygon fill="black" stroke="black" points="552.38,-62.46 554.97,-52.19 546.54,-58.6 552.38,-62.46"/> +</g> +<!-- node_1_2 --> +<g id="node10" class="node"> +<title>node_1_2</title> +<polygon fill="lightgrey" stroke="lightgrey" points="438,-150 360,-150 360,-114 438,-114 438,-150"/> +<text text-anchor="middle" x="399" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-2</text> +</g> +<!-- node_1_2->block_5 --> +<g id="edge6" class="edge"> +<title>node_1_2->block_5</title> +<path fill="none" stroke="black" d="M420.8,-113.75C426.35,-108.92 432.12,-103.48 437,-98 447.17,-86.57 456.92,-72.62 464.56,-60.76"/> +<polygon fill="black" stroke="black" points="467.6,-62.5 469.96,-52.17 461.67,-58.78 467.6,-62.5"/> +</g> +<!-- node_1_2->block_4 --> +<g id="edge5" class="edge"> +<title>node_1_2->block_4</title> +<path fill="none" stroke="black" d="M398.11,-113.84C397.36,-99.5 396.28,-78.81 395.42,-62.22"/> +<polygon fill="black" stroke="black" points="398.9,-61.82 394.89,-52.01 391.91,-62.18 398.9,-61.82"/> +</g> +<!-- node_1_1 --> +<g id="node11" class="node"> +<title>node_1_1</title> +<polygon fill="orange" stroke="orange" points="342,-150 264,-150 264,-114 342,-114 342,-150"/> +<text text-anchor="middle" x="303" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-1</text> +</g> +<!-- node_1_1->block_3 --> +<g id="edge4" class="edge"> +<title>node_1_1->block_3</title> +<path fill="none" stroke="black" d="M303.89,-113.84C304.64,-99.5 305.72,-78.81 306.58,-62.22"/> +<polygon fill="black" stroke="black" points="310.09,-62.18 307.11,-52.01 303.1,-61.82 310.09,-62.18"/> +</g> +<!-- node_1_1->block_2 --> +<g id="edge3" class="edge"> +<title>node_1_1->block_2</title> +<path fill="none" stroke="black" d="M281.2,-113.75C275.65,-108.92 269.88,-103.48 265,-98 254.83,-86.57 245.08,-72.62 237.44,-60.76"/> +<polygon fill="black" stroke="black" points="240.33,-58.78 232.04,-52.17 234.4,-62.5 240.33,-58.78"/> +</g> +<!-- node_1_0 --> +<g id="node12" class="node"> +<title>node_1_0</title> +<polygon fill="yellow" stroke="yellow" points="246,-150 168,-150 168,-114 246,-114 246,-150"/> +<text text-anchor="middle" x="207" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-0</text> +</g> +<!-- node_1_0->block_1 --> +<g id="edge2" class="edge"> +<title>node_1_0->block_1</title> +<path fill="none" stroke="black" d="M191.83,-113.81C187.57,-108.8 183.01,-103.26 179,-98 169.85,-86 160.33,-72.2 152.58,-60.58"/> +<polygon fill="black" stroke="black" points="155.46,-58.6 147.03,-52.19 149.62,-62.46 155.46,-58.6"/> +</g> +<!-- node_1_0->block_0 --> +<g id="edge1" class="edge"> +<title>node_1_0->block_0</title> +<path fill="none" stroke="black" d="M167.91,-126.45C144.42,-122.17 114.94,-113.89 93,-98 79.97,-88.56 69.62,-73.89 62.34,-61.08"/> +<polygon fill="black" stroke="black" points="65.39,-59.36 57.59,-52.18 59.22,-62.65 65.39,-59.36"/> +</g> +<!-- node_2_1 --> +<g id="node13" class="node"> +<title>node_2_1</title> +<polygon fill="lightgrey" stroke="lightgrey" points="438,-233 360,-233 360,-197 438,-197 438,-233"/> +<text text-anchor="middle" x="399" y="-211.3" font-family="Times,serif" font-size="14.00">node-2-1</text> +</g> +<!-- node_2_1->node_1_3 --> +<g id="edge12" class="edge"> +<title>node_2_1->node_1_3</title> +<path fill="none" stroke="black" d="M425.79,-196.86C432.88,-191.98 440.39,-186.5 447,-181 455.56,-173.88 464.34,-165.47 472.02,-157.7"/> +<polygon fill="black" stroke="black" points="474.83,-159.83 479.27,-150.22 469.8,-154.96 474.83,-159.83"/> +</g> +<!-- node_2_1->node_1_2 --> +<g id="edge11" class="edge"> +<title>node_2_1->node_1_2</title> +<path fill="none" stroke="black" d="M399,-196.82C399,-186.19 399,-172.31 399,-160.2"/> +<polygon fill="black" stroke="black" points="402.5,-160.15 399,-150.15 395.5,-160.15 402.5,-160.15"/> +</g> +<!-- node_2_0 --> +<g id="node14" class="node"> +<title>node_2_0</title> +<polygon fill="orange" stroke="orange" points="342,-233 264,-233 264,-197 342,-197 342,-233"/> +<text text-anchor="middle" x="303" y="-211.3" font-family="Times,serif" font-size="14.00">node-2-0</text> +</g> +<!-- node_2_0->node_1_1 --> +<g id="edge10" class="edge"> +<title>node_2_0->node_1_1</title> +<path fill="none" stroke="black" d="M303,-196.82C303,-186.19 303,-172.31 303,-160.2"/> +<polygon fill="black" stroke="black" points="306.5,-160.15 303,-150.15 299.5,-160.15 306.5,-160.15"/> +</g> +<!-- node_2_0->node_1_0 --> +<g id="edge9" class="edge"> +<title>node_2_0->node_1_0</title> +<path fill="none" stroke="black" d="M276.21,-196.86C269.12,-191.98 261.61,-186.5 255,-181 246.44,-173.88 237.66,-165.47 229.98,-157.7"/> +<polygon fill="black" stroke="black" points="232.2,-154.96 222.73,-150.22 227.17,-159.83 232.2,-154.96"/> +</g> +<!-- node_3_0 --> +<g id="node15" class="node"> +<title>node_3_0</title> +<polygon fill="orange" stroke="orange" points="390,-316 312,-316 312,-280 390,-280 390,-316"/> +<text text-anchor="middle" x="351" y="-294.3" font-family="Times,serif" font-size="14.00">node-3-0</text> +</g> +<!-- node_3_0->node_2_1 --> +<g id="edge14" class="edge"> +<title>node_3_0->node_2_1</title> +<path fill="none" stroke="black" d="M361.18,-279.82C367.67,-268.87 376.21,-254.46 383.53,-242.11"/> +<polygon fill="black" stroke="black" points="386.75,-243.54 388.84,-233.15 380.73,-239.97 386.75,-243.54"/> +</g> +<!-- node_3_0->node_2_0 --> +<g id="edge13" class="edge"> +<title>node_3_0->node_2_0</title> +<path fill="none" stroke="black" d="M340.82,-279.82C334.33,-268.87 325.79,-254.46 318.47,-242.11"/> +<polygon fill="black" stroke="black" points="321.27,-239.97 313.16,-233.15 315.25,-243.54 321.27,-239.97"/> +</g> +</g> +</svg> diff --git a/doc/images/node-nonce-position-3.svg b/doc/images/node-nonce-position-3.svg new file mode 100644 index 0000000..9e391a3 --- /dev/null +++ b/doc/images/node-nonce-position-3.svg @@ -0,0 +1,208 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.42.3 (20191010.1750) + --> +<!-- Title: %3 Pages: 1 --> +<svg width="710pt" height="363pt" + viewBox="0.00 0.00 710.00 363.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 359)"> +<title>%3</title> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-359 706,-359 706,4 -4,4"/> +<g id="clust1" class="cluster"> +<title>cluster__level_0</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="8,-8 8,-98 694,-98 694,-8 8,-8"/> +<text text-anchor="middle" x="62" y="-82.8" font-family="Times,serif" font-size="14.00">level 0</text> +<text text-anchor="middle" x="62" y="-67.8" font-family="Times,serif" font-size="14.00">(data blocks)</text> +</g> +<g id="clust2" class="cluster"> +<title>cluster__level_1</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="160,-106 160,-181 542,-181 542,-106 160,-106"/> +<text text-anchor="middle" x="192" y="-165.8" font-family="Times,serif" font-size="14.00">level 1</text> +</g> +<g id="clust3" class="cluster"> +<title>cluster__level_2</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="256,-189 256,-264 446,-264 446,-189 256,-189"/> +<text text-anchor="middle" x="288" y="-248.8" font-family="Times,serif" font-size="14.00">level 2</text> +</g> +<g id="clust4" class="cluster"> +<title>cluster__level_3</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="304,-272 304,-347 398,-347 398,-272 304,-272"/> +<text text-anchor="middle" x="336" y="-331.8" font-family="Times,serif" font-size="14.00">level 3</text> +</g> +<!-- block_7 --> +<g id="node1" class="node"> +<title>block_7</title> +<polygon fill="lightblue" stroke="lightblue" points="686,-52 618,-52 618,-16 686,-16 686,-52"/> +<text text-anchor="middle" x="652" y="-30.3" font-family="Times,serif" font-size="14.00">block-7</text> +</g> +<!-- block_6 --> +<g id="node2" class="node"> +<title>block_6</title> +<polygon fill="lightblue" stroke="lightblue" points="600,-52 532,-52 532,-16 600,-16 600,-52"/> +<text text-anchor="middle" x="566" y="-30.3" font-family="Times,serif" font-size="14.00">block-6</text> +</g> +<!-- block_5 --> +<g id="node3" class="node"> +<title>block_5</title> +<polygon fill="lightblue" stroke="lightblue" points="514,-52 446,-52 446,-16 514,-16 514,-52"/> +<text text-anchor="middle" x="480" y="-30.3" font-family="Times,serif" font-size="14.00">block-5</text> +</g> +<!-- block_4 --> +<g id="node4" class="node"> +<title>block_4</title> +<polygon fill="lightblue" stroke="lightblue" points="428,-52 360,-52 360,-16 428,-16 428,-52"/> +<text text-anchor="middle" x="394" y="-30.3" font-family="Times,serif" font-size="14.00">block-4</text> +</g> +<!-- block_3 --> +<g id="node5" class="node"> +<title>block_3</title> +<polygon fill="lightblue" stroke="lightblue" points="342,-52 274,-52 274,-16 342,-16 342,-52"/> +<text text-anchor="middle" x="308" y="-30.3" font-family="Times,serif" font-size="14.00">block-3</text> +</g> +<!-- block_2 --> +<g id="node6" class="node"> +<title>block_2</title> +<polygon fill="lightblue" stroke="lightblue" points="256,-52 188,-52 188,-16 256,-16 256,-52"/> +<text text-anchor="middle" x="222" y="-30.3" font-family="Times,serif" font-size="14.00">block-2</text> +</g> +<!-- block_1 --> +<g id="node7" class="node"> +<title>block_1</title> +<polygon fill="lightblue" stroke="lightblue" points="170,-52 102,-52 102,-16 170,-16 170,-52"/> +<text text-anchor="middle" x="136" y="-30.3" font-family="Times,serif" font-size="14.00">block-1</text> +</g> +<!-- block_0 --> +<g id="node8" class="node"> +<title>block_0</title> +<polygon fill="lightblue" stroke="lightblue" points="84,-52 16,-52 16,-16 84,-16 84,-52"/> +<text text-anchor="middle" x="50" y="-30.3" font-family="Times,serif" font-size="14.00">block-0</text> +</g> +<!-- node_1_3 --> +<g id="node9" class="node"> +<title>node_1_3</title> +<polygon fill="lightgrey" stroke="lightgrey" points="534,-150 456,-150 456,-114 534,-114 534,-150"/> +<text text-anchor="middle" x="495" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-3</text> +</g> +<!-- node_1_3->block_7 --> +<g id="edge8" class="edge"> +<title>node_1_3->block_7</title> +<path fill="none" stroke="black" d="M534.09,-126.45C557.58,-122.17 587.06,-113.89 609,-98 622.03,-88.56 632.38,-73.89 639.66,-61.08"/> +<polygon fill="black" stroke="black" points="642.78,-62.65 644.41,-52.18 636.61,-59.36 642.78,-62.65"/> +</g> +<!-- node_1_3->block_6 --> +<g id="edge7" class="edge"> +<title>node_1_3->block_6</title> +<path fill="none" stroke="black" d="M510.17,-113.81C514.43,-108.8 518.99,-103.26 523,-98 532.15,-86 541.67,-72.2 549.42,-60.58"/> +<polygon fill="black" stroke="black" points="552.38,-62.46 554.97,-52.19 546.54,-58.6 552.38,-62.46"/> +</g> +<!-- node_1_2 --> +<g id="node10" class="node"> +<title>node_1_2</title> +<polygon fill="lightgrey" stroke="lightgrey" points="438,-150 360,-150 360,-114 438,-114 438,-150"/> +<text text-anchor="middle" x="399" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-2</text> +</g> +<!-- node_1_2->block_5 --> +<g id="edge6" class="edge"> +<title>node_1_2->block_5</title> +<path fill="none" stroke="black" d="M420.8,-113.75C426.35,-108.92 432.12,-103.48 437,-98 447.17,-86.57 456.92,-72.62 464.56,-60.76"/> +<polygon fill="black" stroke="black" points="467.6,-62.5 469.96,-52.17 461.67,-58.78 467.6,-62.5"/> +</g> +<!-- node_1_2->block_4 --> +<g id="edge5" class="edge"> +<title>node_1_2->block_4</title> +<path fill="none" stroke="black" d="M398.11,-113.84C397.36,-99.5 396.28,-78.81 395.42,-62.22"/> +<polygon fill="black" stroke="black" points="398.9,-61.82 394.89,-52.01 391.91,-62.18 398.9,-61.82"/> +</g> +<!-- node_1_1 --> +<g id="node11" class="node"> +<title>node_1_1</title> +<polygon fill="yellow" stroke="yellow" points="342,-150 264,-150 264,-114 342,-114 342,-150"/> +<text text-anchor="middle" x="303" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-1</text> +</g> +<!-- node_1_1->block_3 --> +<g id="edge4" class="edge"> +<title>node_1_1->block_3</title> +<path fill="none" stroke="black" d="M303.89,-113.84C304.64,-99.5 305.72,-78.81 306.58,-62.22"/> +<polygon fill="black" stroke="black" points="310.09,-62.18 307.11,-52.01 303.1,-61.82 310.09,-62.18"/> +</g> +<!-- node_1_1->block_2 --> +<g id="edge3" class="edge"> +<title>node_1_1->block_2</title> +<path fill="none" stroke="black" d="M281.2,-113.75C275.65,-108.92 269.88,-103.48 265,-98 254.83,-86.57 245.08,-72.62 237.44,-60.76"/> +<polygon fill="black" stroke="black" points="240.33,-58.78 232.04,-52.17 234.4,-62.5 240.33,-58.78"/> +</g> +<!-- node_1_0 --> +<g id="node12" class="node"> +<title>node_1_0</title> +<polygon fill="yellow" stroke="yellow" points="246,-150 168,-150 168,-114 246,-114 246,-150"/> +<text text-anchor="middle" x="207" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-0</text> +</g> +<!-- node_1_0->block_1 --> +<g id="edge2" class="edge"> +<title>node_1_0->block_1</title> +<path fill="none" stroke="black" d="M191.83,-113.81C187.57,-108.8 183.01,-103.26 179,-98 169.85,-86 160.33,-72.2 152.58,-60.58"/> +<polygon fill="black" stroke="black" points="155.46,-58.6 147.03,-52.19 149.62,-62.46 155.46,-58.6"/> +</g> +<!-- node_1_0->block_0 --> +<g id="edge1" class="edge"> +<title>node_1_0->block_0</title> +<path fill="none" stroke="black" d="M167.91,-126.45C144.42,-122.17 114.94,-113.89 93,-98 79.97,-88.56 69.62,-73.89 62.34,-61.08"/> +<polygon fill="black" stroke="black" points="65.39,-59.36 57.59,-52.18 59.22,-62.65 65.39,-59.36"/> +</g> +<!-- node_2_1 --> +<g id="node13" class="node"> +<title>node_2_1</title> +<polygon fill="lightgrey" stroke="lightgrey" points="438,-233 360,-233 360,-197 438,-197 438,-233"/> +<text text-anchor="middle" x="399" y="-211.3" font-family="Times,serif" font-size="14.00">node-2-1</text> +</g> +<!-- node_2_1->node_1_3 --> +<g id="edge12" class="edge"> +<title>node_2_1->node_1_3</title> +<path fill="none" stroke="black" d="M425.79,-196.86C432.88,-191.98 440.39,-186.5 447,-181 455.56,-173.88 464.34,-165.47 472.02,-157.7"/> +<polygon fill="black" stroke="black" points="474.83,-159.83 479.27,-150.22 469.8,-154.96 474.83,-159.83"/> +</g> +<!-- node_2_1->node_1_2 --> +<g id="edge11" class="edge"> +<title>node_2_1->node_1_2</title> +<path fill="none" stroke="black" d="M399,-196.82C399,-186.19 399,-172.31 399,-160.2"/> +<polygon fill="black" stroke="black" points="402.5,-160.15 399,-150.15 395.5,-160.15 402.5,-160.15"/> +</g> +<!-- node_2_0 --> +<g id="node14" class="node"> +<title>node_2_0</title> +<polygon fill="orange" stroke="orange" points="342,-233 264,-233 264,-197 342,-197 342,-233"/> +<text text-anchor="middle" x="303" y="-211.3" font-family="Times,serif" font-size="14.00">node-2-0</text> +</g> +<!-- node_2_0->node_1_1 --> +<g id="edge10" class="edge"> +<title>node_2_0->node_1_1</title> +<path fill="none" stroke="black" d="M303,-196.82C303,-186.19 303,-172.31 303,-160.2"/> +<polygon fill="black" stroke="black" points="306.5,-160.15 303,-150.15 299.5,-160.15 306.5,-160.15"/> +</g> +<!-- node_2_0->node_1_0 --> +<g id="edge9" class="edge"> +<title>node_2_0->node_1_0</title> +<path fill="none" stroke="black" d="M276.21,-196.86C269.12,-191.98 261.61,-186.5 255,-181 246.44,-173.88 237.66,-165.47 229.98,-157.7"/> +<polygon fill="black" stroke="black" points="232.2,-154.96 222.73,-150.22 227.17,-159.83 232.2,-154.96"/> +</g> +<!-- node_3_0 --> +<g id="node15" class="node"> +<title>node_3_0</title> +<polygon fill="orange" stroke="orange" points="390,-316 312,-316 312,-280 390,-280 390,-316"/> +<text text-anchor="middle" x="351" y="-294.3" font-family="Times,serif" font-size="14.00">node-3-0</text> +</g> +<!-- node_3_0->node_2_1 --> +<g id="edge14" class="edge"> +<title>node_3_0->node_2_1</title> +<path fill="none" stroke="black" d="M361.18,-279.82C367.67,-268.87 376.21,-254.46 383.53,-242.11"/> +<polygon fill="black" stroke="black" points="386.75,-243.54 388.84,-233.15 380.73,-239.97 386.75,-243.54"/> +</g> +<!-- node_3_0->node_2_0 --> +<g id="edge13" class="edge"> +<title>node_3_0->node_2_0</title> +<path fill="none" stroke="black" d="M340.82,-279.82C334.33,-268.87 325.79,-254.46 318.47,-242.11"/> +<polygon fill="black" stroke="black" points="321.27,-239.97 313.16,-233.15 315.25,-243.54 321.27,-239.97"/> +</g> +</g> +</svg> diff --git a/doc/images/node-nonce-position-4.svg b/doc/images/node-nonce-position-4.svg new file mode 100644 index 0000000..d6908ec --- /dev/null +++ b/doc/images/node-nonce-position-4.svg @@ -0,0 +1,208 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.42.3 (20191010.1750) + --> +<!-- Title: %3 Pages: 1 --> +<svg width="710pt" height="363pt" + viewBox="0.00 0.00 710.00 363.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 359)"> +<title>%3</title> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-359 706,-359 706,4 -4,4"/> +<g id="clust1" class="cluster"> +<title>cluster__level_0</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="8,-8 8,-98 694,-98 694,-8 8,-8"/> +<text text-anchor="middle" x="62" y="-82.8" font-family="Times,serif" font-size="14.00">level 0</text> +<text text-anchor="middle" x="62" y="-67.8" font-family="Times,serif" font-size="14.00">(data blocks)</text> +</g> +<g id="clust2" class="cluster"> +<title>cluster__level_1</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="160,-106 160,-181 542,-181 542,-106 160,-106"/> +<text text-anchor="middle" x="192" y="-165.8" font-family="Times,serif" font-size="14.00">level 1</text> +</g> +<g id="clust3" class="cluster"> +<title>cluster__level_2</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="256,-189 256,-264 446,-264 446,-189 256,-189"/> +<text text-anchor="middle" x="288" y="-248.8" font-family="Times,serif" font-size="14.00">level 2</text> +</g> +<g id="clust4" class="cluster"> +<title>cluster__level_3</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="304,-272 304,-347 398,-347 398,-272 304,-272"/> +<text text-anchor="middle" x="336" y="-331.8" font-family="Times,serif" font-size="14.00">level 3</text> +</g> +<!-- block_7 --> +<g id="node1" class="node"> +<title>block_7</title> +<polygon fill="lightblue" stroke="lightblue" points="686,-52 618,-52 618,-16 686,-16 686,-52"/> +<text text-anchor="middle" x="652" y="-30.3" font-family="Times,serif" font-size="14.00">block-7</text> +</g> +<!-- block_6 --> +<g id="node2" class="node"> +<title>block_6</title> +<polygon fill="lightblue" stroke="lightblue" points="600,-52 532,-52 532,-16 600,-16 600,-52"/> +<text text-anchor="middle" x="566" y="-30.3" font-family="Times,serif" font-size="14.00">block-6</text> +</g> +<!-- block_5 --> +<g id="node3" class="node"> +<title>block_5</title> +<polygon fill="lightblue" stroke="lightblue" points="514,-52 446,-52 446,-16 514,-16 514,-52"/> +<text text-anchor="middle" x="480" y="-30.3" font-family="Times,serif" font-size="14.00">block-5</text> +</g> +<!-- block_4 --> +<g id="node4" class="node"> +<title>block_4</title> +<polygon fill="lightblue" stroke="lightblue" points="428,-52 360,-52 360,-16 428,-16 428,-52"/> +<text text-anchor="middle" x="394" y="-30.3" font-family="Times,serif" font-size="14.00">block-4</text> +</g> +<!-- block_3 --> +<g id="node5" class="node"> +<title>block_3</title> +<polygon fill="lightblue" stroke="lightblue" points="342,-52 274,-52 274,-16 342,-16 342,-52"/> +<text text-anchor="middle" x="308" y="-30.3" font-family="Times,serif" font-size="14.00">block-3</text> +</g> +<!-- block_2 --> +<g id="node6" class="node"> +<title>block_2</title> +<polygon fill="lightblue" stroke="lightblue" points="256,-52 188,-52 188,-16 256,-16 256,-52"/> +<text text-anchor="middle" x="222" y="-30.3" font-family="Times,serif" font-size="14.00">block-2</text> +</g> +<!-- block_1 --> +<g id="node7" class="node"> +<title>block_1</title> +<polygon fill="lightblue" stroke="lightblue" points="170,-52 102,-52 102,-16 170,-16 170,-52"/> +<text text-anchor="middle" x="136" y="-30.3" font-family="Times,serif" font-size="14.00">block-1</text> +</g> +<!-- block_0 --> +<g id="node8" class="node"> +<title>block_0</title> +<polygon fill="lightblue" stroke="lightblue" points="84,-52 16,-52 16,-16 84,-16 84,-52"/> +<text text-anchor="middle" x="50" y="-30.3" font-family="Times,serif" font-size="14.00">block-0</text> +</g> +<!-- node_1_3 --> +<g id="node9" class="node"> +<title>node_1_3</title> +<polygon fill="lightgrey" stroke="lightgrey" points="534,-150 456,-150 456,-114 534,-114 534,-150"/> +<text text-anchor="middle" x="495" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-3</text> +</g> +<!-- node_1_3->block_7 --> +<g id="edge8" class="edge"> +<title>node_1_3->block_7</title> +<path fill="none" stroke="black" d="M534.09,-126.45C557.58,-122.17 587.06,-113.89 609,-98 622.03,-88.56 632.38,-73.89 639.66,-61.08"/> +<polygon fill="black" stroke="black" points="642.78,-62.65 644.41,-52.18 636.61,-59.36 642.78,-62.65"/> +</g> +<!-- node_1_3->block_6 --> +<g id="edge7" class="edge"> +<title>node_1_3->block_6</title> +<path fill="none" stroke="black" d="M510.17,-113.81C514.43,-108.8 518.99,-103.26 523,-98 532.15,-86 541.67,-72.2 549.42,-60.58"/> +<polygon fill="black" stroke="black" points="552.38,-62.46 554.97,-52.19 546.54,-58.6 552.38,-62.46"/> +</g> +<!-- node_1_2 --> +<g id="node10" class="node"> +<title>node_1_2</title> +<polygon fill="orange" stroke="orange" points="438,-150 360,-150 360,-114 438,-114 438,-150"/> +<text text-anchor="middle" x="399" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-2</text> +</g> +<!-- node_1_2->block_5 --> +<g id="edge6" class="edge"> +<title>node_1_2->block_5</title> +<path fill="none" stroke="black" d="M420.8,-113.75C426.35,-108.92 432.12,-103.48 437,-98 447.17,-86.57 456.92,-72.62 464.56,-60.76"/> +<polygon fill="black" stroke="black" points="467.6,-62.5 469.96,-52.17 461.67,-58.78 467.6,-62.5"/> +</g> +<!-- node_1_2->block_4 --> +<g id="edge5" class="edge"> +<title>node_1_2->block_4</title> +<path fill="none" stroke="black" d="M398.11,-113.84C397.36,-99.5 396.28,-78.81 395.42,-62.22"/> +<polygon fill="black" stroke="black" points="398.9,-61.82 394.89,-52.01 391.91,-62.18 398.9,-61.82"/> +</g> +<!-- node_1_1 --> +<g id="node11" class="node"> +<title>node_1_1</title> +<polygon fill="yellow" stroke="yellow" points="342,-150 264,-150 264,-114 342,-114 342,-150"/> +<text text-anchor="middle" x="303" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-1</text> +</g> +<!-- node_1_1->block_3 --> +<g id="edge4" class="edge"> +<title>node_1_1->block_3</title> +<path fill="none" stroke="black" d="M303.89,-113.84C304.64,-99.5 305.72,-78.81 306.58,-62.22"/> +<polygon fill="black" stroke="black" points="310.09,-62.18 307.11,-52.01 303.1,-61.82 310.09,-62.18"/> +</g> +<!-- node_1_1->block_2 --> +<g id="edge3" class="edge"> +<title>node_1_1->block_2</title> +<path fill="none" stroke="black" d="M281.2,-113.75C275.65,-108.92 269.88,-103.48 265,-98 254.83,-86.57 245.08,-72.62 237.44,-60.76"/> +<polygon fill="black" stroke="black" points="240.33,-58.78 232.04,-52.17 234.4,-62.5 240.33,-58.78"/> +</g> +<!-- node_1_0 --> +<g id="node12" class="node"> +<title>node_1_0</title> +<polygon fill="yellow" stroke="yellow" points="246,-150 168,-150 168,-114 246,-114 246,-150"/> +<text text-anchor="middle" x="207" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-0</text> +</g> +<!-- node_1_0->block_1 --> +<g id="edge2" class="edge"> +<title>node_1_0->block_1</title> +<path fill="none" stroke="black" d="M191.83,-113.81C187.57,-108.8 183.01,-103.26 179,-98 169.85,-86 160.33,-72.2 152.58,-60.58"/> +<polygon fill="black" stroke="black" points="155.46,-58.6 147.03,-52.19 149.62,-62.46 155.46,-58.6"/> +</g> +<!-- node_1_0->block_0 --> +<g id="edge1" class="edge"> +<title>node_1_0->block_0</title> +<path fill="none" stroke="black" d="M167.91,-126.45C144.42,-122.17 114.94,-113.89 93,-98 79.97,-88.56 69.62,-73.89 62.34,-61.08"/> +<polygon fill="black" stroke="black" points="65.39,-59.36 57.59,-52.18 59.22,-62.65 65.39,-59.36"/> +</g> +<!-- node_2_1 --> +<g id="node13" class="node"> +<title>node_2_1</title> +<polygon fill="orange" stroke="orange" points="438,-233 360,-233 360,-197 438,-197 438,-233"/> +<text text-anchor="middle" x="399" y="-211.3" font-family="Times,serif" font-size="14.00">node-2-1</text> +</g> +<!-- node_2_1->node_1_3 --> +<g id="edge12" class="edge"> +<title>node_2_1->node_1_3</title> +<path fill="none" stroke="black" d="M425.79,-196.86C432.88,-191.98 440.39,-186.5 447,-181 455.56,-173.88 464.34,-165.47 472.02,-157.7"/> +<polygon fill="black" stroke="black" points="474.83,-159.83 479.27,-150.22 469.8,-154.96 474.83,-159.83"/> +</g> +<!-- node_2_1->node_1_2 --> +<g id="edge11" class="edge"> +<title>node_2_1->node_1_2</title> +<path fill="none" stroke="black" d="M399,-196.82C399,-186.19 399,-172.31 399,-160.2"/> +<polygon fill="black" stroke="black" points="402.5,-160.15 399,-150.15 395.5,-160.15 402.5,-160.15"/> +</g> +<!-- node_2_0 --> +<g id="node14" class="node"> +<title>node_2_0</title> +<polygon fill="yellow" stroke="yellow" points="342,-233 264,-233 264,-197 342,-197 342,-233"/> +<text text-anchor="middle" x="303" y="-211.3" font-family="Times,serif" font-size="14.00">node-2-0</text> +</g> +<!-- node_2_0->node_1_1 --> +<g id="edge10" class="edge"> +<title>node_2_0->node_1_1</title> +<path fill="none" stroke="black" d="M303,-196.82C303,-186.19 303,-172.31 303,-160.2"/> +<polygon fill="black" stroke="black" points="306.5,-160.15 303,-150.15 299.5,-160.15 306.5,-160.15"/> +</g> +<!-- node_2_0->node_1_0 --> +<g id="edge9" class="edge"> +<title>node_2_0->node_1_0</title> +<path fill="none" stroke="black" d="M276.21,-196.86C269.12,-191.98 261.61,-186.5 255,-181 246.44,-173.88 237.66,-165.47 229.98,-157.7"/> +<polygon fill="black" stroke="black" points="232.2,-154.96 222.73,-150.22 227.17,-159.83 232.2,-154.96"/> +</g> +<!-- node_3_0 --> +<g id="node15" class="node"> +<title>node_3_0</title> +<polygon fill="orange" stroke="orange" points="390,-316 312,-316 312,-280 390,-280 390,-316"/> +<text text-anchor="middle" x="351" y="-294.3" font-family="Times,serif" font-size="14.00">node-3-0</text> +</g> +<!-- node_3_0->node_2_1 --> +<g id="edge14" class="edge"> +<title>node_3_0->node_2_1</title> +<path fill="none" stroke="black" d="M361.18,-279.82C367.67,-268.87 376.21,-254.46 383.53,-242.11"/> +<polygon fill="black" stroke="black" points="386.75,-243.54 388.84,-233.15 380.73,-239.97 386.75,-243.54"/> +</g> +<!-- node_3_0->node_2_0 --> +<g id="edge13" class="edge"> +<title>node_3_0->node_2_0</title> +<path fill="none" stroke="black" d="M340.82,-279.82C334.33,-268.87 325.79,-254.46 318.47,-242.11"/> +<polygon fill="black" stroke="black" points="321.27,-239.97 313.16,-233.15 315.25,-243.54 321.27,-239.97"/> +</g> +</g> +</svg> diff --git a/doc/images/node-nonce-position-5.svg b/doc/images/node-nonce-position-5.svg new file mode 100644 index 0000000..26de0e8 --- /dev/null +++ b/doc/images/node-nonce-position-5.svg @@ -0,0 +1,208 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.42.3 (20191010.1750) + --> +<!-- Title: %3 Pages: 1 --> +<svg width="710pt" height="363pt" + viewBox="0.00 0.00 710.00 363.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 359)"> +<title>%3</title> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-359 706,-359 706,4 -4,4"/> +<g id="clust1" class="cluster"> +<title>cluster__level_0</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="8,-8 8,-98 694,-98 694,-8 8,-8"/> +<text text-anchor="middle" x="62" y="-82.8" font-family="Times,serif" font-size="14.00">level 0</text> +<text text-anchor="middle" x="62" y="-67.8" font-family="Times,serif" font-size="14.00">(data blocks)</text> +</g> +<g id="clust2" class="cluster"> +<title>cluster__level_1</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="160,-106 160,-181 542,-181 542,-106 160,-106"/> +<text text-anchor="middle" x="192" y="-165.8" font-family="Times,serif" font-size="14.00">level 1</text> +</g> +<g id="clust3" class="cluster"> +<title>cluster__level_2</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="256,-189 256,-264 446,-264 446,-189 256,-189"/> +<text text-anchor="middle" x="288" y="-248.8" font-family="Times,serif" font-size="14.00">level 2</text> +</g> +<g id="clust4" class="cluster"> +<title>cluster__level_3</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="304,-272 304,-347 398,-347 398,-272 304,-272"/> +<text text-anchor="middle" x="336" y="-331.8" font-family="Times,serif" font-size="14.00">level 3</text> +</g> +<!-- block_7 --> +<g id="node1" class="node"> +<title>block_7</title> +<polygon fill="lightblue" stroke="lightblue" points="686,-52 618,-52 618,-16 686,-16 686,-52"/> +<text text-anchor="middle" x="652" y="-30.3" font-family="Times,serif" font-size="14.00">block-7</text> +</g> +<!-- block_6 --> +<g id="node2" class="node"> +<title>block_6</title> +<polygon fill="lightblue" stroke="lightblue" points="600,-52 532,-52 532,-16 600,-16 600,-52"/> +<text text-anchor="middle" x="566" y="-30.3" font-family="Times,serif" font-size="14.00">block-6</text> +</g> +<!-- block_5 --> +<g id="node3" class="node"> +<title>block_5</title> +<polygon fill="lightblue" stroke="lightblue" points="514,-52 446,-52 446,-16 514,-16 514,-52"/> +<text text-anchor="middle" x="480" y="-30.3" font-family="Times,serif" font-size="14.00">block-5</text> +</g> +<!-- block_4 --> +<g id="node4" class="node"> +<title>block_4</title> +<polygon fill="lightblue" stroke="lightblue" points="428,-52 360,-52 360,-16 428,-16 428,-52"/> +<text text-anchor="middle" x="394" y="-30.3" font-family="Times,serif" font-size="14.00">block-4</text> +</g> +<!-- block_3 --> +<g id="node5" class="node"> +<title>block_3</title> +<polygon fill="lightblue" stroke="lightblue" points="342,-52 274,-52 274,-16 342,-16 342,-52"/> +<text text-anchor="middle" x="308" y="-30.3" font-family="Times,serif" font-size="14.00">block-3</text> +</g> +<!-- block_2 --> +<g id="node6" class="node"> +<title>block_2</title> +<polygon fill="lightblue" stroke="lightblue" points="256,-52 188,-52 188,-16 256,-16 256,-52"/> +<text text-anchor="middle" x="222" y="-30.3" font-family="Times,serif" font-size="14.00">block-2</text> +</g> +<!-- block_1 --> +<g id="node7" class="node"> +<title>block_1</title> +<polygon fill="lightblue" stroke="lightblue" points="170,-52 102,-52 102,-16 170,-16 170,-52"/> +<text text-anchor="middle" x="136" y="-30.3" font-family="Times,serif" font-size="14.00">block-1</text> +</g> +<!-- block_0 --> +<g id="node8" class="node"> +<title>block_0</title> +<polygon fill="lightblue" stroke="lightblue" points="84,-52 16,-52 16,-16 84,-16 84,-52"/> +<text text-anchor="middle" x="50" y="-30.3" font-family="Times,serif" font-size="14.00">block-0</text> +</g> +<!-- node_1_3 --> +<g id="node9" class="node"> +<title>node_1_3</title> +<polygon fill="orange" stroke="orange" points="534,-150 456,-150 456,-114 534,-114 534,-150"/> +<text text-anchor="middle" x="495" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-3</text> +</g> +<!-- node_1_3->block_7 --> +<g id="edge8" class="edge"> +<title>node_1_3->block_7</title> +<path fill="none" stroke="black" d="M534.09,-126.45C557.58,-122.17 587.06,-113.89 609,-98 622.03,-88.56 632.38,-73.89 639.66,-61.08"/> +<polygon fill="black" stroke="black" points="642.78,-62.65 644.41,-52.18 636.61,-59.36 642.78,-62.65"/> +</g> +<!-- node_1_3->block_6 --> +<g id="edge7" class="edge"> +<title>node_1_3->block_6</title> +<path fill="none" stroke="black" d="M510.17,-113.81C514.43,-108.8 518.99,-103.26 523,-98 532.15,-86 541.67,-72.2 549.42,-60.58"/> +<polygon fill="black" stroke="black" points="552.38,-62.46 554.97,-52.19 546.54,-58.6 552.38,-62.46"/> +</g> +<!-- node_1_2 --> +<g id="node10" class="node"> +<title>node_1_2</title> +<polygon fill="yellow" stroke="yellow" points="438,-150 360,-150 360,-114 438,-114 438,-150"/> +<text text-anchor="middle" x="399" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-2</text> +</g> +<!-- node_1_2->block_5 --> +<g id="edge6" class="edge"> +<title>node_1_2->block_5</title> +<path fill="none" stroke="black" d="M420.8,-113.75C426.35,-108.92 432.12,-103.48 437,-98 447.17,-86.57 456.92,-72.62 464.56,-60.76"/> +<polygon fill="black" stroke="black" points="467.6,-62.5 469.96,-52.17 461.67,-58.78 467.6,-62.5"/> +</g> +<!-- node_1_2->block_4 --> +<g id="edge5" class="edge"> +<title>node_1_2->block_4</title> +<path fill="none" stroke="black" d="M398.11,-113.84C397.36,-99.5 396.28,-78.81 395.42,-62.22"/> +<polygon fill="black" stroke="black" points="398.9,-61.82 394.89,-52.01 391.91,-62.18 398.9,-61.82"/> +</g> +<!-- node_1_1 --> +<g id="node11" class="node"> +<title>node_1_1</title> +<polygon fill="yellow" stroke="yellow" points="342,-150 264,-150 264,-114 342,-114 342,-150"/> +<text text-anchor="middle" x="303" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-1</text> +</g> +<!-- node_1_1->block_3 --> +<g id="edge4" class="edge"> +<title>node_1_1->block_3</title> +<path fill="none" stroke="black" d="M303.89,-113.84C304.64,-99.5 305.72,-78.81 306.58,-62.22"/> +<polygon fill="black" stroke="black" points="310.09,-62.18 307.11,-52.01 303.1,-61.82 310.09,-62.18"/> +</g> +<!-- node_1_1->block_2 --> +<g id="edge3" class="edge"> +<title>node_1_1->block_2</title> +<path fill="none" stroke="black" d="M281.2,-113.75C275.65,-108.92 269.88,-103.48 265,-98 254.83,-86.57 245.08,-72.62 237.44,-60.76"/> +<polygon fill="black" stroke="black" points="240.33,-58.78 232.04,-52.17 234.4,-62.5 240.33,-58.78"/> +</g> +<!-- node_1_0 --> +<g id="node12" class="node"> +<title>node_1_0</title> +<polygon fill="yellow" stroke="yellow" points="246,-150 168,-150 168,-114 246,-114 246,-150"/> +<text text-anchor="middle" x="207" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-0</text> +</g> +<!-- node_1_0->block_1 --> +<g id="edge2" class="edge"> +<title>node_1_0->block_1</title> +<path fill="none" stroke="black" d="M191.83,-113.81C187.57,-108.8 183.01,-103.26 179,-98 169.85,-86 160.33,-72.2 152.58,-60.58"/> +<polygon fill="black" stroke="black" points="155.46,-58.6 147.03,-52.19 149.62,-62.46 155.46,-58.6"/> +</g> +<!-- node_1_0->block_0 --> +<g id="edge1" class="edge"> +<title>node_1_0->block_0</title> +<path fill="none" stroke="black" d="M167.91,-126.45C144.42,-122.17 114.94,-113.89 93,-98 79.97,-88.56 69.62,-73.89 62.34,-61.08"/> +<polygon fill="black" stroke="black" points="65.39,-59.36 57.59,-52.18 59.22,-62.65 65.39,-59.36"/> +</g> +<!-- node_2_1 --> +<g id="node13" class="node"> +<title>node_2_1</title> +<polygon fill="orange" stroke="orange" points="438,-233 360,-233 360,-197 438,-197 438,-233"/> +<text text-anchor="middle" x="399" y="-211.3" font-family="Times,serif" font-size="14.00">node-2-1</text> +</g> +<!-- node_2_1->node_1_3 --> +<g id="edge12" class="edge"> +<title>node_2_1->node_1_3</title> +<path fill="none" stroke="black" d="M425.79,-196.86C432.88,-191.98 440.39,-186.5 447,-181 455.56,-173.88 464.34,-165.47 472.02,-157.7"/> +<polygon fill="black" stroke="black" points="474.83,-159.83 479.27,-150.22 469.8,-154.96 474.83,-159.83"/> +</g> +<!-- node_2_1->node_1_2 --> +<g id="edge11" class="edge"> +<title>node_2_1->node_1_2</title> +<path fill="none" stroke="black" d="M399,-196.82C399,-186.19 399,-172.31 399,-160.2"/> +<polygon fill="black" stroke="black" points="402.5,-160.15 399,-150.15 395.5,-160.15 402.5,-160.15"/> +</g> +<!-- node_2_0 --> +<g id="node14" class="node"> +<title>node_2_0</title> +<polygon fill="yellow" stroke="yellow" points="342,-233 264,-233 264,-197 342,-197 342,-233"/> +<text text-anchor="middle" x="303" y="-211.3" font-family="Times,serif" font-size="14.00">node-2-0</text> +</g> +<!-- node_2_0->node_1_1 --> +<g id="edge10" class="edge"> +<title>node_2_0->node_1_1</title> +<path fill="none" stroke="black" d="M303,-196.82C303,-186.19 303,-172.31 303,-160.2"/> +<polygon fill="black" stroke="black" points="306.5,-160.15 303,-150.15 299.5,-160.15 306.5,-160.15"/> +</g> +<!-- node_2_0->node_1_0 --> +<g id="edge9" class="edge"> +<title>node_2_0->node_1_0</title> +<path fill="none" stroke="black" d="M276.21,-196.86C269.12,-191.98 261.61,-186.5 255,-181 246.44,-173.88 237.66,-165.47 229.98,-157.7"/> +<polygon fill="black" stroke="black" points="232.2,-154.96 222.73,-150.22 227.17,-159.83 232.2,-154.96"/> +</g> +<!-- node_3_0 --> +<g id="node15" class="node"> +<title>node_3_0</title> +<polygon fill="orange" stroke="orange" points="390,-316 312,-316 312,-280 390,-280 390,-316"/> +<text text-anchor="middle" x="351" y="-294.3" font-family="Times,serif" font-size="14.00">node-3-0</text> +</g> +<!-- node_3_0->node_2_1 --> +<g id="edge14" class="edge"> +<title>node_3_0->node_2_1</title> +<path fill="none" stroke="black" d="M361.18,-279.82C367.67,-268.87 376.21,-254.46 383.53,-242.11"/> +<polygon fill="black" stroke="black" points="386.75,-243.54 388.84,-233.15 380.73,-239.97 386.75,-243.54"/> +</g> +<!-- node_3_0->node_2_0 --> +<g id="edge13" class="edge"> +<title>node_3_0->node_2_0</title> +<path fill="none" stroke="black" d="M340.82,-279.82C334.33,-268.87 325.79,-254.46 318.47,-242.11"/> +<polygon fill="black" stroke="black" points="321.27,-239.97 313.16,-233.15 315.25,-243.54 321.27,-239.97"/> +</g> +</g> +</svg> diff --git a/doc/images/node-nonce-position-6.svg b/doc/images/node-nonce-position-6.svg new file mode 100644 index 0000000..e626495 --- /dev/null +++ b/doc/images/node-nonce-position-6.svg @@ -0,0 +1,208 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.42.3 (20191010.1750) + --> +<!-- Title: %3 Pages: 1 --> +<svg width="710pt" height="363pt" + viewBox="0.00 0.00 710.00 363.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 359)"> +<title>%3</title> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-359 706,-359 706,4 -4,4"/> +<g id="clust1" class="cluster"> +<title>cluster__level_0</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="8,-8 8,-98 694,-98 694,-8 8,-8"/> +<text text-anchor="middle" x="62" y="-82.8" font-family="Times,serif" font-size="14.00">level 0</text> +<text text-anchor="middle" x="62" y="-67.8" font-family="Times,serif" font-size="14.00">(data blocks)</text> +</g> +<g id="clust2" class="cluster"> +<title>cluster__level_1</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="160,-106 160,-181 542,-181 542,-106 160,-106"/> +<text text-anchor="middle" x="192" y="-165.8" font-family="Times,serif" font-size="14.00">level 1</text> +</g> +<g id="clust3" class="cluster"> +<title>cluster__level_2</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="256,-189 256,-264 446,-264 446,-189 256,-189"/> +<text text-anchor="middle" x="288" y="-248.8" font-family="Times,serif" font-size="14.00">level 2</text> +</g> +<g id="clust4" class="cluster"> +<title>cluster__level_3</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="304,-272 304,-347 398,-347 398,-272 304,-272"/> +<text text-anchor="middle" x="336" y="-331.8" font-family="Times,serif" font-size="14.00">level 3</text> +</g> +<!-- block_7 --> +<g id="node1" class="node"> +<title>block_7</title> +<polygon fill="lightblue" stroke="lightblue" points="686,-52 618,-52 618,-16 686,-16 686,-52"/> +<text text-anchor="middle" x="652" y="-30.3" font-family="Times,serif" font-size="14.00">block-7</text> +</g> +<!-- block_6 --> +<g id="node2" class="node"> +<title>block_6</title> +<polygon fill="lightblue" stroke="lightblue" points="600,-52 532,-52 532,-16 600,-16 600,-52"/> +<text text-anchor="middle" x="566" y="-30.3" font-family="Times,serif" font-size="14.00">block-6</text> +</g> +<!-- block_5 --> +<g id="node3" class="node"> +<title>block_5</title> +<polygon fill="lightblue" stroke="lightblue" points="514,-52 446,-52 446,-16 514,-16 514,-52"/> +<text text-anchor="middle" x="480" y="-30.3" font-family="Times,serif" font-size="14.00">block-5</text> +</g> +<!-- block_4 --> +<g id="node4" class="node"> +<title>block_4</title> +<polygon fill="lightblue" stroke="lightblue" points="428,-52 360,-52 360,-16 428,-16 428,-52"/> +<text text-anchor="middle" x="394" y="-30.3" font-family="Times,serif" font-size="14.00">block-4</text> +</g> +<!-- block_3 --> +<g id="node5" class="node"> +<title>block_3</title> +<polygon fill="lightblue" stroke="lightblue" points="342,-52 274,-52 274,-16 342,-16 342,-52"/> +<text text-anchor="middle" x="308" y="-30.3" font-family="Times,serif" font-size="14.00">block-3</text> +</g> +<!-- block_2 --> +<g id="node6" class="node"> +<title>block_2</title> +<polygon fill="lightblue" stroke="lightblue" points="256,-52 188,-52 188,-16 256,-16 256,-52"/> +<text text-anchor="middle" x="222" y="-30.3" font-family="Times,serif" font-size="14.00">block-2</text> +</g> +<!-- block_1 --> +<g id="node7" class="node"> +<title>block_1</title> +<polygon fill="lightblue" stroke="lightblue" points="170,-52 102,-52 102,-16 170,-16 170,-52"/> +<text text-anchor="middle" x="136" y="-30.3" font-family="Times,serif" font-size="14.00">block-1</text> +</g> +<!-- block_0 --> +<g id="node8" class="node"> +<title>block_0</title> +<polygon fill="lightblue" stroke="lightblue" points="84,-52 16,-52 16,-16 84,-16 84,-52"/> +<text text-anchor="middle" x="50" y="-30.3" font-family="Times,serif" font-size="14.00">block-0</text> +</g> +<!-- node_1_3 --> +<g id="node9" class="node"> +<title>node_1_3</title> +<polygon fill="yellow" stroke="yellow" points="534,-150 456,-150 456,-114 534,-114 534,-150"/> +<text text-anchor="middle" x="495" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-3</text> +</g> +<!-- node_1_3->block_7 --> +<g id="edge8" class="edge"> +<title>node_1_3->block_7</title> +<path fill="none" stroke="black" d="M534.09,-126.45C557.58,-122.17 587.06,-113.89 609,-98 622.03,-88.56 632.38,-73.89 639.66,-61.08"/> +<polygon fill="black" stroke="black" points="642.78,-62.65 644.41,-52.18 636.61,-59.36 642.78,-62.65"/> +</g> +<!-- node_1_3->block_6 --> +<g id="edge7" class="edge"> +<title>node_1_3->block_6</title> +<path fill="none" stroke="black" d="M510.17,-113.81C514.43,-108.8 518.99,-103.26 523,-98 532.15,-86 541.67,-72.2 549.42,-60.58"/> +<polygon fill="black" stroke="black" points="552.38,-62.46 554.97,-52.19 546.54,-58.6 552.38,-62.46"/> +</g> +<!-- node_1_2 --> +<g id="node10" class="node"> +<title>node_1_2</title> +<polygon fill="yellow" stroke="yellow" points="438,-150 360,-150 360,-114 438,-114 438,-150"/> +<text text-anchor="middle" x="399" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-2</text> +</g> +<!-- node_1_2->block_5 --> +<g id="edge6" class="edge"> +<title>node_1_2->block_5</title> +<path fill="none" stroke="black" d="M420.8,-113.75C426.35,-108.92 432.12,-103.48 437,-98 447.17,-86.57 456.92,-72.62 464.56,-60.76"/> +<polygon fill="black" stroke="black" points="467.6,-62.5 469.96,-52.17 461.67,-58.78 467.6,-62.5"/> +</g> +<!-- node_1_2->block_4 --> +<g id="edge5" class="edge"> +<title>node_1_2->block_4</title> +<path fill="none" stroke="black" d="M398.11,-113.84C397.36,-99.5 396.28,-78.81 395.42,-62.22"/> +<polygon fill="black" stroke="black" points="398.9,-61.82 394.89,-52.01 391.91,-62.18 398.9,-61.82"/> +</g> +<!-- node_1_1 --> +<g id="node11" class="node"> +<title>node_1_1</title> +<polygon fill="yellow" stroke="yellow" points="342,-150 264,-150 264,-114 342,-114 342,-150"/> +<text text-anchor="middle" x="303" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-1</text> +</g> +<!-- node_1_1->block_3 --> +<g id="edge4" class="edge"> +<title>node_1_1->block_3</title> +<path fill="none" stroke="black" d="M303.89,-113.84C304.64,-99.5 305.72,-78.81 306.58,-62.22"/> +<polygon fill="black" stroke="black" points="310.09,-62.18 307.11,-52.01 303.1,-61.82 310.09,-62.18"/> +</g> +<!-- node_1_1->block_2 --> +<g id="edge3" class="edge"> +<title>node_1_1->block_2</title> +<path fill="none" stroke="black" d="M281.2,-113.75C275.65,-108.92 269.88,-103.48 265,-98 254.83,-86.57 245.08,-72.62 237.44,-60.76"/> +<polygon fill="black" stroke="black" points="240.33,-58.78 232.04,-52.17 234.4,-62.5 240.33,-58.78"/> +</g> +<!-- node_1_0 --> +<g id="node12" class="node"> +<title>node_1_0</title> +<polygon fill="yellow" stroke="yellow" points="246,-150 168,-150 168,-114 246,-114 246,-150"/> +<text text-anchor="middle" x="207" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-0</text> +</g> +<!-- node_1_0->block_1 --> +<g id="edge2" class="edge"> +<title>node_1_0->block_1</title> +<path fill="none" stroke="black" d="M191.83,-113.81C187.57,-108.8 183.01,-103.26 179,-98 169.85,-86 160.33,-72.2 152.58,-60.58"/> +<polygon fill="black" stroke="black" points="155.46,-58.6 147.03,-52.19 149.62,-62.46 155.46,-58.6"/> +</g> +<!-- node_1_0->block_0 --> +<g id="edge1" class="edge"> +<title>node_1_0->block_0</title> +<path fill="none" stroke="black" d="M167.91,-126.45C144.42,-122.17 114.94,-113.89 93,-98 79.97,-88.56 69.62,-73.89 62.34,-61.08"/> +<polygon fill="black" stroke="black" points="65.39,-59.36 57.59,-52.18 59.22,-62.65 65.39,-59.36"/> +</g> +<!-- node_2_1 --> +<g id="node13" class="node"> +<title>node_2_1</title> +<polygon fill="orange" stroke="orange" points="438,-233 360,-233 360,-197 438,-197 438,-233"/> +<text text-anchor="middle" x="399" y="-211.3" font-family="Times,serif" font-size="14.00">node-2-1</text> +</g> +<!-- node_2_1->node_1_3 --> +<g id="edge12" class="edge"> +<title>node_2_1->node_1_3</title> +<path fill="none" stroke="black" d="M425.79,-196.86C432.88,-191.98 440.39,-186.5 447,-181 455.56,-173.88 464.34,-165.47 472.02,-157.7"/> +<polygon fill="black" stroke="black" points="474.83,-159.83 479.27,-150.22 469.8,-154.96 474.83,-159.83"/> +</g> +<!-- node_2_1->node_1_2 --> +<g id="edge11" class="edge"> +<title>node_2_1->node_1_2</title> +<path fill="none" stroke="black" d="M399,-196.82C399,-186.19 399,-172.31 399,-160.2"/> +<polygon fill="black" stroke="black" points="402.5,-160.15 399,-150.15 395.5,-160.15 402.5,-160.15"/> +</g> +<!-- node_2_0 --> +<g id="node14" class="node"> +<title>node_2_0</title> +<polygon fill="yellow" stroke="yellow" points="342,-233 264,-233 264,-197 342,-197 342,-233"/> +<text text-anchor="middle" x="303" y="-211.3" font-family="Times,serif" font-size="14.00">node-2-0</text> +</g> +<!-- node_2_0->node_1_1 --> +<g id="edge10" class="edge"> +<title>node_2_0->node_1_1</title> +<path fill="none" stroke="black" d="M303,-196.82C303,-186.19 303,-172.31 303,-160.2"/> +<polygon fill="black" stroke="black" points="306.5,-160.15 303,-150.15 299.5,-160.15 306.5,-160.15"/> +</g> +<!-- node_2_0->node_1_0 --> +<g id="edge9" class="edge"> +<title>node_2_0->node_1_0</title> +<path fill="none" stroke="black" d="M276.21,-196.86C269.12,-191.98 261.61,-186.5 255,-181 246.44,-173.88 237.66,-165.47 229.98,-157.7"/> +<polygon fill="black" stroke="black" points="232.2,-154.96 222.73,-150.22 227.17,-159.83 232.2,-154.96"/> +</g> +<!-- node_3_0 --> +<g id="node15" class="node"> +<title>node_3_0</title> +<polygon fill="orange" stroke="orange" points="390,-316 312,-316 312,-280 390,-280 390,-316"/> +<text text-anchor="middle" x="351" y="-294.3" font-family="Times,serif" font-size="14.00">node-3-0</text> +</g> +<!-- node_3_0->node_2_1 --> +<g id="edge14" class="edge"> +<title>node_3_0->node_2_1</title> +<path fill="none" stroke="black" d="M361.18,-279.82C367.67,-268.87 376.21,-254.46 383.53,-242.11"/> +<polygon fill="black" stroke="black" points="386.75,-243.54 388.84,-233.15 380.73,-239.97 386.75,-243.54"/> +</g> +<!-- node_3_0->node_2_0 --> +<g id="edge13" class="edge"> +<title>node_3_0->node_2_0</title> +<path fill="none" stroke="black" d="M340.82,-279.82C334.33,-268.87 325.79,-254.46 318.47,-242.11"/> +<polygon fill="black" stroke="black" points="321.27,-239.97 313.16,-233.15 315.25,-243.54 321.27,-239.97"/> +</g> +</g> +</svg> diff --git a/doc/images/node-nonce-position-7.svg b/doc/images/node-nonce-position-7.svg new file mode 100644 index 0000000..f3aa1e5 --- /dev/null +++ b/doc/images/node-nonce-position-7.svg @@ -0,0 +1,208 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.42.3 (20191010.1750) + --> +<!-- Title: %3 Pages: 1 --> +<svg width="710pt" height="363pt" + viewBox="0.00 0.00 710.00 363.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 359)"> +<title>%3</title> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-359 706,-359 706,4 -4,4"/> +<g id="clust1" class="cluster"> +<title>cluster__level_0</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="8,-8 8,-98 694,-98 694,-8 8,-8"/> +<text text-anchor="middle" x="62" y="-82.8" font-family="Times,serif" font-size="14.00">level 0</text> +<text text-anchor="middle" x="62" y="-67.8" font-family="Times,serif" font-size="14.00">(data blocks)</text> +</g> +<g id="clust2" class="cluster"> +<title>cluster__level_1</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="160,-106 160,-181 542,-181 542,-106 160,-106"/> +<text text-anchor="middle" x="192" y="-165.8" font-family="Times,serif" font-size="14.00">level 1</text> +</g> +<g id="clust3" class="cluster"> +<title>cluster__level_2</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="256,-189 256,-264 446,-264 446,-189 256,-189"/> +<text text-anchor="middle" x="288" y="-248.8" font-family="Times,serif" font-size="14.00">level 2</text> +</g> +<g id="clust4" class="cluster"> +<title>cluster__level_3</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="304,-272 304,-347 398,-347 398,-272 304,-272"/> +<text text-anchor="middle" x="336" y="-331.8" font-family="Times,serif" font-size="14.00">level 3</text> +</g> +<!-- block_7 --> +<g id="node1" class="node"> +<title>block_7</title> +<polygon fill="lightblue" stroke="lightblue" points="686,-52 618,-52 618,-16 686,-16 686,-52"/> +<text text-anchor="middle" x="652" y="-30.3" font-family="Times,serif" font-size="14.00">block-7</text> +</g> +<!-- block_6 --> +<g id="node2" class="node"> +<title>block_6</title> +<polygon fill="lightblue" stroke="lightblue" points="600,-52 532,-52 532,-16 600,-16 600,-52"/> +<text text-anchor="middle" x="566" y="-30.3" font-family="Times,serif" font-size="14.00">block-6</text> +</g> +<!-- block_5 --> +<g id="node3" class="node"> +<title>block_5</title> +<polygon fill="lightblue" stroke="lightblue" points="514,-52 446,-52 446,-16 514,-16 514,-52"/> +<text text-anchor="middle" x="480" y="-30.3" font-family="Times,serif" font-size="14.00">block-5</text> +</g> +<!-- block_4 --> +<g id="node4" class="node"> +<title>block_4</title> +<polygon fill="lightblue" stroke="lightblue" points="428,-52 360,-52 360,-16 428,-16 428,-52"/> +<text text-anchor="middle" x="394" y="-30.3" font-family="Times,serif" font-size="14.00">block-4</text> +</g> +<!-- block_3 --> +<g id="node5" class="node"> +<title>block_3</title> +<polygon fill="lightblue" stroke="lightblue" points="342,-52 274,-52 274,-16 342,-16 342,-52"/> +<text text-anchor="middle" x="308" y="-30.3" font-family="Times,serif" font-size="14.00">block-3</text> +</g> +<!-- block_2 --> +<g id="node6" class="node"> +<title>block_2</title> +<polygon fill="lightblue" stroke="lightblue" points="256,-52 188,-52 188,-16 256,-16 256,-52"/> +<text text-anchor="middle" x="222" y="-30.3" font-family="Times,serif" font-size="14.00">block-2</text> +</g> +<!-- block_1 --> +<g id="node7" class="node"> +<title>block_1</title> +<polygon fill="lightblue" stroke="lightblue" points="170,-52 102,-52 102,-16 170,-16 170,-52"/> +<text text-anchor="middle" x="136" y="-30.3" font-family="Times,serif" font-size="14.00">block-1</text> +</g> +<!-- block_0 --> +<g id="node8" class="node"> +<title>block_0</title> +<polygon fill="lightblue" stroke="lightblue" points="84,-52 16,-52 16,-16 84,-16 84,-52"/> +<text text-anchor="middle" x="50" y="-30.3" font-family="Times,serif" font-size="14.00">block-0</text> +</g> +<!-- node_1_3 --> +<g id="node9" class="node"> +<title>node_1_3</title> +<polygon fill="yellow" stroke="yellow" points="534,-150 456,-150 456,-114 534,-114 534,-150"/> +<text text-anchor="middle" x="495" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-3</text> +</g> +<!-- node_1_3->block_7 --> +<g id="edge8" class="edge"> +<title>node_1_3->block_7</title> +<path fill="none" stroke="black" d="M534.09,-126.45C557.58,-122.17 587.06,-113.89 609,-98 622.03,-88.56 632.38,-73.89 639.66,-61.08"/> +<polygon fill="black" stroke="black" points="642.78,-62.65 644.41,-52.18 636.61,-59.36 642.78,-62.65"/> +</g> +<!-- node_1_3->block_6 --> +<g id="edge7" class="edge"> +<title>node_1_3->block_6</title> +<path fill="none" stroke="black" d="M510.17,-113.81C514.43,-108.8 518.99,-103.26 523,-98 532.15,-86 541.67,-72.2 549.42,-60.58"/> +<polygon fill="black" stroke="black" points="552.38,-62.46 554.97,-52.19 546.54,-58.6 552.38,-62.46"/> +</g> +<!-- node_1_2 --> +<g id="node10" class="node"> +<title>node_1_2</title> +<polygon fill="yellow" stroke="yellow" points="438,-150 360,-150 360,-114 438,-114 438,-150"/> +<text text-anchor="middle" x="399" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-2</text> +</g> +<!-- node_1_2->block_5 --> +<g id="edge6" class="edge"> +<title>node_1_2->block_5</title> +<path fill="none" stroke="black" d="M420.8,-113.75C426.35,-108.92 432.12,-103.48 437,-98 447.17,-86.57 456.92,-72.62 464.56,-60.76"/> +<polygon fill="black" stroke="black" points="467.6,-62.5 469.96,-52.17 461.67,-58.78 467.6,-62.5"/> +</g> +<!-- node_1_2->block_4 --> +<g id="edge5" class="edge"> +<title>node_1_2->block_4</title> +<path fill="none" stroke="black" d="M398.11,-113.84C397.36,-99.5 396.28,-78.81 395.42,-62.22"/> +<polygon fill="black" stroke="black" points="398.9,-61.82 394.89,-52.01 391.91,-62.18 398.9,-61.82"/> +</g> +<!-- node_1_1 --> +<g id="node11" class="node"> +<title>node_1_1</title> +<polygon fill="yellow" stroke="yellow" points="342,-150 264,-150 264,-114 342,-114 342,-150"/> +<text text-anchor="middle" x="303" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-1</text> +</g> +<!-- node_1_1->block_3 --> +<g id="edge4" class="edge"> +<title>node_1_1->block_3</title> +<path fill="none" stroke="black" d="M303.89,-113.84C304.64,-99.5 305.72,-78.81 306.58,-62.22"/> +<polygon fill="black" stroke="black" points="310.09,-62.18 307.11,-52.01 303.1,-61.82 310.09,-62.18"/> +</g> +<!-- node_1_1->block_2 --> +<g id="edge3" class="edge"> +<title>node_1_1->block_2</title> +<path fill="none" stroke="black" d="M281.2,-113.75C275.65,-108.92 269.88,-103.48 265,-98 254.83,-86.57 245.08,-72.62 237.44,-60.76"/> +<polygon fill="black" stroke="black" points="240.33,-58.78 232.04,-52.17 234.4,-62.5 240.33,-58.78"/> +</g> +<!-- node_1_0 --> +<g id="node12" class="node"> +<title>node_1_0</title> +<polygon fill="yellow" stroke="yellow" points="246,-150 168,-150 168,-114 246,-114 246,-150"/> +<text text-anchor="middle" x="207" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-0</text> +</g> +<!-- node_1_0->block_1 --> +<g id="edge2" class="edge"> +<title>node_1_0->block_1</title> +<path fill="none" stroke="black" d="M191.83,-113.81C187.57,-108.8 183.01,-103.26 179,-98 169.85,-86 160.33,-72.2 152.58,-60.58"/> +<polygon fill="black" stroke="black" points="155.46,-58.6 147.03,-52.19 149.62,-62.46 155.46,-58.6"/> +</g> +<!-- node_1_0->block_0 --> +<g id="edge1" class="edge"> +<title>node_1_0->block_0</title> +<path fill="none" stroke="black" d="M167.91,-126.45C144.42,-122.17 114.94,-113.89 93,-98 79.97,-88.56 69.62,-73.89 62.34,-61.08"/> +<polygon fill="black" stroke="black" points="65.39,-59.36 57.59,-52.18 59.22,-62.65 65.39,-59.36"/> +</g> +<!-- node_2_1 --> +<g id="node13" class="node"> +<title>node_2_1</title> +<polygon fill="yellow" stroke="yellow" points="438,-233 360,-233 360,-197 438,-197 438,-233"/> +<text text-anchor="middle" x="399" y="-211.3" font-family="Times,serif" font-size="14.00">node-2-1</text> +</g> +<!-- node_2_1->node_1_3 --> +<g id="edge12" class="edge"> +<title>node_2_1->node_1_3</title> +<path fill="none" stroke="black" d="M425.79,-196.86C432.88,-191.98 440.39,-186.5 447,-181 455.56,-173.88 464.34,-165.47 472.02,-157.7"/> +<polygon fill="black" stroke="black" points="474.83,-159.83 479.27,-150.22 469.8,-154.96 474.83,-159.83"/> +</g> +<!-- node_2_1->node_1_2 --> +<g id="edge11" class="edge"> +<title>node_2_1->node_1_2</title> +<path fill="none" stroke="black" d="M399,-196.82C399,-186.19 399,-172.31 399,-160.2"/> +<polygon fill="black" stroke="black" points="402.5,-160.15 399,-150.15 395.5,-160.15 402.5,-160.15"/> +</g> +<!-- node_2_0 --> +<g id="node14" class="node"> +<title>node_2_0</title> +<polygon fill="yellow" stroke="yellow" points="342,-233 264,-233 264,-197 342,-197 342,-233"/> +<text text-anchor="middle" x="303" y="-211.3" font-family="Times,serif" font-size="14.00">node-2-0</text> +</g> +<!-- node_2_0->node_1_1 --> +<g id="edge10" class="edge"> +<title>node_2_0->node_1_1</title> +<path fill="none" stroke="black" d="M303,-196.82C303,-186.19 303,-172.31 303,-160.2"/> +<polygon fill="black" stroke="black" points="306.5,-160.15 303,-150.15 299.5,-160.15 306.5,-160.15"/> +</g> +<!-- node_2_0->node_1_0 --> +<g id="edge9" class="edge"> +<title>node_2_0->node_1_0</title> +<path fill="none" stroke="black" d="M276.21,-196.86C269.12,-191.98 261.61,-186.5 255,-181 246.44,-173.88 237.66,-165.47 229.98,-157.7"/> +<polygon fill="black" stroke="black" points="232.2,-154.96 222.73,-150.22 227.17,-159.83 232.2,-154.96"/> +</g> +<!-- node_3_0 --> +<g id="node15" class="node"> +<title>node_3_0</title> +<polygon fill="orange" stroke="orange" points="390,-316 312,-316 312,-280 390,-280 390,-316"/> +<text text-anchor="middle" x="351" y="-294.3" font-family="Times,serif" font-size="14.00">node-3-0</text> +</g> +<!-- node_3_0->node_2_1 --> +<g id="edge14" class="edge"> +<title>node_3_0->node_2_1</title> +<path fill="none" stroke="black" d="M361.18,-279.82C367.67,-268.87 376.21,-254.46 383.53,-242.11"/> +<polygon fill="black" stroke="black" points="386.75,-243.54 388.84,-233.15 380.73,-239.97 386.75,-243.54"/> +</g> +<!-- node_3_0->node_2_0 --> +<g id="edge13" class="edge"> +<title>node_3_0->node_2_0</title> +<path fill="none" stroke="black" d="M340.82,-279.82C334.33,-268.87 325.79,-254.46 318.47,-242.11"/> +<polygon fill="black" stroke="black" points="321.27,-239.97 313.16,-233.15 315.25,-243.54 321.27,-239.97"/> +</g> +</g> +</svg> diff --git a/doc/images/node-nonce-position.svg b/doc/images/node-nonce-position.svg new file mode 100644 index 0000000..9efb132 --- /dev/null +++ b/doc/images/node-nonce-position.svg @@ -0,0 +1,208 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.42.3 (20191010.1750) + --> +<!-- Title: %3 Pages: 1 --> +<svg width="710pt" height="363pt" + viewBox="0.00 0.00 710.00 363.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 359)"> +<title>%3</title> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-359 706,-359 706,4 -4,4"/> +<g id="clust1" class="cluster"> +<title>cluster__level_0</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="8,-8 8,-98 694,-98 694,-8 8,-8"/> +<text text-anchor="middle" x="62" y="-82.8" font-family="Times,serif" font-size="14.00">level 0</text> +<text text-anchor="middle" x="62" y="-67.8" font-family="Times,serif" font-size="14.00">(data blocks)</text> +</g> +<g id="clust2" class="cluster"> +<title>cluster__level_1</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="160,-106 160,-181 542,-181 542,-106 160,-106"/> +<text text-anchor="middle" x="192" y="-165.8" font-family="Times,serif" font-size="14.00">level 1</text> +</g> +<g id="clust3" class="cluster"> +<title>cluster__level_2</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="256,-189 256,-264 446,-264 446,-189 256,-189"/> +<text text-anchor="middle" x="288" y="-248.8" font-family="Times,serif" font-size="14.00">level 2</text> +</g> +<g id="clust4" class="cluster"> +<title>cluster__level_3</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="304,-272 304,-347 398,-347 398,-272 304,-272"/> +<text text-anchor="middle" x="336" y="-331.8" font-family="Times,serif" font-size="14.00">level 3</text> +</g> +<!-- block_7 --> +<g id="node1" class="node"> +<title>block_7</title> +<polygon fill="lightblue" stroke="lightblue" points="686,-52 618,-52 618,-16 686,-16 686,-52"/> +<text text-anchor="middle" x="652" y="-30.3" font-family="Times,serif" font-size="14.00">block-7</text> +</g> +<!-- block_6 --> +<g id="node2" class="node"> +<title>block_6</title> +<polygon fill="lightblue" stroke="lightblue" points="600,-52 532,-52 532,-16 600,-16 600,-52"/> +<text text-anchor="middle" x="566" y="-30.3" font-family="Times,serif" font-size="14.00">block-6</text> +</g> +<!-- block_5 --> +<g id="node3" class="node"> +<title>block_5</title> +<polygon fill="lightblue" stroke="lightblue" points="514,-52 446,-52 446,-16 514,-16 514,-52"/> +<text text-anchor="middle" x="480" y="-30.3" font-family="Times,serif" font-size="14.00">block-5</text> +</g> +<!-- block_4 --> +<g id="node4" class="node"> +<title>block_4</title> +<polygon fill="lightblue" stroke="lightblue" points="428,-52 360,-52 360,-16 428,-16 428,-52"/> +<text text-anchor="middle" x="394" y="-30.3" font-family="Times,serif" font-size="14.00">block-4</text> +</g> +<!-- block_3 --> +<g id="node5" class="node"> +<title>block_3</title> +<polygon fill="lightblue" stroke="lightblue" points="342,-52 274,-52 274,-16 342,-16 342,-52"/> +<text text-anchor="middle" x="308" y="-30.3" font-family="Times,serif" font-size="14.00">block-3</text> +</g> +<!-- block_2 --> +<g id="node6" class="node"> +<title>block_2</title> +<polygon fill="lightblue" stroke="lightblue" points="256,-52 188,-52 188,-16 256,-16 256,-52"/> +<text text-anchor="middle" x="222" y="-30.3" font-family="Times,serif" font-size="14.00">block-2</text> +</g> +<!-- block_1 --> +<g id="node7" class="node"> +<title>block_1</title> +<polygon fill="lightblue" stroke="lightblue" points="170,-52 102,-52 102,-16 170,-16 170,-52"/> +<text text-anchor="middle" x="136" y="-30.3" font-family="Times,serif" font-size="14.00">block-1</text> +</g> +<!-- block_0 --> +<g id="node8" class="node"> +<title>block_0</title> +<polygon fill="lightblue" stroke="lightblue" points="84,-52 16,-52 16,-16 84,-16 84,-52"/> +<text text-anchor="middle" x="50" y="-30.3" font-family="Times,serif" font-size="14.00">block-0</text> +</g> +<!-- node_1_3 --> +<g id="node9" class="node"> +<title>node_1_3</title> +<polygon fill="lightgrey" stroke="lightgrey" points="534,-150 456,-150 456,-114 534,-114 534,-150"/> +<text text-anchor="middle" x="495" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-3</text> +</g> +<!-- node_1_3->block_7 --> +<g id="edge8" class="edge"> +<title>node_1_3->block_7</title> +<path fill="none" stroke="black" d="M534.09,-126.45C557.58,-122.17 587.06,-113.89 609,-98 622.03,-88.56 632.38,-73.89 639.66,-61.08"/> +<polygon fill="black" stroke="black" points="642.78,-62.65 644.41,-52.18 636.61,-59.36 642.78,-62.65"/> +</g> +<!-- node_1_3->block_6 --> +<g id="edge7" class="edge"> +<title>node_1_3->block_6</title> +<path fill="none" stroke="black" d="M510.17,-113.81C514.43,-108.8 518.99,-103.26 523,-98 532.15,-86 541.67,-72.2 549.42,-60.58"/> +<polygon fill="black" stroke="black" points="552.38,-62.46 554.97,-52.19 546.54,-58.6 552.38,-62.46"/> +</g> +<!-- node_1_2 --> +<g id="node10" class="node"> +<title>node_1_2</title> +<polygon fill="lightgrey" stroke="lightgrey" points="438,-150 360,-150 360,-114 438,-114 438,-150"/> +<text text-anchor="middle" x="399" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-2</text> +</g> +<!-- node_1_2->block_5 --> +<g id="edge6" class="edge"> +<title>node_1_2->block_5</title> +<path fill="none" stroke="black" d="M420.8,-113.75C426.35,-108.92 432.12,-103.48 437,-98 447.17,-86.57 456.92,-72.62 464.56,-60.76"/> +<polygon fill="black" stroke="black" points="467.6,-62.5 469.96,-52.17 461.67,-58.78 467.6,-62.5"/> +</g> +<!-- node_1_2->block_4 --> +<g id="edge5" class="edge"> +<title>node_1_2->block_4</title> +<path fill="none" stroke="black" d="M398.11,-113.84C397.36,-99.5 396.28,-78.81 395.42,-62.22"/> +<polygon fill="black" stroke="black" points="398.9,-61.82 394.89,-52.01 391.91,-62.18 398.9,-61.82"/> +</g> +<!-- node_1_1 --> +<g id="node11" class="node"> +<title>node_1_1</title> +<polygon fill="lightgrey" stroke="lightgrey" points="342,-150 264,-150 264,-114 342,-114 342,-150"/> +<text text-anchor="middle" x="303" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-1</text> +</g> +<!-- node_1_1->block_3 --> +<g id="edge4" class="edge"> +<title>node_1_1->block_3</title> +<path fill="none" stroke="black" d="M303.89,-113.84C304.64,-99.5 305.72,-78.81 306.58,-62.22"/> +<polygon fill="black" stroke="black" points="310.09,-62.18 307.11,-52.01 303.1,-61.82 310.09,-62.18"/> +</g> +<!-- node_1_1->block_2 --> +<g id="edge3" class="edge"> +<title>node_1_1->block_2</title> +<path fill="none" stroke="black" d="M281.2,-113.75C275.65,-108.92 269.88,-103.48 265,-98 254.83,-86.57 245.08,-72.62 237.44,-60.76"/> +<polygon fill="black" stroke="black" points="240.33,-58.78 232.04,-52.17 234.4,-62.5 240.33,-58.78"/> +</g> +<!-- node_1_0 --> +<g id="node12" class="node"> +<title>node_1_0</title> +<polygon fill="orange" stroke="orange" points="246,-150 168,-150 168,-114 246,-114 246,-150"/> +<text text-anchor="middle" x="207" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-0</text> +</g> +<!-- node_1_0->block_1 --> +<g id="edge2" class="edge"> +<title>node_1_0->block_1</title> +<path fill="none" stroke="black" d="M191.83,-113.81C187.57,-108.8 183.01,-103.26 179,-98 169.85,-86 160.33,-72.2 152.58,-60.58"/> +<polygon fill="black" stroke="black" points="155.46,-58.6 147.03,-52.19 149.62,-62.46 155.46,-58.6"/> +</g> +<!-- node_1_0->block_0 --> +<g id="edge1" class="edge"> +<title>node_1_0->block_0</title> +<path fill="none" stroke="black" d="M167.91,-126.45C144.42,-122.17 114.94,-113.89 93,-98 79.97,-88.56 69.62,-73.89 62.34,-61.08"/> +<polygon fill="black" stroke="black" points="65.39,-59.36 57.59,-52.18 59.22,-62.65 65.39,-59.36"/> +</g> +<!-- node_2_1 --> +<g id="node13" class="node"> +<title>node_2_1</title> +<polygon fill="lightgrey" stroke="lightgrey" points="438,-233 360,-233 360,-197 438,-197 438,-233"/> +<text text-anchor="middle" x="399" y="-211.3" font-family="Times,serif" font-size="14.00">node-2-1</text> +</g> +<!-- node_2_1->node_1_3 --> +<g id="edge12" class="edge"> +<title>node_2_1->node_1_3</title> +<path fill="none" stroke="black" d="M425.79,-196.86C432.88,-191.98 440.39,-186.5 447,-181 455.56,-173.88 464.34,-165.47 472.02,-157.7"/> +<polygon fill="black" stroke="black" points="474.83,-159.83 479.27,-150.22 469.8,-154.96 474.83,-159.83"/> +</g> +<!-- node_2_1->node_1_2 --> +<g id="edge11" class="edge"> +<title>node_2_1->node_1_2</title> +<path fill="none" stroke="black" d="M399,-196.82C399,-186.19 399,-172.31 399,-160.2"/> +<polygon fill="black" stroke="black" points="402.5,-160.15 399,-150.15 395.5,-160.15 402.5,-160.15"/> +</g> +<!-- node_2_0 --> +<g id="node14" class="node"> +<title>node_2_0</title> +<polygon fill="orange" stroke="orange" points="342,-233 264,-233 264,-197 342,-197 342,-233"/> +<text text-anchor="middle" x="303" y="-211.3" font-family="Times,serif" font-size="14.00">node-2-0</text> +</g> +<!-- node_2_0->node_1_1 --> +<g id="edge10" class="edge"> +<title>node_2_0->node_1_1</title> +<path fill="none" stroke="black" d="M303,-196.82C303,-186.19 303,-172.31 303,-160.2"/> +<polygon fill="black" stroke="black" points="306.5,-160.15 303,-150.15 299.5,-160.15 306.5,-160.15"/> +</g> +<!-- node_2_0->node_1_0 --> +<g id="edge9" class="edge"> +<title>node_2_0->node_1_0</title> +<path fill="none" stroke="black" d="M276.21,-196.86C269.12,-191.98 261.61,-186.5 255,-181 246.44,-173.88 237.66,-165.47 229.98,-157.7"/> +<polygon fill="black" stroke="black" points="232.2,-154.96 222.73,-150.22 227.17,-159.83 232.2,-154.96"/> +</g> +<!-- node_3_0 --> +<g id="node15" class="node"> +<title>node_3_0</title> +<polygon fill="orange" stroke="orange" points="390,-316 312,-316 312,-280 390,-280 390,-316"/> +<text text-anchor="middle" x="351" y="-294.3" font-family="Times,serif" font-size="14.00">node-3-0</text> +</g> +<!-- node_3_0->node_2_1 --> +<g id="edge14" class="edge"> +<title>node_3_0->node_2_1</title> +<path fill="none" stroke="black" d="M361.18,-279.82C367.67,-268.87 376.21,-254.46 383.53,-242.11"/> +<polygon fill="black" stroke="black" points="386.75,-243.54 388.84,-233.15 380.73,-239.97 386.75,-243.54"/> +</g> +<!-- node_3_0->node_2_0 --> +<g id="edge13" class="edge"> +<title>node_3_0->node_2_0</title> +<path fill="none" stroke="black" d="M340.82,-279.82C334.33,-268.87 325.79,-254.46 318.47,-242.11"/> +<polygon fill="black" stroke="black" points="321.27,-239.97 313.16,-233.15 315.25,-243.54 321.27,-239.97"/> +</g> +</g> +</svg> diff --git a/doc/images/rdf-graph.svg b/doc/images/rdf-graph.svg new file mode 100644 index 0000000..60b97a3 --- /dev/null +++ b/doc/images/rdf-graph.svg @@ -0,0 +1,175 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.40.1 (20161225.0304) + --> +<!-- Title: %3 Pages: 1 --> +<svg width="1795pt" height="341pt" + viewBox="0.00 0.00 1795.47 341.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 337)"> +<title>%3</title> +<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-337 1791.4729,-337 1791.4729,4 -4,4"/> +<!-- alice --> +<g id="node1" class="node"> +<title>alice</title> +<ellipse fill="none" stroke="#000000" cx="628.8547" cy="-315" rx="128.0773" ry="18"/> +<text text-anchor="middle" x="628.8547" y="-311.3" font-family="sans-serif" font-size="14.00" fill="#000000">https://test.example/alice</text> +</g> +<!-- as:Person --> +<g id="node2" class="node"> +<title>as:Person</title> +<ellipse fill="none" stroke="#000000" cx="1253.6603" cy="-315" rx="55.7903" ry="18"/> +<text text-anchor="middle" x="1253.6603" y="-311.3" font-family="sans-serif" font-size="14.00" fill="#000000">as:Person</text> +</g> +<!-- alice->as:Person --> +<g id="edge1" class="edge"> +<title>alice->as:Person</title> +<path fill="none" stroke="#000000" d="M757.179,-315C887.8639,-315 1085.354,-315 1187.4007,-315"/> +<polygon fill="#000000" stroke="#000000" points="1187.5703,-318.5001 1197.5703,-315 1187.5702,-311.5001 1187.5703,-318.5001"/> +<text text-anchor="middle" x="918.8345" y="-318.8" font-family="Times,serif" font-size="14.00" fill="#000000">rdf:type</text> +</g> +<!-- note_1 --> +<g id="node3" class="node"> +<title>note_1</title> +<ellipse fill="none" stroke="#000000" cx="141.6874" cy="-207" rx="141.8751" ry="18"/> +<text text-anchor="middle" x="141.6874" y="-203.3" font-family="sans-serif" font-size="14.00" fill="#000000">https://test.example/notes/1</text> +</g> +<!-- note_1->alice --> +<g id="edge3" class="edge"> +<title>note_1->alice</title> +<path fill="none" stroke="#000000" d="M187.4448,-224.0956C238.7955,-242.6136 324.9355,-271.688 401.3749,-288 435.6244,-295.3088 473.2271,-300.7841 507.8238,-304.8225"/> +<polygon fill="#000000" stroke="#000000" points="507.6438,-308.3245 517.9752,-305.9768 508.4347,-301.3693 507.6438,-308.3245"/> +<text text-anchor="middle" x="342.3749" y="-286.8" font-family="Times,serif" font-size="14.00" fill="#000000">as:attributedTo</text> +</g> +<!-- as:Note --> +<g id="node4" class="node"> +<title>as:Note</title> +<ellipse fill="none" stroke="#000000" cx="628.8547" cy="-261" rx="46.2923" ry="18"/> +<text text-anchor="middle" x="628.8547" y="-257.3" font-family="sans-serif" font-size="14.00" fill="#000000">as:Note</text> +</g> +<!-- note_1->as:Note --> +<g id="edge2" class="edge"> +<title>note_1->as:Note</title> +<path fill="none" stroke="#000000" d="M244.7476,-219.4456C263.5817,-221.6679 283.0647,-223.9323 301.3749,-226 397.2382,-236.8254 508.9903,-248.5847 574.0461,-255.3444"/> +<polygon fill="#000000" stroke="#000000" points="573.7687,-258.8343 584.0766,-256.3855 574.4914,-251.8717 573.7687,-258.8343"/> +<text text-anchor="middle" x="342.3749" y="-237.8" font-family="Times,serif" font-size="14.00" fill="#000000">rdf:type</text> +</g> +<!-- note_content --> +<g id="node5" class="node"> +<title>note_content</title> +<polygon fill="none" stroke="#000000" points="795.3547,-225 462.3547,-225 462.3547,-189 795.3547,-189 795.3547,-225"/> +<text text-anchor="middle" x="628.8547" y="-203.3" font-family="sans-serif" font-size="14.00" fill="#000000">"The clowns just went trough the loop!"@en</text> +</g> +<!-- note_1->note_content --> +<g id="edge4" class="edge"> +<title>note_1->note_content</title> +<path fill="none" stroke="#000000" d="M283.5783,-207C336.2003,-207 396.5398,-207 451.9041,-207"/> +<polygon fill="#000000" stroke="#000000" points="452.181,-210.5001 462.1809,-207 452.1809,-203.5001 452.181,-210.5001"/> +<text text-anchor="middle" x="342.3749" y="-210.8" font-family="Times,serif" font-size="14.00" fill="#000000">as:content</text> +</g> +<!-- note_1_image --> +<g id="node6" class="node"> +<title>note_1_image</title> +<ellipse fill="none" stroke="#000000" cx="628.8547" cy="-153" rx="173.5692" ry="18"/> +<text text-anchor="middle" x="628.8547" y="-149.3" font-family="sans-serif" font-size="14.00" fill="#000000">https://test.example/note/1#image</text> +</g> +<!-- note_1->note_1_image --> +<g id="edge5" class="edge"> +<title>note_1->note_1_image</title> +<path fill="none" stroke="#000000" d="M244.7476,-194.5544C263.5817,-192.3321 283.0647,-190.0677 301.3749,-188 365.2893,-180.7824 436.2667,-173.1498 495.7583,-166.8604"/> +<polygon fill="#000000" stroke="#000000" points="496.3873,-170.3136 505.9644,-165.7827 495.6521,-163.3523 496.3873,-170.3136"/> +<text text-anchor="middle" x="342.3749" y="-191.8" font-family="Times,serif" font-size="14.00" fill="#000000">as:image</text> +</g> +<!-- event --> +<g id="node7" class="node"> +<title>event</title> +<ellipse fill="none" stroke="#000000" cx="628.8547" cy="-99" rx="227.4596" ry="18"/> +<text text-anchor="middle" x="628.8547" y="-95.3" font-family="sans-serif" font-size="14.00" fill="#000000">https://circus.show/performance-in-funky-town</text> +</g> +<!-- note_1->event --> +<g id="edge6" class="edge"> +<title>note_1->event</title> +<path fill="none" stroke="#000000" d="M187.4448,-189.9044C238.7955,-171.3864 324.9355,-142.312 401.3749,-126 423.4961,-121.2794 447.0162,-117.3236 470.2216,-114.0258"/> +<polygon fill="#000000" stroke="#000000" points="470.717,-117.4907 480.1426,-112.6525 469.7571,-110.5568 470.717,-117.4907"/> +<text text-anchor="middle" x="342.3749" y="-153.8" font-family="Times,serif" font-size="14.00" fill="#000000">as:context</text> +</g> +<!-- as:Image --> +<g id="node8" class="node"> +<title>as:Image</title> +<ellipse fill="none" stroke="#000000" cx="1253.6603" cy="-207" rx="53.8905" ry="18"/> +<text text-anchor="middle" x="1253.6603" y="-203.3" font-family="sans-serif" font-size="14.00" fill="#000000">as:Image</text> +</g> +<!-- note_1_image->as:Image --> +<g id="edge7" class="edge"> +<title>note_1_image->as:Image</title> +<path fill="none" stroke="#000000" d="M762.5078,-164.5512C894.7681,-175.9821 1091.4495,-192.9806 1191.0327,-201.5873"/> +<polygon fill="#000000" stroke="#000000" points="1190.969,-205.0947 1201.2333,-202.4689 1191.5718,-198.1207 1190.969,-205.0947"/> +<text text-anchor="middle" x="918.8345" y="-184.8" font-family="Times,serif" font-size="14.00" fill="#000000">rdf:type</text> +</g> +<!-- https://test.example/images/1.jpg --> +<g id="node9" class="node"> +<title>https://test.example/images/1.jpg</title> +<ellipse fill="none" stroke="#000000" cx="1253.6603" cy="-153" rx="167.0704" ry="18"/> +<text text-anchor="middle" x="1253.6603" y="-149.3" font-family="sans-serif" font-size="14.00" fill="#000000">https://test.example/images/1.jpg</text> +</g> +<!-- note_1_image->https://test.example/images/1.jpg --> +<g id="edge8" class="edge"> +<title>note_1_image->https://test.example/images/1.jpg</title> +<path fill="none" stroke="#000000" d="M802.4829,-153C887.8474,-153 990.5624,-153 1076.4096,-153"/> +<polygon fill="#000000" stroke="#000000" points="1076.5252,-156.5001 1086.5252,-153 1076.5251,-149.5001 1076.5252,-156.5001"/> +<text text-anchor="middle" x="918.8345" y="-156.8" font-family="Times,serif" font-size="14.00" fill="#000000">as:url</text> +</g> +<!-- schema:Event --> +<g id="node10" class="node"> +<title>schema:Event</title> +<ellipse fill="none" stroke="#000000" cx="1253.6603" cy="-99" rx="76.8869" ry="18"/> +<text text-anchor="middle" x="1253.6603" y="-95.3" font-family="sans-serif" font-size="14.00" fill="#000000">schema:Event</text> +</g> +<!-- event->schema:Event --> +<g id="edge9" class="edge"> +<title>event->schema:Event</title> +<path fill="none" stroke="#000000" d="M856.6336,-99C964.3288,-99 1086.5354,-99 1166.576,-99"/> +<polygon fill="#000000" stroke="#000000" points="1166.6102,-102.5001 1176.6102,-99 1166.6101,-95.5001 1166.6102,-102.5001"/> +<text text-anchor="middle" x="918.8345" y="-102.8" font-family="Times,serif" font-size="14.00" fill="#000000">rdf:type</text> +</g> +<!-- event_location --> +<g id="node11" class="node"> +<title>event_location</title> +<ellipse fill="none" stroke="#000000" cx="1253.6603" cy="-45" rx="272.1518" ry="18"/> +<text text-anchor="middle" x="1253.6603" y="-41.3" font-family="sans-serif" font-size="14.00" fill="#000000">https://circus.show/performance-in-funky-town#location</text> +</g> +<!-- event->event_location --> +<g id="edge10" class="edge"> +<title>event->event_location</title> +<path fill="none" stroke="#000000" d="M782.4996,-85.721C871.9215,-77.9925 984.9791,-68.2213 1077.9305,-60.1878"/> +<polygon fill="#000000" stroke="#000000" points="1078.3475,-63.6649 1088.009,-59.3167 1077.7447,-56.6909 1078.3475,-63.6649"/> +<text text-anchor="middle" x="918.8345" y="-79.8" font-family="Times,serif" font-size="14.00" fill="#000000">schema:location</text> +</g> +<!-- schema:Place --> +<g id="node12" class="node"> +<title>schema:Place</title> +<ellipse fill="none" stroke="#000000" cx="1712.7295" cy="-72" rx="74.9875" ry="18"/> +<text text-anchor="middle" x="1712.7295" y="-68.3" font-family="sans-serif" font-size="14.00" fill="#000000">schema:Place</text> +</g> +<!-- event_location->schema:Place --> +<g id="edge11" class="edge"> +<title>event_location->schema:Place</title> +<path fill="none" stroke="#000000" d="M1457.3538,-56.9802C1518.2093,-60.5594 1581.519,-64.2829 1629.8786,-67.1272"/> +<polygon fill="#000000" stroke="#000000" points="1629.7766,-70.6271 1639.9649,-67.7204 1630.1877,-63.6392 1629.7766,-70.6271"/> +<text text-anchor="middle" x="1581.9862" y="-69.8" font-family="Times,serif" font-size="14.00" fill="#000000">rdf:type</text> +</g> +<!-- event_location_name --> +<g id="node13" class="node"> +<title>event_location_name</title> +<polygon fill="none" stroke="#000000" points="1758.2295,-36 1667.2295,-36 1667.2295,0 1758.2295,0 1758.2295,-36"/> +<text text-anchor="middle" x="1712.7295" y="-14.3" font-family="sans-serif" font-size="14.00" fill="#000000">"The Tent"</text> +</g> +<!-- event_location->event_location_name --> +<g id="edge12" class="edge"> +<title>event_location->event_location_name</title> +<path fill="none" stroke="#000000" d="M1457.3538,-33.0198C1530.2909,-28.7301 1606.7533,-24.233 1656.7772,-21.2908"/> +<polygon fill="#000000" stroke="#000000" points="1657.2624,-24.7684 1667.0397,-20.6872 1656.8514,-17.7805 1657.2624,-24.7684"/> +<text text-anchor="middle" x="1581.9862" y="-30.8" font-family="Times,serif" font-size="14.00" fill="#000000">schema:name</text> +</g> +</g> +</svg> diff --git a/doc/images/tree-level-1.svg b/doc/images/tree-level-1.svg new file mode 100644 index 0000000..e17dcfb --- /dev/null +++ b/doc/images/tree-level-1.svg @@ -0,0 +1,90 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.42.3 (20191010.1750) + --> +<!-- Title: %3 Pages: 1 --> +<svg width="710pt" height="197pt" + viewBox="0.00 0.00 710.00 197.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 193)"> +<title>%3</title> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-193 706,-193 706,4 -4,4"/> +<g id="clust1" class="cluster"> +<title>cluster__level_0</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="8,-8 8,-98 694,-98 694,-8 8,-8"/> +<text text-anchor="middle" x="62" y="-82.8" font-family="Times,serif" font-size="14.00">level 0</text> +<text text-anchor="middle" x="62" y="-67.8" font-family="Times,serif" font-size="14.00">(data blocks)</text> +</g> +<g id="clust2" class="cluster"> +<title>cluster__level_1</title> +<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="47,-106 47,-181 141,-181 141,-106 47,-106"/> +<text text-anchor="middle" x="79" y="-165.8" font-family="Times,serif" font-size="14.00">level 1</text> +</g> +<!-- block_7 --> +<g id="node1" class="node"> +<title>block_7</title> +<polygon fill="lightblue" stroke="lightblue" points="686,-52 618,-52 618,-16 686,-16 686,-52"/> +<text text-anchor="middle" x="652" y="-30.3" font-family="Times,serif" font-size="14.00">block-7</text> +</g> +<!-- block_6 --> +<g id="node2" class="node"> +<title>block_6</title> +<polygon fill="lightblue" stroke="lightblue" points="600,-52 532,-52 532,-16 600,-16 600,-52"/> +<text text-anchor="middle" x="566" y="-30.3" font-family="Times,serif" font-size="14.00">block-6</text> +</g> +<!-- block_5 --> +<g id="node3" class="node"> +<title>block_5</title> +<polygon fill="lightblue" stroke="lightblue" points="514,-52 446,-52 446,-16 514,-16 514,-52"/> +<text text-anchor="middle" x="480" y="-30.3" font-family="Times,serif" font-size="14.00">block-5</text> +</g> +<!-- block_4 --> +<g id="node4" class="node"> +<title>block_4</title> +<polygon fill="lightblue" stroke="lightblue" points="428,-52 360,-52 360,-16 428,-16 428,-52"/> +<text text-anchor="middle" x="394" y="-30.3" font-family="Times,serif" font-size="14.00">block-4</text> +</g> +<!-- block_3 --> +<g id="node5" class="node"> +<title>block_3</title> +<polygon fill="lightblue" stroke="lightblue" points="342,-52 274,-52 274,-16 342,-16 342,-52"/> +<text text-anchor="middle" x="308" y="-30.3" font-family="Times,serif" font-size="14.00">block-3</text> +</g> +<!-- block_2 --> +<g id="node6" class="node"> +<title>block_2</title> +<polygon fill="lightblue" stroke="lightblue" points="256,-52 188,-52 188,-16 256,-16 256,-52"/> +<text text-anchor="middle" x="222" y="-30.3" font-family="Times,serif" font-size="14.00">block-2</text> +</g> +<!-- block_1 --> +<g id="node7" class="node"> +<title>block_1</title> +<polygon fill="lightblue" stroke="lightblue" points="170,-52 102,-52 102,-16 170,-16 170,-52"/> +<text text-anchor="middle" x="136" y="-30.3" font-family="Times,serif" font-size="14.00">block-1</text> +</g> +<!-- block_0 --> +<g id="node8" class="node"> +<title>block_0</title> +<polygon fill="lightblue" stroke="lightblue" points="84,-52 16,-52 16,-16 84,-16 84,-52"/> +<text text-anchor="middle" x="50" y="-30.3" font-family="Times,serif" font-size="14.00">block-0</text> +</g> +<!-- node_1_0 --> +<g id="node9" class="node"> +<title>node_1_0</title> +<polygon fill="yellow" stroke="yellow" points="133,-150 55,-150 55,-114 133,-114 133,-150"/> +<text text-anchor="middle" x="94" y="-128.3" font-family="Times,serif" font-size="14.00">node-1-0</text> +</g> +<!-- node_1_0->block_1 --> +<g id="edge2" class="edge"> +<title>node_1_0->block_1</title> +<path fill="none" stroke="black" d="M101.51,-113.84C107.9,-99.23 117.18,-78.02 124.51,-61.27"/> +<polygon fill="black" stroke="black" points="127.75,-62.58 128.56,-52.01 121.34,-59.77 127.75,-62.58"/> +</g> +<!-- node_1_0->block_0 --> +<g id="edge1" class="edge"> +<title>node_1_0->block_0</title> +<path fill="none" stroke="black" d="M86.13,-113.84C79.44,-99.23 69.72,-78.02 62.04,-61.27"/> +<polygon fill="black" stroke="black" points="65.15,-59.65 57.8,-52.01 58.78,-62.56 65.15,-59.65"/> +</g> +</g> +</svg> diff --git a/doc/images/triple-1.svg b/doc/images/triple-1.svg new file mode 100644 index 0000000..5a06142 --- /dev/null +++ b/doc/images/triple-1.svg @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.42.3 (20191010.1750) + --> +<!-- Title: %3 Pages: 1 --> +<svg width="276pt" height="44pt" + viewBox="0.00 0.00 275.79 44.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 40)"> +<title>%3</title> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-40 271.79,-40 271.79,4 -4,4"/> +<!-- subject --> +<g id="node1" class="node"> +<title>subject</title> +<ellipse fill="none" stroke="black" cx="43.55" cy="-18" rx="43.59" ry="18"/> +<text text-anchor="middle" x="43.55" y="-14.3" font-family="sans-serif" font-size="14.00">subject</text> +</g> +<!-- object --> +<g id="node2" class="node"> +<title>object</title> +<ellipse fill="none" stroke="black" cx="229.44" cy="-18" rx="38.19" ry="18"/> +<text text-anchor="middle" x="229.44" y="-14.3" font-family="sans-serif" font-size="14.00">object</text> +</g> +<!-- subject->object --> +<g id="edge1" class="edge"> +<title>subject->object</title> +<path fill="none" stroke="black" d="M87.2,-18C115.17,-18 151.78,-18 180.72,-18"/> +<polygon fill="black" stroke="black" points="181,-21.5 191,-18 181,-14.5 181,-21.5"/> +<text text-anchor="middle" x="139.09" y="-21.8" font-family="Times,serif" font-size="14.00">predicate</text> +</g> +</g> +</svg> diff --git a/doc/refs.bib b/doc/refs.bib new file mode 100644 index 0000000..deb26d8 --- /dev/null +++ b/doc/refs.bib @@ -0,0 +1,367 @@ +@Article{Aebeloe_2019, + author = {Aebeloe, Christian and Montoya, Gabriela and Hose, Katja}, + title = {A Decentralized Architecture for Sharing and Querying Semantic + Data}, + year = 2019, + pages = {3–18}, + issn = {1611-3349}, + doi = {10.1007/978-3-030-21348-0_1}, + url = {http://dx.doi.org/10.1007/978-3-030-21348-0_1}, + isbn = 9783030213480, + journal = {Lecture Notes in Computer Science}, + publisher = {Springer International Publishing} +} + +@misc{Armstrong_2015, + title = {The web of names, hashes and UUIDs}, + year = 2015, + url = + {https://joearms.github.io/published/2015-03-12-The_web_of_names.html} +} + +@techreport{Augier_2016, + title = {Trustworthy Cloud Storage}, + author = {Augier, Maxime}, + year = 2016, + institution = {EPFL} +} + +@article{Becket_2014, + title = {RDF 1.1 Turtle}, + author = {Beckett, David and Berners-Lee, Tim and Prud’hommeaux, Eric + and Carothers, Gavin}, + journal = {World Wide Web Consortium}, + url = {https://www.w3.org/TR/2014/REC-turtle-20140225/}, + year = 2014 +} + +@misc{Bernstein_1997, + author = {Bernstein, D. J.}, + title = {Netstrings}, + year = 1997, + url = {https://cr.yp.to/proto/netstrings.txt}, + urldata = {2020-05-17} +} + +@misc{Bizer_2007, + title = {How to publish linked data on the web}, + author = {Bizer, Chris and others}, + url = + {http://wifo5-03.informatik.uni-mannheim.de/bizer/HowtoPublishLinkedData.htm}, + year = 2007 +} + +@Article{Cai_2004, + author = {Cai, Min and Frank, Martin}, + title = {RDFPeers}, + year = 2004, + doi = {10.1145/988672.988760}, + url = {http://dx.doi.org/10.1145/988672.988760}, + isbn = {158113844X}, + journal = {Proceedings of the 13th conference on World Wide Web - WWW + ’04}, + publisher = {ACM Press} +} + +@Article{Carroll_2003, + author = {Carroll, Jeremy J.}, + title = {Signing RDF Graphs}, + year = 2003, + pages = {369–384}, + issn = {1611-3349}, + doi = {10.1007/978-3-540-39718-2_24}, + url = {http://dx.doi.org/10.1007/978-3-540-39718-2_24}, + isbn = 9783540397182, + journal = {The Semantic Web - ISWC 2003}, + publisher = {Springer Berlin Heidelberg} +} + +@misc{ContentAddressableRDF2020, + author = {openEngiadina}, + title = {Content-addressable RDF}, + year = 2020, + url = {https://openengiadina.net/papers/content-addressable-rdf.html} +} + +@misc{Cyganiak_2011, + author = {Cyganiak, Richard}, + title = {Blank nodes considered harmful}, + url = + {http://richard.cyganiak.de/blog/2011/03/blank-nodes-considered-harmful/}, + year = 2001 +} + +@misc{ERIS_2020, + author = {openEngiadina}, + title = {Encoding for Robust Immutable Storage}, + year = 2020, + url = {https://openengiadina.net/papers/eris.html} +} + +@misc{Grothoff_2003, + title = {An encoding for censorship-resistant sharing}, + author = {Grothoff, Christian and Grothoff, Krista and Horozov, Tzvetan + and Lindgren, Jussi T}, + url = {https://gnunet.org/sites/default/files/ecrs.pdf}, + year = 2003 +} + +@Article{Kaoudi_2010, + author = {Kaoudi, Zoi and Koubarakis, Manolis and Kyzirakos, Kostis and + Miliaraki, Iris and Magiridou, Matoula and Papadakis-Pesaresi, + Antonios}, + title = {Atlas: Storing, updating and querying RDF(S) data on top of + DHTs}, + year = 2010, + volume = 8, + number = 4, + month = {Nov}, + pages = {271–277}, + issn = {1570-8268}, + doi = {10.1016/j.websem.2010.07.001}, + url = {http://dx.doi.org/10.1016/j.websem.2010.07.001}, + journal = {Journal of Web Semantics}, + publisher = {Elsevier BV} +} + +@Article{Karnstedt_2007, + author = {Karnstedt, Marcel and Sattler, Kai-Uwe and Richtarsky, Martin + and Muller, Jessica and Hauswirth, Manfred and Schmidt, Roman + and John, Renault}, + title = {UniStore: Querying a DHT-based Universal Storage}, + year = 2007, + doi = {10.1109/icde.2007.369054}, + url = {http://dx.doi.org/10.1109/ICDE.2007.369054}, + isbn = 1424408024, + journal = {2007 IEEE 23rd International Conference on Data Engineering}, + publisher = {IEEE} +} + +@article{Leach_2005, + title = {RFC 4122: A universally unique identifier (UUID) URN + namespace}, + author = {Leach, P and Mealling, Michael and Salz, Rich}, + journal = {{IETF} Proposed Standard}, + url = {https://tools.ietf.org/html/rfc4122}, + year = 2005 +} + +@Article{Longley_2019, + title = {RDF Dataset Normalization}, + author = {Longley, Dave and Sporny, Manu}, + url = {https://json-ld.github.io/normalization/spec/}, + journal = {{W3C} Draft Community Group Report}, + year = 2019 +} + +@inproceedings{Mallea_2011, + title = {On blank nodes}, + author = {Mallea, Alejandro and Arenas, Marcelo and Hogan, Aidan and + Polleres, Axel}, + booktitle = {International semantic web conference}, + pages = {421--437}, + year = 2011, + organization = {Springer} +} + +@Article{Marx_2018, + author = {Marx, Edgard and Saleem, Muhammad and Lytra, Ioanna and Ngomo, + Axel-Cyrille Ngonga}, + title = {A Decentralized Architecture for SPARQL Query Processing and + RDF Sharing: A Position Paper}, + year = 2018, + month = {Jan}, + doi = {10.1109/icsc.2018.00049}, + url = {http://dx.doi.org/10.1109/ICSC.2018.00049}, + isbn = 9781538644089, + journal = {2018 IEEE 12th International Conference on Semantic Computing + (ICSC)}, + publisher = {IEEE} +} + +@Article{Peterson_2012, + title = {W3C XML schema definition language (XSD) 1.1 part 2: + Datatypes}, + author = {Peterson, David and Gao, Shudi and Malhotra, Ashok and + Sperberg-McQueen, C Michael and Thompson, Henry S and Biron, + PV}, + journal = {{W3C} Recommendation}, + url = {https://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/}, + year = 2012 +} + +@Article{Polleres_Kamdar_Fernández_Tudorache_Musen_2020, + author = {Polleres, Axel and Kamdar, Maulik Rajendra and Fernández, + Javier David and Tudorache, Tania and Musen, Mark Alan}, + title = {A more decentralized vision for Linked Data}, + year = 2020, + editor = {Hitzler, Pascal and Janowicz, KrzysztofEditors}, + volume = 11, + number = 1, + month = {Jan}, + pages = {101–113}, + issn = {2210-4968}, + doi = {10.3233/SW-190380}, + url = {http://doi.org/10.3233/SW-190380}, + journal = {Semantic Web}, + publisher = {IOS Press} +} + +@Article{Prodromou_2006, + title = {RDF serialization to s-expressions}, + author = {Prodromou, Evan}, + url = + {https://web.archive.org/web/20120525071104/http://evan.prodromou.name/RDF_serialization_to_s-expressions}, + journal = {Blog post (via Internet Archive Wayback Machine)}, + year = 2006 +} + +@Article{Rivest_1997, + author = {Rivest, Ronald L.}, + title = {S-Expressions}, + year = 1997, + journal = {{IETF} Internet-Draft}, + url = {https://people.csail.mit.edu/rivest/Sexp.txt}, + urldata = {2020-05-17} +} + +@Article{Tummarello_2005, + author = {Tummarello, Giovanni and Morbidoni, Christian and Puliti, + Paolo and Piazza, Francesco}, + title = {Signing individual fragments of an RDF graph}, + year = 2005, + doi = {10.1145/1062745.1062848}, + url = {http://dx.doi.org/10.1145/1062745.1062848}, + isbn = 1595930515, + journal = {Special interest tracks and posters of the 14th international + conference on World Wide Web - WWW ’05}, + publisher = {ACM Press} +} + +@Article{Verborgh_2016, + author = {Verborgh, Ruben and Vander Sande, Miel and Hartig, Olaf and + Van Herwegen, Joachim and De Vocht, Laurens and De Meester, + Ben and Haesendonck, Gerald and Colpaert, Pieter}, + title = {Triple Pattern Fragments: A low-cost knowledge graph interface + for the Web}, + year = 2016, + volume = {37-38}, + month = {Mar}, + pages = {184–206}, + issn = {1570-8268}, + doi = {10.1016/j.websem.2016.03.003}, + url = {http://dx.doi.org/10.1016/j.websem.2016.03.003}, + journal = {Journal of Web Semantics}, + publisher = {Elsevier BV} +} + +@Article{Wood_2014, + author = {Wood, David and Lanthaler, Markus and Cyganiak, Richard}, + institution = {W3C}, + timestamp = {2015-05-29T13:33:56.000+0200}, + title = {{RDF} 1.1 Concepts and Abstract Syntax}, + journal = {{W3C} Recommendation}, + url = {http://www.w3.org/TR/2014/REC-rdf11-concepts-20140225/}, + urldate = {2020-05-16}, + year = 2014 +} + +@misc{Zooko2008, + author = {Wilcox-O'Hearn, Zooko}, + title = {Drew Perttula and Attacks on Convergent Encryption}, + year = 2008, + url = {https://tahoe-lafs.org/hacktahoelafs/drew_perttula.html} +} + +@inproceedings{alvaro2010dedalus, + title = {Dedalus: Datalog in time and space}, + author = {Alvaro, Peter and Marczak, William R and Conway, Neil and + Hellerstein, Joseph M and Maier, David and Sears, Russell}, + booktitle = {International Datalog 2.0 Workshop}, + pages = {262--281}, + year = 2010, + organization = {Springer} +} + +@inproceedings{aumasson2013blake2, + title = {BLAKE2: simpler, smaller, fast as MD5}, + author = {Aumasson, Jean-Philippe and Neves, Samuel and Wilcox-O’Hearn, + Zooko and Winnerlein, Christian}, + booktitle = {International Conference on Applied Cryptography and Network + Security}, + pages = {119--135}, + year = 2013, + organization = {Springer} +} + +@article{fernandez2013binary, + title = {Binary RDF representation for publication and exchange (HDT)}, + author = {Fern{\'a}ndez, Javier D and Mart{\'\i}nez-Prieto, Miguel A and + Guti{\'e}rrez, Claudio and Polleres, Axel and Arias, Mario}, + journal = {Journal of Web Semantics}, + volume = 19, + pages = {22--41}, + year = 2013, + publisher = {Elsevier} +} + +@inproceedings{karlsson2018vegvisir, + title = {Vegvisir: A partition-tolerant blockchain for the + internet-of-things}, + author = {Karlsson, Kolbeinn and Jiang, Weitao and Wicker, Stephen and + Adams, Danny and Ma, Edwin and van Renesse, Robbert and + Weatherspoon, Hakim}, + booktitle = {2018 IEEE 38th International Conference on Distributed + Computing Systems (ICDCS)}, + pages = {1150--1158}, + year = 2018, + organization = {IEEE} +} + +@article{lebo2013prov, + title = {PROV-O: The PROV ontology}, + author = {Lebo, Timothy and Sahoo, Satya and McGuinness, Deborah and + Belhajjame, Khalid and Cheney, James and Corsar, David and + Garijo, Daniel and Soiland-Reyes, Stian and Zednik, Stephan + and Zhao, Jun}, + journal = {W3C recommendation}, + volume = 30, + year = 2013, + publisher = {W3C} +} + +@article{liedtke1995micro, + title = {On micro-kernel construction}, + author = {Liedtke, Jochen}, + journal = {ACM SIGOPS Operating Systems Review}, + volume = 29, + number = 5, + pages = {237--250}, + year = 1995, + publisher = {ACM New York, NY, USA} +} + +@article{nir2015chacha20, + title = {ChaCha20 and Poly1305 for IETF Protocols}, + author = {Nir, Yoav and Langley, Adam}, + journal = {Internet Engineering Task Force}, + url = {https://tools.ietf.org/html/rfc8439}, + year = 2018 +} + +@article{saarinen2015blake2, + title = {The BLAKE2 cryptographic hash and message authentication code + (MAC)}, + author = {Saarinen, Markku Juhani and Aumasson, Jean-Philippe}, + journal = {Internet Engineering Task Force}, + url = {https://tools.ietf.org/html/rfc7693}, + year = 2015 +} + +@article{shapiro2011comprehensive, + title = {A comprehensive study of convergent and commutative replicated + data types}, + author = {Shapiro, Marc and Pregui{\c{c}}a, Nuno and Baquero, Carlos and + Zawirski, Marek}, + year = 2011 +} diff --git a/doc/slides.org b/doc/slides.org new file mode 100644 index 0000000..370bccd --- /dev/null +++ b/doc/slides.org @@ -0,0 +1,744 @@ +#+TITLE: Encoding for Robust Immutable Storage (ERIS) +#+AUTHOR: +#+OPTIONS: timestamp:nil +#+OPTIONS: reveal_single_file:t +#+REVEAL_ROOT: file://../../../../dev/reveal.js-3.8.0/ +#+REVEAL_EXTRA_CSS: style.css +#+REVEAL_HLEVEL: 1 +#+REVEAL_THEME: white +#+REVEAL_TRANS: none +#+OPTIONS: toc:nil +#+OPTIONS: num:nil + +* An /encoding/ + +Defines how to encode arbitrary content into uniformly sized encrypted blocks and how to reassemble them. + +Does not define storage level or transport level. + +** Inspiration + +- Datashards: How to use it for ActivityPub +- An Encoding for Censorship-Resistant Sharing: implemented in GNUNet filesharing. + +** Context + +- Work part of the openEngiadina project +- Supported by NGI0 via the NLNet foundation + +** Robustness + +- Availability of content +- Authenticity +- Plausible deniability for peers +- Simple to implement correctly + +* Overview + +[[./images/eris-overview.svg]] + +Notable differences to IDSC: + +- optional convergence secret +- verification capability + +** Cryptographic primitives + +Blake2b & ChaCha20 (IETF variant) + +- fast, standardized and widely implemented +- Blake2b: inbuilt support for keying and personalization (allows implementation of convergence secret and key derivation) +- ChaCha20: Nonce does not have to have high-entropy (vs. IV of AES) + +** Content-addressable storage + +- ~cas-put!(block)~ +- ~cas-get(ref)~ + +Like the "Store Core Interface" in Datashards. + +** Read and verification key + +- read key :: ~BLAKE2b(content)~, ~BLAKE2b(content, key=covergence-secret)~ +- verification key :: deterministically derived from read key + +* Encoding content +** Split content into uniformly sized blocks + +#+BEGIN_SRC dot :file images/data-blocks.svg :exports results +digraph { + + compound=true; + + subgraph cluster__level_0 { + style=dotted; + labeljust="l"; + + block_7 [shape=box,color=lightblue,style=filled,label="block-7"]; + block_6 [shape=box,color=lightblue,style=filled,label="block-6"]; + block_5 [shape=box,color=lightblue,style=filled,label="block-5"]; + block_4 [shape=box,color=lightblue,style=filled,label="block-4"]; + block_3 [shape=box,color=lightblue,style=filled,label="block-3"]; + block_2 [shape=box,color=lightblue,style=filled,label="block-2"]; + block_1 [shape=box,color=lightblue,style=filled,label="block-1"]; + block_0 [shape=box,color=lightblue,style=filled,label="block-0"]; + }; + + } +#+END_SRC + +#+RESULTS: +[[file:images/data-blocks.svg]] + +Encrypt content with read key (nonce=0). + +** Collect references + +#+BEGIN_SRC dot :file images/tree-level-1.svg :exports results +digraph { + + compound=true; + + subgraph cluster__level_0 { + style=dotted; + label="level 0\n(data blocks)"; + labeljust="l"; + + block_7 [shape=box,color=lightblue,style=filled,label="block-7"]; + block_6 [shape=box,color=lightblue,style=filled,label="block-6"]; + block_5 [shape=box,color=lightblue,style=filled,label="block-5"]; + block_4 [shape=box,color=lightblue,style=filled,label="block-4"]; + block_3 [shape=box,color=lightblue,style=filled,label="block-3"]; + block_2 [shape=box,color=lightblue,style=filled,label="block-2"]; + block_1 [shape=box,color=lightblue,style=filled,label="block-1"]; + block_0 [shape=box,color=lightblue,style=filled,label="block-0"]; + }; + + subgraph cluster__level_1 { + style=dotted; + label="level 1"; + labeljust="l"; + node_1_0 [shape=box,color=yellow,style=filled,label="node-1-0"]; + }; + + node_1_0 -> block_0; + node_1_0 -> block_1; + +} +#+END_SRC + +#+RESULTS: +[[file:images/tree-level-1.svg]] + +Simple concatenation of references, filled with null-references to reach block size. + +Encrypt with *verification key*. + +** Encryption nonce for nodes + +#+BEGIN_SRC dot :file images/node-nonce-position.svg :exports results +digraph { + + compound=true; + + subgraph cluster__level_0 { + style=dotted; + label="level 0\n(data blocks)"; + labeljust="l"; + + block_7 [shape=box,color=lightblue,style=filled,label="block-7"]; + block_6 [shape=box,color=lightblue,style=filled,label="block-6"]; + block_5 [shape=box,color=lightblue,style=filled,label="block-5"]; + block_4 [shape=box,color=lightblue,style=filled,label="block-4"]; + block_3 [shape=box,color=lightblue,style=filled,label="block-3"]; + block_2 [shape=box,color=lightblue,style=filled,label="block-2"]; + block_1 [shape=box,color=lightblue,style=filled,label="block-1"]; + block_0 [shape=box,color=lightblue,style=filled,label="block-0"]; + }; + + subgraph cluster__level_1 { + style=dotted; + label="level 1"; + labeljust="l"; + node_1_3 [shape=box,color=lightgrey,style=filled,label="node-1-3"]; + node_1_2 [shape=box,color=lightgrey,style=filled,label="node-1-2"]; + node_1_1 [shape=box,color=lightgrey,style=filled,label="node-1-1"]; + node_1_0 [shape=box,color=orange,style=filled,label="node-1-0"]; + }; + + node_1_0 -> block_0; + node_1_0 -> block_1; + + node_1_1 -> block_2; + node_1_1 -> block_3; + + node_1_2 -> block_4; + node_1_2 -> block_5; + + node_1_3 -> block_6; + node_1_3 -> block_7; + + subgraph cluster__level_2 { + label="level 2"; + labeljust="l"; + style=dotted; + node_2_1 [shape=box,color=lightgrey,style=filled,label="node-2-1"]; + node_2_0 [shape=box,color=orange,style=filled,label="node-2-0"]; + }; + + node_2_0 -> node_1_0; + node_2_0 -> node_1_1; + + node_2_1 -> node_1_2; + node_2_1 -> node_1_3; + + subgraph cluster__level_3 { + style=dotted; + label="level 3"; + labeljust="l"; + node_3_0 [shape=box,color=orange,style=filled,label="node-3-0"]; + } + + node_3_0 -> node_2_0; + node_3_0 -> node_2_1; + +} +#+END_SRC + +#+RESULTS: +[[file:images/node-nonce-position.svg]] + + +Use the path to the node as nonce. For ~node-1-0~: ~[0 0]~ + +** Encryption nonce for nodes + +#+BEGIN_SRC dot :file images/node-nonce-position-2.svg :exports results +digraph { + + compound=true; + + subgraph cluster__level_0 { + style=dotted; + label="level 0\n(data blocks)"; + labeljust="l"; + + block_7 [shape=box,color=lightblue,style=filled,label="block-7"]; + block_6 [shape=box,color=lightblue,style=filled,label="block-6"]; + block_5 [shape=box,color=lightblue,style=filled,label="block-5"]; + block_4 [shape=box,color=lightblue,style=filled,label="block-4"]; + block_3 [shape=box,color=lightblue,style=filled,label="block-3"]; + block_2 [shape=box,color=lightblue,style=filled,label="block-2"]; + block_1 [shape=box,color=lightblue,style=filled,label="block-1"]; + block_0 [shape=box,color=lightblue,style=filled,label="block-0"]; + }; + + subgraph cluster__level_1 { + style=dotted; + label="level 1"; + labeljust="l"; + node_1_3 [shape=box,color=lightgrey,style=filled,label="node-1-3"]; + node_1_2 [shape=box,color=lightgrey,style=filled,label="node-1-2"]; + node_1_1 [shape=box,color=orange,style=filled,label="node-1-1"]; + node_1_0 [shape=box,color=yellow,style=filled,label="node-1-0"]; + }; + + node_1_0 -> block_0; + node_1_0 -> block_1; + + node_1_1 -> block_2; + node_1_1 -> block_3; + + node_1_2 -> block_4; + node_1_2 -> block_5; + + node_1_3 -> block_6; + node_1_3 -> block_7; + + subgraph cluster__level_2 { + label="level 2"; + labeljust="l"; + style=dotted; + node_2_1 [shape=box,color=lightgrey,style=filled,label="node-2-1"]; + node_2_0 [shape=box,color=orange,style=filled,label="node-2-0"]; + }; + + node_2_0 -> node_1_0; + node_2_0 -> node_1_1; + + node_2_1 -> node_1_2; + node_2_1 -> node_1_3; + + subgraph cluster__level_3 { + style=dotted; + label="level 3"; + labeljust="l"; + node_3_0 [shape=box,color=orange,style=filled,label="node-3-0"]; + } + + node_3_0 -> node_2_0; + node_3_0 -> node_2_1; + +} +#+END_SRC + +#+RESULTS: +[[file:images/node-nonce-position-2.svg]] + + +Use the path to the node as nonce. For ~node-1-1~: ~[0 1]~ + +** Encryption nonce for nodes + +#+BEGIN_SRC dot :file images/node-nonce-position-3.svg :exports results +digraph { + + compound=true; + + subgraph cluster__level_0 { + style=dotted; + label="level 0\n(data blocks)"; + labeljust="l"; + + block_7 [shape=box,color=lightblue,style=filled,label="block-7"]; + block_6 [shape=box,color=lightblue,style=filled,label="block-6"]; + block_5 [shape=box,color=lightblue,style=filled,label="block-5"]; + block_4 [shape=box,color=lightblue,style=filled,label="block-4"]; + block_3 [shape=box,color=lightblue,style=filled,label="block-3"]; + block_2 [shape=box,color=lightblue,style=filled,label="block-2"]; + block_1 [shape=box,color=lightblue,style=filled,label="block-1"]; + block_0 [shape=box,color=lightblue,style=filled,label="block-0"]; + }; + + subgraph cluster__level_1 { + style=dotted; + label="level 1"; + labeljust="l"; + node_1_3 [shape=box,color=lightgrey,style=filled,label="node-1-3"]; + node_1_2 [shape=box,color=lightgrey,style=filled,label="node-1-2"]; + node_1_1 [shape=box,color=yellow,style=filled,label="node-1-1"]; + node_1_0 [shape=box,color=yellow,style=filled,label="node-1-0"]; + }; + + node_1_0 -> block_0; + node_1_0 -> block_1; + + node_1_1 -> block_2; + node_1_1 -> block_3; + + node_1_2 -> block_4; + node_1_2 -> block_5; + + node_1_3 -> block_6; + node_1_3 -> block_7; + + subgraph cluster__level_2 { + label="level 2"; + labeljust="l"; + style=dotted; + node_2_1 [shape=box,color=lightgrey,style=filled,label="node-2-1"]; + node_2_0 [shape=box,color=orange,style=filled,label="node-2-0"]; + }; + + node_2_0 -> node_1_0; + node_2_0 -> node_1_1; + + node_2_1 -> node_1_2; + node_2_1 -> node_1_3; + + subgraph cluster__level_3 { + style=dotted; + label="level 3"; + labeljust="l"; + node_3_0 [shape=box,color=orange,style=filled,label="node-3-0"]; + } + + node_3_0 -> node_2_0; + node_3_0 -> node_2_1; + +} +#+END_SRC + +#+RESULTS: +[[file:images/node-nonce-position-3.svg]] + + +~node-2-0~: ~[0 X]~ + +Special symbol ~X~ to denote path not taken. + +** Encryption nonce for nodes + +#+BEGIN_SRC dot :file images/node-nonce-position-4.svg :exports results +digraph { + + compound=true; + + subgraph cluster__level_0 { + style=dotted; + label="level 0\n(data blocks)"; + labeljust="l"; + + block_7 [shape=box,color=lightblue,style=filled,label="block-7"]; + block_6 [shape=box,color=lightblue,style=filled,label="block-6"]; + block_5 [shape=box,color=lightblue,style=filled,label="block-5"]; + block_4 [shape=box,color=lightblue,style=filled,label="block-4"]; + block_3 [shape=box,color=lightblue,style=filled,label="block-3"]; + block_2 [shape=box,color=lightblue,style=filled,label="block-2"]; + block_1 [shape=box,color=lightblue,style=filled,label="block-1"]; + block_0 [shape=box,color=lightblue,style=filled,label="block-0"]; + }; + + subgraph cluster__level_1 { + style=dotted; + label="level 1"; + labeljust="l"; + node_1_3 [shape=box,color=lightgrey,style=filled,label="node-1-3"]; + node_1_2 [shape=box,color=orange,style=filled,label="node-1-2"]; + node_1_1 [shape=box,color=yellow,style=filled,label="node-1-1"]; + node_1_0 [shape=box,color=yellow,style=filled,label="node-1-0"]; + }; + + node_1_0 -> block_0; + node_1_0 -> block_1; + + node_1_1 -> block_2; + node_1_1 -> block_3; + + node_1_2 -> block_4; + node_1_2 -> block_5; + + node_1_3 -> block_6; + node_1_3 -> block_7; + + subgraph cluster__level_2 { + label="level 2"; + labeljust="l"; + style=dotted; + node_2_1 [shape=box,color=orange,style=filled,label="node-2-1"]; + node_2_0 [shape=box,color=yellow,style=filled,label="node-2-0"]; + }; + + node_2_0 -> node_1_0; + node_2_0 -> node_1_1; + + node_2_1 -> node_1_2; + node_2_1 -> node_1_3; + + subgraph cluster__level_3 { + style=dotted; + label="level 3"; + labeljust="l"; + node_3_0 [shape=box,color=orange,style=filled,label="node-3-0"]; + } + + node_3_0 -> node_2_0; + node_3_0 -> node_2_1; + +} +#+END_SRC + +#+RESULTS: +[[file:images/node-nonce-position-4.svg]] + + +~node-1-2~: ~[1 0]~ + +** Encryption nonce for nodes + +#+BEGIN_SRC dot :file images/node-nonce-position-5.svg :exports results +digraph { + + compound=true; + + subgraph cluster__level_0 { + style=dotted; + label="level 0\n(data blocks)"; + labeljust="l"; + + block_7 [shape=box,color=lightblue,style=filled,label="block-7"]; + block_6 [shape=box,color=lightblue,style=filled,label="block-6"]; + block_5 [shape=box,color=lightblue,style=filled,label="block-5"]; + block_4 [shape=box,color=lightblue,style=filled,label="block-4"]; + block_3 [shape=box,color=lightblue,style=filled,label="block-3"]; + block_2 [shape=box,color=lightblue,style=filled,label="block-2"]; + block_1 [shape=box,color=lightblue,style=filled,label="block-1"]; + block_0 [shape=box,color=lightblue,style=filled,label="block-0"]; + }; + + subgraph cluster__level_1 { + style=dotted; + label="level 1"; + labeljust="l"; + node_1_3 [shape=box,color=orange,style=filled,label="node-1-3"]; + node_1_2 [shape=box,color=yellow,style=filled,label="node-1-2"]; + node_1_1 [shape=box,color=yellow,style=filled,label="node-1-1"]; + node_1_0 [shape=box,color=yellow,style=filled,label="node-1-0"]; + }; + + node_1_0 -> block_0; + node_1_0 -> block_1; + + node_1_1 -> block_2; + node_1_1 -> block_3; + + node_1_2 -> block_4; + node_1_2 -> block_5; + + node_1_3 -> block_6; + node_1_3 -> block_7; + + subgraph cluster__level_2 { + label="level 2"; + labeljust="l"; + style=dotted; + node_2_1 [shape=box,color=orange,style=filled,label="node-2-1"]; + node_2_0 [shape=box,color=yellow,style=filled,label="node-2-0"]; + }; + + node_2_0 -> node_1_0; + node_2_0 -> node_1_1; + + node_2_1 -> node_1_2; + node_2_1 -> node_1_3; + + subgraph cluster__level_3 { + style=dotted; + label="level 3"; + labeljust="l"; + node_3_0 [shape=box,color=orange,style=filled,label="node-3-0"]; + } + + node_3_0 -> node_2_0; + node_3_0 -> node_2_1; + +} +#+END_SRC + +#+RESULTS: +[[file:images/node-nonce-position-5.svg]] + + +~node-1-3~: ~[1 1]~ + +** Encryption nonce for nodes + +#+BEGIN_SRC dot :file images/node-nonce-position-6.svg :exports results +digraph { + + compound=true; + + subgraph cluster__level_0 { + style=dotted; + label="level 0\n(data blocks)"; + labeljust="l"; + + block_7 [shape=box,color=lightblue,style=filled,label="block-7"]; + block_6 [shape=box,color=lightblue,style=filled,label="block-6"]; + block_5 [shape=box,color=lightblue,style=filled,label="block-5"]; + block_4 [shape=box,color=lightblue,style=filled,label="block-4"]; + block_3 [shape=box,color=lightblue,style=filled,label="block-3"]; + block_2 [shape=box,color=lightblue,style=filled,label="block-2"]; + block_1 [shape=box,color=lightblue,style=filled,label="block-1"]; + block_0 [shape=box,color=lightblue,style=filled,label="block-0"]; + }; + + subgraph cluster__level_1 { + style=dotted; + label="level 1"; + labeljust="l"; + node_1_3 [shape=box,color=yellow,style=filled,label="node-1-3"]; + node_1_2 [shape=box,color=yellow,style=filled,label="node-1-2"]; + node_1_1 [shape=box,color=yellow,style=filled,label="node-1-1"]; + node_1_0 [shape=box,color=yellow,style=filled,label="node-1-0"]; + }; + + node_1_0 -> block_0; + node_1_0 -> block_1; + + node_1_1 -> block_2; + node_1_1 -> block_3; + + node_1_2 -> block_4; + node_1_2 -> block_5; + + node_1_3 -> block_6; + node_1_3 -> block_7; + + subgraph cluster__level_2 { + label="level 2"; + labeljust="l"; + style=dotted; + node_2_1 [shape=box,color=orange,style=filled,label="node-2-1"]; + node_2_0 [shape=box,color=yellow,style=filled,label="node-2-0"]; + }; + + node_2_0 -> node_1_0; + node_2_0 -> node_1_1; + + node_2_1 -> node_1_2; + node_2_1 -> node_1_3; + + subgraph cluster__level_3 { + style=dotted; + label="level 3"; + labeljust="l"; + node_3_0 [shape=box,color=orange,style=filled,label="node-3-0"]; + } + + node_3_0 -> node_2_0; + node_3_0 -> node_2_1; + +} +#+END_SRC + +#+RESULTS: +[[file:images/node-nonce-position-6.svg]] + + +~node-2-1~: ~[1 X]~ + +** Encryption nonce for nodes + +#+BEGIN_SRC dot :file images/node-nonce-position-7.svg :exports results +digraph { + + compound=true; + + subgraph cluster__level_0 { + style=dotted; + label="level 0\n(data blocks)"; + labeljust="l"; + + block_7 [shape=box,color=lightblue,style=filled,label="block-7"]; + block_6 [shape=box,color=lightblue,style=filled,label="block-6"]; + block_5 [shape=box,color=lightblue,style=filled,label="block-5"]; + block_4 [shape=box,color=lightblue,style=filled,label="block-4"]; + block_3 [shape=box,color=lightblue,style=filled,label="block-3"]; + block_2 [shape=box,color=lightblue,style=filled,label="block-2"]; + block_1 [shape=box,color=lightblue,style=filled,label="block-1"]; + block_0 [shape=box,color=lightblue,style=filled,label="block-0"]; + }; + + subgraph cluster__level_1 { + style=dotted; + label="level 1"; + labeljust="l"; + node_1_3 [shape=box,color=yellow,style=filled,label="node-1-3"]; + node_1_2 [shape=box,color=yellow,style=filled,label="node-1-2"]; + node_1_1 [shape=box,color=yellow,style=filled,label="node-1-1"]; + node_1_0 [shape=box,color=yellow,style=filled,label="node-1-0"]; + }; + + node_1_0 -> block_0; + node_1_0 -> block_1; + + node_1_1 -> block_2; + node_1_1 -> block_3; + + node_1_2 -> block_4; + node_1_2 -> block_5; + + node_1_3 -> block_6; + node_1_3 -> block_7; + + subgraph cluster__level_2 { + label="level 2"; + labeljust="l"; + style=dotted; + node_2_1 [shape=box,color=yellow,style=filled,label="node-2-1"]; + node_2_0 [shape=box,color=yellow,style=filled,label="node-2-0"]; + }; + + node_2_0 -> node_1_0; + node_2_0 -> node_1_1; + + node_2_1 -> node_1_2; + node_2_1 -> node_1_3; + + subgraph cluster__level_3 { + style=dotted; + label="level 3"; + labeljust="l"; + node_3_0 [shape=box,color=orange,style=filled,label="node-3-0"]; + } + + node_3_0 -> node_2_0; + node_3_0 -> node_2_1; + +} +#+END_SRC + +#+RESULTS: +[[file:images/node-nonce-position-7.svg]] + + +~node-3-0~: ~[X X]~ + +** Encryption nonce for nodes + +[[file:images/eris-merkle-1.svg]] + +** Encryption nonce for nodes + +- Node position (nonce) can be computed when building the tree from bottom and when decoding from top. +- Uses fact that ChaCha20 does not require high-entropy nonce +- Protection against second preimage attack as position of node is encoded into node + +** Read capability + +[[file:images/eris-merkle-1.svg]] + +/Read capability/ consists of: root reference, read key and level of root reference (depth of tree). + +** Verification capability + +[[file:images/eris-merkle-1.svg]] + +/Verification capability/ consists of: root reference, verification key and level of root reference (depth of tree). + +* Implementations + +- Guile +- JavaScript (+ ClojureScript bindings) +- Elixir + +Experimental ActivityPub Server and Client (CPub and GeoPub). + +* Verification capability + +Usefulness of this still needs to be demonstrated... + +* Two-pass encoding + +1. Compute hash of content +2. Encode tree + +Not suitable for large content! + +** Block size + +4kB + +Small... + +*** Maybe smaller + +#+BEGIN_QUOTE +A CoAP message, appropriately encapsulated, SHOULD fit within a single IP packet ... an IP MTU of 1280 bytes SHOULD be assumed. + +--- The Constrained Application Protocol (CoAP) (RFC 7252) +#+END_QUOTE + +Block size of 1kB? + +*** What about large content? + +Use ECRS? + +(block size 32kb - single pass encoding) + +* Demo + +[[https://geopub.openengiadina.net][GeoPub]] + diff --git a/doc/style.css b/doc/style.css new file mode 100644 index 0000000..6b013e3 --- /dev/null +++ b/doc/style.css @@ -0,0 +1,3 @@ +.reveal section img { background:none; border:none; box-shadow:none;} + +.reveal h3 {font-size: 1.1em;} |