From b7671273673da80def7356635e2bc3de62c1fc59 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Fri, 26 Feb 2021 20:55:10 +0100 Subject: [PATCH 01/20] Commit work in progress: - provide context - notes / todos --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 173 ++++++++++++++++++++++ docs/lazy-adr/img/extended_square.png | Bin 0 -> 13803 bytes 2 files changed, 173 insertions(+) create mode 100644 docs/lazy-adr/adr-002-ipds-da-sampling.md create mode 100644 docs/lazy-adr/img/extended_square.png diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md new file mode 100644 index 0000000000..4ccd45f3e6 --- /dev/null +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -0,0 +1,173 @@ +# LAZY ADR 002: Sampling erasure coded Block chunks + +## Changelog + +- 26-2-2021: Created + +## Context + +In Tendermint's block gossiping each peer gossips random parts of block data to peers. +For LazyLedger, we need nodes (from light-clients to validators) to be able to sample rows/columns of the erasure coded +block (aka the extended data square) from the network. +This is necessary for Data Availability proofs. + +![extended_square.png](img/extended_square.png) + +A high-level, implementation-independent formalization of above mentioned sampling and Data Availability proofs can be found in: +[_Fraud and Data Availability Proofs: Detecting Invalid Blocks in Light Clients_](https://fc21.ifca.ai/papers/83.pdf). + +For the time being, besides the academic paper, no other formalization or specification of the protocol exists. +Currently, the LazyLedger specification itself only describes the [erasure coding](https://github.com/lazyledger/lazyledger-specs/blob/master/specs/data_structures.md#erasure-coding) +and how to retrieve the extended data square from the block data. + +The core data structures and the erasure coding of the block are already implemented in lazyledger-core ([#17], [#19], [#83]). +While there are no ADRs for these changes, we can refer to the LazyLedger specification in this case. +For this aspect, the existing implementation and specification should already be on par for the most part. +The exact arrangement of the data as described in this [rationale document](https://github.com/lazyledger/lazyledger-specs/blob/master/rationale/message_block_layout.md) +in the specification can happen at app-side of the ABCI boundary. +The latter was implemented in [lazyledger/lazyledger-app#21](https://github.com/lazyledger/lazyledger-app/pull/21) +leveraging a new ABCI method, added in [#110](https://github.com/lazyledger/lazyledger-core/pull/110). +This new method is a sub-set of the proposed ABCI changes aka [ABCI++](https://github.com/tendermint/spec/pull/254). + +Mustafa Al-Bassam (@musalbas) implemented a [prototype](https://github.com/lazyledger/lazyledger-prototype) +whose main purpose is to realistically analyse the protocol. +Although the prototype does make any network requests and only operates locally, it currently is the most advanced implementation of the protocol. +It uses the [rsmt2d] library. + + +This ADR describes: + - the high-level requirements + - the API that and how it can be used by different components of LazyLedger (block gossiping, block sync, DA proofs) + - decisions on how to implement this. + +The implementation will essentially use IPFS' APIs. For reading (and writing) chunks +will use the IPLD [`DagService`](https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/merkledag.go#L54), +more precisely the [`NodeGetter`](https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/merkledag.go#L18-L27) +and [`NodeAdder`](https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/merkledag.go#L29-L39). +This will be achieved by passing around a [CoreAPI](https://github.com/ipfs/interface-go-ipfs-core/blob/b935dfe5375eac7ea3c65b14b3f9a0242861d0b3/coreapi.go#L15) +object, which derive from the ipfs node which is created along a with a tendermint node (see [#152]). +This code snippet does exactly that (see the [go-ipfs documentation] for more examples): +````go +// This constructs an IPFS node instance +node, _ := core.NewNode(ctx, nodeOptions) +// This attaches the Core API to the constructed node +coreApi := coreapi.NewCoreAPI(node) +```` + +The above mentioned IPLD methods operate on so called [ipld.Nodes]. +When computing the data root, we can pass in a [`NodeVisitor`](https://github.com/lazyledger/nmt/blob/b22170d6f23796a186c07e87e4ef9856282ffd1a/nmt.go#L22) +into the Namespaced Merkle Tree library to create these (each inner- and leaf-node in the tree becomes an ipld node). +As a peer that requests such an ipld node, the LazyLedger ipld plugin provides the [function](https://github.com/lazyledger/lazyledger-core/blob/ceb881a177b6a4a7e456c7c4ab1dd0eb2b263066/p2p/ipld/plugin/nodes/nodes.go#L175) +`NmtNodeParser` to transform the retrieved raw data back into an `ipld.Node`. + +A more high-level description on the changes required to rip out the current block gossiping routine, +including changes to block storage-, RPC-layer, and potential changes to reactors is either handled in [LAZY ADR 001](./adr-001-block-propagation.md), +and/or in a few smaller, separate followup ADRs. + +## Alternative Approaches + +Instead of creating a full ipfs node object and passing it around as explained above + - use API (http) + - use ipld-light + - use alternative client + +Also, for better performance + - use graph-sync, ipld selectors (ipld-prime) + +Also, there is the idea, that nodes only receive the Header with the data root only +and, in an additional step/request, download the DA header using the library, too. +While this feature is not considered here, and we assume each node that uses this library has the DA header, this assumption +is likely to change when flesh out other parts of the system in more detail. + +## Decision + +> This section records the decision that was made. +> It is best to record as much info as possible from the discussion that happened. This aids in not having to go back to the Pull Request to get the needed information. + +> - TODO: briefly summarize github, discord, and slack discussions (?) +> - also mention Mustafa's prototype and compare both apis briefly (RequestSamples, RespondSamples, ProcessSamplesResponse) +> - mention [ipld experiments] + + + + +## Detailed Design + +Also a request / respond pattern? + +- sample a given batch of row/col indices of extended data square +- sample single cell from extended square (?) +- reconstruct whole block from DA header (or from data root) +- randomness source does need to be configurable by caller + + + + +> This section does not need to be filled in at the start of the ADR, but must be completed prior to the merging of the implementation. +> +> Here are some common questions that get answered as part of the detailed design: +> +> - What are the user requirements? +> +> - What systems will be affected? +> +> - What new data structures are needed, what data structures will be changed? +> +> - What new APIs will be needed, what APIs will be changed? +> +> - What are the efficiency considerations (time/space)? +> +> - What are the expected access patterns (load/throughput)? +> +> - Are there any logging, monitoring or observability needs? +> +> - Are there any security considerations? +> +> - Are there any privacy considerations? +> +> - How will the changes be tested? +> +> - If the change is large, how will the changes be broken up for ease of review? +> +> - Will these changes require a breaking (major) release? +> +> - Does this change require coordination with the SDK or other? + +## Status + +> A decision may be "proposed" if it hasn't been agreed upon yet, or "accepted" once it is agreed upon. Once the ADR has been implemented mark the ADR as "implemented". If a later ADR changes or reverses a decision, it may be marked as "deprecated" or "superseded" with a reference to its replacement. + +Proposed + +## Consequences + +> This section describes the consequences, after applying the decision. All consequences should be summarized here, not just the "positive" ones. + +### Positive + +### Negative + +### Neutral + +## References + +> Are there any relevant PR comments, issues that led up to this, or articles referenced for why we made the given design choice? If so link them here! + +- https://docs.ipld.io/#nodes +- https://arxiv.org/abs/1809.09044 +- https://fc21.ifca.ai/papers/83.pdf +- https://github.com/tendermint/spec/pull/254 + +[#17]: https://github.com/lazyledger/lazyledger-core/pull/17 +[#19]: https://github.com/lazyledger/lazyledger-core/pull/19 +[#83]: https://github.com/lazyledger/lazyledger-core/pull/83 + +[#152]: https://github.com/lazyledger/lazyledger-core/pull/152 + +[go-ipfs documentation]: https://github.com/ipfs/go-ipfs/tree/master/docs/examples/go-ipfs-as-a-library#use-go-ipfs-as-a-library-to-spawn-a-node-and-add-a-file +[ipld experiments]: https://github.com/lazyledger/ipld-plugin-experiments +[ipld.Nodes]: https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/format.go#L22-L45 + +[rsmt2d]: https://github.com/lazyledger/rsmt2d + + diff --git a/docs/lazy-adr/img/extended_square.png b/docs/lazy-adr/img/extended_square.png new file mode 100644 index 0000000000000000000000000000000000000000..8bbf4695053f4f2ca7aa5a46c9869631ebd3ef79 GIT binary patch literal 13803 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 literal 0 HcmV?d00001 From 1e95a71b447bc483d845a5701c5e1ee435aa564a Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Mon, 1 Mar 2021 12:25:24 +0100 Subject: [PATCH 02/20] Add high-level design considerations --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 35 +++++++++++++++++++---- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index 4ccd45f3e6..d8218ed1dd 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -93,12 +93,25 @@ is likely to change when flesh out other parts of the system in more detail. ## Detailed Design -Also a request / respond pattern? +Add a package to the library that provides the following features: + 1. sample a given number of random row/col indices of extended data square given a DA header and indicate if successful or timeout/other error occurred. + 2. reconstruct the whole block from a given DA header + 3. get all messages of a particular namespace ID. + +We mention 3. here mostly for completeness. Its details will be described / implemented in a separate ADR / PR. + +Apart from the above mentioned features, we informally collect additional requirements: +- where randomness is needed, the randomness source should be configurable (but should be the same source per instance) +- all replies by the network should be verified if this is not sufficiently covered by the used libraries already (IPFS) +- where possible, the requests to the network should happen in parallel (without DoSing the proposer for instance). + +This feature should be implemented as two new packages: First, a sub-package should be added to the layzledger-core [p2p] package +which does not know anything about the core data structures (Block, DA header etc). +It handles the actual network requests to the IPFS network and operates on IPFS/IPLD objects directly and hence should live under [p2p/ipld] + +Second, a high-level API that can "live" closer to the actual types, e.g., in a sub-package in [lazyledger-core/types]. + -- sample a given batch of row/col indices of extended data square -- sample single cell from extended square (?) -- reconstruct whole block from DA header (or from data root) -- randomness source does need to be configurable by caller @@ -145,8 +158,13 @@ Proposed ### Positive + - simplicity & ease of implementation + ### Negative + - latency + - being connected to the public IPFS network might be overkill if peers should in fact only care about a subset that participates in the LazyLedger protocol + ### Neutral ## References @@ -158,6 +176,8 @@ Proposed - https://fc21.ifca.ai/papers/83.pdf - https://github.com/tendermint/spec/pull/254 +- https://github.com/lazyledger/lazyledger-core/issues/85 + [#17]: https://github.com/lazyledger/lazyledger-core/pull/17 [#19]: https://github.com/lazyledger/lazyledger-core/pull/19 [#83]: https://github.com/lazyledger/lazyledger-core/pull/83 @@ -171,3 +191,8 @@ Proposed [rsmt2d]: https://github.com/lazyledger/rsmt2d +[p2p]: https://github.com/lazyledger/lazyledger-core/tree/master/p2p +[p2p/ipld]: https://github.com/lazyledger/lazyledger-core/tree/master/p2p/ipld +[lazyledger-core/types]: https://github.com/lazyledger/lazyledger-core/tree/master/types + + From 85c35f9ad91b36eadff80cc74bb99e894e2f1f8a Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Mon, 1 Mar 2021 15:09:32 +0100 Subject: [PATCH 03/20] Add ipfs-agnostic part of the library --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 41 ++++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index d8218ed1dd..211f980994 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -78,6 +78,7 @@ Also, there is the idea, that nodes only receive the Header with the data root o and, in an additional step/request, download the DA header using the library, too. While this feature is not considered here, and we assume each node that uses this library has the DA header, this assumption is likely to change when flesh out other parts of the system in more detail. +Note that this also means that light clients would still need to validate that the data root and merkelizing the DA header yield the same result. ## Decision @@ -101,15 +102,47 @@ Add a package to the library that provides the following features: We mention 3. here mostly for completeness. Its details will be described / implemented in a separate ADR / PR. Apart from the above mentioned features, we informally collect additional requirements: -- where randomness is needed, the randomness source should be configurable (but should be the same source per instance) +- where randomness is needed, the randomness source should be configurable - all replies by the network should be verified if this is not sufficiently covered by the used libraries already (IPFS) - where possible, the requests to the network should happen in parallel (without DoSing the proposer for instance). -This feature should be implemented as two new packages: First, a sub-package should be added to the layzledger-core [p2p] package +This library should be implemented as two new packages: + +First, a sub-package should be added to the layzledger-core [p2p] package which does not know anything about the core data structures (Block, DA header etc). -It handles the actual network requests to the IPFS network and operates on IPFS/IPLD objects directly and hence should live under [p2p/ipld] +It handles the actual network requests to the IPFS network and operates on IPFS/IPLD objects directly and hence should live under [p2p/ipld]. + +Second, a high-level API that can "live" closer to the actual types, e.g., in a sub-package in [lazyledger-core/types] +or in a new top-level package `da`. + +We first describe the high-level library here. +Two functions need to be added and we describe them in detail inline in their +godoc comments below. + +```go +// ValidateAvailability implements the protocol described in https://fc21.ifca.ai/papers/83.pdf. +// Specifically all steps of the the protocol described in section +// _5.2 Random Sampling and Network Block Recovery_ are carried out. +// +// In more detail it will first create numSamples random unique coordinates. +// Then, it will ask the network for the leaf data corresponding to these coordinates. +// Additionally to the number of requests, the caller can pass in a callback, +// which will be called on for each retrieved leaf with a verified Merkle proof. +// +// Among other use-cases, the callback can be useful to monitoring (progress), or, +// to process the leaf data the moment it was validated. +func ValidateAvailability(ctx contex.Context, dah *DataAvailabilityHeader, numSamples int, leafSucessCb func(namespacedleaf []byte)) error {/* ... */} + + +// RetrieveBlock can be used to recover the block Data. +// It will carry out a similar protocol as described for ValidateAvailability. +// The key difference is that it will sample enough chunks until it can recover the +// original data. +func RetrieveBlock(ctx contex.Context, dah *DataAvailabilityHeader) (types.Data, error) {/* ... */} +``` + +We now describe the lower-level library that will be used by above methods. -Second, a high-level API that can "live" closer to the actual types, e.g., in a sub-package in [lazyledger-core/types]. From d9882143b3df6837c3f6ef8071da96b246a5b4cd Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Mon, 1 Mar 2021 15:14:44 +0100 Subject: [PATCH 04/20] improve readability in rendered version --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index 211f980994..2fe98d4dce 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -131,8 +131,12 @@ godoc comments below. // // Among other use-cases, the callback can be useful to monitoring (progress), or, // to process the leaf data the moment it was validated. -func ValidateAvailability(ctx contex.Context, dah *DataAvailabilityHeader, numSamples int, leafSucessCb func(namespacedleaf []byte)) error {/* ... */} - +func ValidateAvailability( + ctx contex.Context, + dah *DataAvailabilityHeader, + numSamples int, + leafSucessCb func(namespacedleaf []byte), +) error { /* ... */} // RetrieveBlock can be used to recover the block Data. // It will carry out a similar protocol as described for ValidateAvailability. From de21e31a94ce29281e282371a801b85f63c260f9 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Mon, 1 Mar 2021 19:19:43 +0100 Subject: [PATCH 05/20] slightly restructure and add a PutLeaves and GetLeafData method (wip) --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 39 +++++++++++++++++------ 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index 2fe98d4dce..cd0eee29be 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -20,6 +20,12 @@ For the time being, besides the academic paper, no other formalization or specif Currently, the LazyLedger specification itself only describes the [erasure coding](https://github.com/lazyledger/lazyledger-specs/blob/master/specs/data_structures.md#erasure-coding) and how to retrieve the extended data square from the block data. +This ADR: +- describes the high-level requirements +- defines the API that and how it can be used by different components of LazyLedger (block gossiping, block sync, DA proofs) +- documents decision on how to implement this. + + The core data structures and the erasure coding of the block are already implemented in lazyledger-core ([#17], [#19], [#83]). While there are no ADRs for these changes, we can refer to the LazyLedger specification in this case. For this aspect, the existing implementation and specification should already be on par for the most part. @@ -34,12 +40,6 @@ whose main purpose is to realistically analyse the protocol. Although the prototype does make any network requests and only operates locally, it currently is the most advanced implementation of the protocol. It uses the [rsmt2d] library. - -This ADR describes: - - the high-level requirements - - the API that and how it can be used by different components of LazyLedger (block gossiping, block sync, DA proofs) - - decisions on how to implement this. - The implementation will essentially use IPFS' APIs. For reading (and writing) chunks will use the IPLD [`DagService`](https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/merkledag.go#L54), more precisely the [`NodeGetter`](https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/merkledag.go#L18-L27) @@ -116,7 +116,7 @@ Second, a high-level API that can "live" closer to the actual types, e.g., in a or in a new top-level package `da`. We first describe the high-level library here. -Two functions need to be added and we describe them in detail inline in their +Two functions need to be added, and we describe them in detail inline in their godoc comments below. ```go @@ -131,6 +131,8 @@ godoc comments below. // // Among other use-cases, the callback can be useful to monitoring (progress), or, // to process the leaf data the moment it was validated. +// The context can be used to provide a timeout. +// TODO: Should there be a constant = lower bound for #samples func ValidateAvailability( ctx contex.Context, dah *DataAvailabilityHeader, @@ -143,13 +145,30 @@ func ValidateAvailability( // The key difference is that it will sample enough chunks until it can recover the // original data. func RetrieveBlock(ctx contex.Context, dah *DataAvailabilityHeader) (types.Data, error) {/* ... */} + +// PutLeaves takes the namespaced leaves from the extended data square and calls +// nodes.DataSquareRowOrColumnRawInputParser from the ipld plugin. +// The resulting ipld nodes are passed to a Batch calling AddMany: +// https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/batch.go#L29 +// Note, that this method could also return the row and column roots. +func PutLeaves(namespacedLeaves [][]byte) error ``` We now describe the lower-level library that will be used by above methods. +Again we provide more details inline in the godoc comments directly. - - - +```go +// GetLeafData takes in a Merkle tree root transformed into a Cid +// and the leaf index to retrieve. +// Callers also need to pass in the total number of leaves of that tree +// to be able to create the path (this can also be achieved by traversing the tree until a leaf is reached). +func GetLeafData( + ctx context.Context, + rootCid cid.Cid, + leafIndex uint32, + totalLeafs uint32, +) ([]byte, error) +``` From 3c280cf303155c78be6a95e64c042d3e2a85aa07 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Tue, 2 Mar 2021 01:18:09 +0100 Subject: [PATCH 06/20] Add comment about ipfs and some minor udpates --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 34 +++++++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index cd0eee29be..08feb47b7c 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -147,29 +147,51 @@ func ValidateAvailability( func RetrieveBlock(ctx contex.Context, dah *DataAvailabilityHeader) (types.Data, error) {/* ... */} // PutLeaves takes the namespaced leaves from the extended data square and calls -// nodes.DataSquareRowOrColumnRawInputParser from the ipld plugin. +// nodes.DataSquareRowOrColumnRawInputParser of the ipld plugin. // The resulting ipld nodes are passed to a Batch calling AddMany: // https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/batch.go#L29 // Note, that this method could also return the row and column roots. -func PutLeaves(namespacedLeaves [][]byte) error +// Tha caller is responsible for making sure that the leaves are sorted by namespace ID. +// The data will be pinned by default. +func PutLeaves(ctx contex.Context, namespacedLeaves [][]byte) error ``` +As an alternative to the above `PutLeaves` method, the API could also just take in a block. +Then it would also need to internally do the erasure coding. + We now describe the lower-level library that will be used by above methods. Again we provide more details inline in the godoc comments directly. ```go -// GetLeafData takes in a Merkle tree root transformed into a Cid +// GetLeafData takes in a Namespaced Merkle tree root transformed into a Cid // and the leaf index to retrieve. -// Callers also need to pass in the total number of leaves of that tree -// to be able to create the path (this can also be achieved by traversing the tree until a leaf is reached). +// Callers also need to pass in the total number of leaves of that tree. +// Internally, this will be translated to a path and corresponds to +// a ipfs dag get request, e.g. namespacedCID/0/1/0/0/1. +// The retrieved data will be pinned by default. func GetLeafData( ctx context.Context, rootCid cid.Cid, leafIndex uint32, - totalLeafs uint32, + totalLeafs uint32, // this corresponds to the extended square width ) ([]byte, error) ``` +> TODO: add method that calls GetLeafData often enough until the original data can be reconstructed. + +`GetLeafData` can be used by above `ValidateAvailability` and `RetrieveBlock`. +We do not define a corresponding put-function as above's `PutLeaves` already + +### A Note on IPFS/IPLD + +In IPFS all data is _content addressed_ which basically means the data is identified by its hash. +Particularly, in the LazyLedger case, the root CID identifies the Namespaced Merkle tree including all its contents (inner and leaf nodes). +This means that if a `GetLeafData` request succeeds, the retrieved leaf data is in fact the leaf data in the tree. +We do not need to additionally verify Merkle proofs per leaf as this will essentially be done via IPFS on each layer while +resolving and getting to the leaf data. + +> TODO: validate this assumption and link to code that shows how this is done internally + > This section does not need to be filled in at the start of the ADR, but must be completed prior to the merging of the implementation. From 697f1863422689357de4c51bfe5e11833d5d9154 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Tue, 2 Mar 2021 10:31:46 +0100 Subject: [PATCH 07/20] Refactored the main API and moved putting the leaves down the stack --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 97 +++++++++-------------- 1 file changed, 38 insertions(+), 59 deletions(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index 08feb47b7c..1dd9d5ee1c 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -90,8 +90,6 @@ Note that this also means that light clients would still need to validate that t > - mention [ipld experiments] - - ## Detailed Design Add a package to the library that provides the following features: @@ -108,16 +106,22 @@ Apart from the above mentioned features, we informally collect additional requir This library should be implemented as two new packages: -First, a sub-package should be added to the layzledger-core [p2p] package +First, if necessary, a sub-package should be added to the layzledger-core [p2p] package which does not know anything about the core data structures (Block, DA header etc). -It handles the actual network requests to the IPFS network and operates on IPFS/IPLD objects directly and hence should live under [p2p/ipld]. +It handles the actual network requests to the IPFS network and operates on IPFS/IPLD objects +directly and hence should live under [p2p/ipld]. +To a some extent this part of the stack already exists. Second, a high-level API that can "live" closer to the actual types, e.g., in a sub-package in [lazyledger-core/types] or in a new top-level package `da`. -We first describe the high-level library here. -Two functions need to be added, and we describe them in detail inline in their -godoc comments below. +We first describe the high-level library here and describe functions in +more detail inline with their godoc comments below. + +### API that operates on ll-core types (da package) + +As mentioned above this part of the library has knowledge of the core types (and hence depends on them). +It does not deal with IPFS internals. ```go // ValidateAvailability implements the protocol described in https://fc21.ifca.ai/papers/83.pdf. @@ -140,47 +144,55 @@ func ValidateAvailability( leafSucessCb func(namespacedleaf []byte), ) error { /* ... */} -// RetrieveBlock can be used to recover the block Data. +// RetrieveBlockData can be used to recover the block Data. // It will carry out a similar protocol as described for ValidateAvailability. // The key difference is that it will sample enough chunks until it can recover the -// original data. -func RetrieveBlock(ctx contex.Context, dah *DataAvailabilityHeader) (types.Data, error) {/* ... */} +// full extended data square, including original data (e.g. by using rsmt2d.RepairExtendedDataSquare). +func RetrieveBlockData(ctx contex.Context, dah *DataAvailabilityHeader) (types.Data, error) {/* ... */} -// PutLeaves takes the namespaced leaves from the extended data square and calls -// nodes.DataSquareRowOrColumnRawInputParser of the ipld plugin. -// The resulting ipld nodes are passed to a Batch calling AddMany: -// https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/batch.go#L29 +// PutBlock operates directly on the Block. +// It first computes the erasure coding, aka the extended data square. +// Row by row calls a lower level library which handles adding the +// the row to the Merkle Dag, in our case a Namespaced Merkle Tree. // Note, that this method could also return the row and column roots. -// Tha caller is responsible for making sure that the leaves are sorted by namespace ID. // The data will be pinned by default. -func PutLeaves(ctx contex.Context, namespacedLeaves [][]byte) error +func (b *Block) PutBlock(ctx contex.Context) error ``` -As an alternative to the above `PutLeaves` method, the API could also just take in a block. -Then it would also need to internally do the erasure coding. - We now describe the lower-level library that will be used by above methods. Again we provide more details inline in the godoc comments directly. +`PutBlock` is a method on `Block` as the erasure coding can then be cached, e.g. in a private field +in the block. + +### Changes to the lower level API closer to IPFS (p2p/ipld) + ```go // GetLeafData takes in a Namespaced Merkle tree root transformed into a Cid // and the leaf index to retrieve. // Callers also need to pass in the total number of leaves of that tree. -// Internally, this will be translated to a path and corresponds to -// a ipfs dag get request, e.g. namespacedCID/0/1/0/0/1. -// The retrieved data will be pinned by default. +// Internally, this will be translated to a IPLD path and corresponds to +// an ipfs dag get request, e.g. namespacedCID/0/1/0/0/1. +// The retrieved data should be pinned by default. func GetLeafData( ctx context.Context, rootCid cid.Cid, leafIndex uint32, totalLeafs uint32, // this corresponds to the extended square width ) ([]byte, error) -``` -> TODO: add method that calls GetLeafData often enough until the original data can be reconstructed. +// PutLeaves takes the namespaced leaves, a row of the from the extended data square, +// and calls nodes.DataSquareRowOrColumnRawInputParser of the ipld plugin. +// The resulting ipld nodes are passed to a Batch calling AddMany: +// https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/batch.go#L29 +// Note, that this method could also return the row and column roots. +// Tha caller is responsible for making sure that the leaves are sorted by namespace ID. +// The data will be pinned by default. +func PutLeaves(ctx contex.Context, namespacedLeaves [][]byte) error +``` -`GetLeafData` can be used by above `ValidateAvailability` and `RetrieveBlock`. -We do not define a corresponding put-function as above's `PutLeaves` already +`GetLeafData` can be used by above `ValidateAvailability` and `RetrieveBlock` and +`PutLeaves` by `PutBlock`. ### A Note on IPFS/IPLD @@ -193,41 +205,8 @@ resolving and getting to the leaf data. > TODO: validate this assumption and link to code that shows how this is done internally - -> This section does not need to be filled in at the start of the ADR, but must be completed prior to the merging of the implementation. -> -> Here are some common questions that get answered as part of the detailed design: -> -> - What are the user requirements? -> -> - What systems will be affected? -> -> - What new data structures are needed, what data structures will be changed? -> -> - What new APIs will be needed, what APIs will be changed? -> -> - What are the efficiency considerations (time/space)? -> -> - What are the expected access patterns (load/throughput)? -> -> - Are there any logging, monitoring or observability needs? -> -> - Are there any security considerations? -> -> - Are there any privacy considerations? -> -> - How will the changes be tested? -> -> - If the change is large, how will the changes be broken up for ease of review? -> -> - Will these changes require a breaking (major) release? -> -> - Does this change require coordination with the SDK or other? - ## Status -> A decision may be "proposed" if it hasn't been agreed upon yet, or "accepted" once it is agreed upon. Once the ADR has been implemented mark the ADR as "implemented". If a later ADR changes or reverses a decision, it may be marked as "deprecated" or "superseded" with a reference to its replacement. - Proposed ## Consequences From bef6ca45ee86f0327af4af495cc7199e5f7c26ee Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Tue, 2 Mar 2021 10:35:31 +0100 Subject: [PATCH 08/20] minor language glichtes and a clarification --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index 1dd9d5ee1c..acb73a4f92 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -152,9 +152,9 @@ func RetrieveBlockData(ctx contex.Context, dah *DataAvailabilityHeader) (types.D // PutBlock operates directly on the Block. // It first computes the erasure coding, aka the extended data square. -// Row by row calls a lower level library which handles adding the +// Row by row ir calls a lower level library which handles adding the // the row to the Merkle Dag, in our case a Namespaced Merkle Tree. -// Note, that this method could also return the row and column roots. +// Note, that this method could also fill the DA header. // The data will be pinned by default. func (b *Block) PutBlock(ctx contex.Context) error ``` From 23d0ae49cd5be6c30250d07b706db0d26d0e3ac7 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Tue, 2 Mar 2021 13:00:36 +0100 Subject: [PATCH 09/20] Add some pros/cons --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index acb73a4f92..1acb467054 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -216,24 +216,28 @@ Proposed ### Positive - simplicity & ease of implementation + - can re-use an existing networking and p2p stack (go-ipfs) + - potential support of large, cool, and helpful community + - high-level API definitions independent of the used stack ### Negative - latency - being connected to the public IPFS network might be overkill if peers should in fact only care about a subset that participates in the LazyLedger protocol + - dependency on a large code-base with lots of features and options of which we only need a small subset of ### Neutral ## References -> Are there any relevant PR comments, issues that led up to this, or articles referenced for why we made the given design choice? If so link them here! +- https://github.com/lazyledger/lazyledger-core/issues/85 +- https://github.com/lazyledger/lazyledger-core/issues/167 - https://docs.ipld.io/#nodes - https://arxiv.org/abs/1809.09044 - https://fc21.ifca.ai/papers/83.pdf - https://github.com/tendermint/spec/pull/254 -- https://github.com/lazyledger/lazyledger-core/issues/85 [#17]: https://github.com/lazyledger/lazyledger-core/pull/17 [#19]: https://github.com/lazyledger/lazyledger-core/pull/19 From b7f31e2dc3df28abcd427f97ca5b8a5bdf0ba623 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Tue, 2 Mar 2021 13:45:48 +0100 Subject: [PATCH 10/20] break up changes into smaller packages for the sake of reviewability --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 37 ++++++++++++++++++----- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index 1acb467054..1ac865bbfa 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -18,7 +18,7 @@ A high-level, implementation-independent formalization of above mentioned sampli For the time being, besides the academic paper, no other formalization or specification of the protocol exists. Currently, the LazyLedger specification itself only describes the [erasure coding](https://github.com/lazyledger/lazyledger-specs/blob/master/specs/data_structures.md#erasure-coding) -and how to retrieve the extended data square from the block data. +and how to construct the extended data square from the block data. This ADR: - describes the high-level requirements @@ -90,14 +90,19 @@ Note that this also means that light clients would still need to validate that t > - mention [ipld experiments] + ## Detailed Design Add a package to the library that provides the following features: - 1. sample a given number of random row/col indices of extended data square given a DA header and indicate if successful or timeout/other error occurred. - 2. reconstruct the whole block from a given DA header - 3. get all messages of a particular namespace ID. + 1. sample a given number of random row/col indices of extended data square given a DA header and indicate if successful or timeout/other error occurred + 2. store the block in the network + 3. store the sampled chunks in the network + 4. reconstruct the whole block from a given DA header + 5. get all messages of a particular namespace ID. + + -We mention 3. here mostly for completeness. Its details will be described / implemented in a separate ADR / PR. +We mention 5. here mostly for completeness. Its details will be described / implemented in a separate ADR / PR. Apart from the above mentioned features, we informally collect additional requirements: - where randomness is needed, the randomness source should be configurable @@ -106,19 +111,19 @@ Apart from the above mentioned features, we informally collect additional requir This library should be implemented as two new packages: -First, if necessary, a sub-package should be added to the layzledger-core [p2p] package +First, a sub-package should be added to the layzledger-core [p2p] package which does not know anything about the core data structures (Block, DA header etc). It handles the actual network requests to the IPFS network and operates on IPFS/IPLD objects directly and hence should live under [p2p/ipld]. To a some extent this part of the stack already exists. Second, a high-level API that can "live" closer to the actual types, e.g., in a sub-package in [lazyledger-core/types] -or in a new top-level package `da`. +or in a new sub-package `da`. We first describe the high-level library here and describe functions in more detail inline with their godoc comments below. -### API that operates on ll-core types (da package) +### API that operates on ll-core types As mentioned above this part of the library has knowledge of the core types (and hence depends on them). It does not deal with IPFS internals. @@ -204,6 +209,21 @@ resolving and getting to the leaf data. > TODO: validate this assumption and link to code that shows how this is done internally +### Implementation plan + +As fully integrating Data Available proofs into tendermint, is a rather larger change we break up the work into the +following packages (not mentioning the implementation work that was already done): + +1. Flesh out the changes in the consensus messages (lazyledger/lazyledger-specs#126, lazyledger/lazyledger-specs#127) +2. Flesh out the changes that would be necessary to replace the current block gossiping ([LAZY ADR 001](./adr-001-block-propagation.md)) +3. Add the possibility of storing and retrieving block data (samples or whole block) to lazyledger-core (this ADR and related PRs). +4. Integrate above API (3.) as an addition into lazyledger-core without directly replacing the tendermint counterparts (block gossip etc). +5. Rip out each component that will be redundant with above integration in one or even several smaller PRs: + - block gossiping (see LAZY ADR 001) + - modify block store (see LAZY ADR 001) + - make downloading full Blocks optional (flag/config) + - route some RPC requests to IPFS (see LAZY ADR 001) + ## Status @@ -227,6 +247,7 @@ Proposed - dependency on a large code-base with lots of features and options of which we only need a small subset of ### Neutral + - two different p2p layers exist in lazyledger-core ## References From b40785b61008baea1bf03ec2180ca6c1c11a2f2e Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Tue, 2 Mar 2021 14:14:33 +0100 Subject: [PATCH 11/20] mention batch adding in context, too --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index 1ac865bbfa..7490d24d3c 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -44,6 +44,8 @@ The implementation will essentially use IPFS' APIs. For reading (and writing) ch will use the IPLD [`DagService`](https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/merkledag.go#L54), more precisely the [`NodeGetter`](https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/merkledag.go#L18-L27) and [`NodeAdder`](https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/merkledag.go#L29-L39). +As an optimization, we can also use a [`Batch`](https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/batch.go#L29) +to batch add and remove nodes. This will be achieved by passing around a [CoreAPI](https://github.com/ipfs/interface-go-ipfs-core/blob/b935dfe5375eac7ea3c65b14b3f9a0242861d0b3/coreapi.go#L15) object, which derive from the ipfs node which is created along a with a tendermint node (see [#152]). This code snippet does exactly that (see the [go-ipfs documentation] for more examples): From d34fa08ef5065f074786b3339045d1dfc72e283e Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Tue, 2 Mar 2021 14:26:26 +0100 Subject: [PATCH 12/20] minor clarification --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index 7490d24d3c..bec21a72c2 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -7,7 +7,7 @@ ## Context In Tendermint's block gossiping each peer gossips random parts of block data to peers. -For LazyLedger, we need nodes (from light-clients to validators) to be able to sample rows/columns of the erasure coded +For LazyLedger, we need nodes (from light-clients to validators) to be able to sample row-/column-chunks of the erasure coded block (aka the extended data square) from the network. This is necessary for Data Availability proofs. From 4cf8b75a76886c96bf42b7cd8a8693c9d6ffcba3 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Wed, 3 Mar 2021 02:50:56 +0100 Subject: [PATCH 13/20] Apply a batch of suggestions Co-authored-by: John Adler --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 29 ++++++++++------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index 7490d24d3c..0a1885022b 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -68,13 +68,13 @@ and/or in a few smaller, separate followup ADRs. ## Alternative Approaches -Instead of creating a full ipfs node object and passing it around as explained above +Instead of creating a full IPFS node object and passing it around as explained above - use API (http) - use ipld-light - use alternative client Also, for better performance - - use graph-sync, ipld selectors (ipld-prime) + - use graph-sync, IPLD selectors (ipld-prime) Also, there is the idea, that nodes only receive the Header with the data root only and, in an additional step/request, download the DA header using the library, too. @@ -102,8 +102,6 @@ Add a package to the library that provides the following features: 4. reconstruct the whole block from a given DA header 5. get all messages of a particular namespace ID. - - We mention 5. here mostly for completeness. Its details will be described / implemented in a separate ADR / PR. Apart from the above mentioned features, we informally collect additional requirements: @@ -125,14 +123,14 @@ or in a new sub-package `da`. We first describe the high-level library here and describe functions in more detail inline with their godoc comments below. -### API that operates on ll-core types +### API that operates on lazyledger-core types As mentioned above this part of the library has knowledge of the core types (and hence depends on them). It does not deal with IPFS internals. ```go // ValidateAvailability implements the protocol described in https://fc21.ifca.ai/papers/83.pdf. -// Specifically all steps of the the protocol described in section +// Specifically all steps of the protocol described in section // _5.2 Random Sampling and Network Block Recovery_ are carried out. // // In more detail it will first create numSamples random unique coordinates. @@ -233,23 +231,21 @@ Proposed ## Consequences -> This section describes the consequences, after applying the decision. All consequences should be summarized here, not just the "positive" ones. - ### Positive - - simplicity & ease of implementation - - can re-use an existing networking and p2p stack (go-ipfs) - - potential support of large, cool, and helpful community - - high-level API definitions independent of the used stack +- simplicity & ease of implementation +- can re-use an existing networking and p2p stack (go-ipfs) +- potential support of large, cool, and helpful community +- high-level API definitions independent of the used stack ### Negative - - latency - - being connected to the public IPFS network might be overkill if peers should in fact only care about a subset that participates in the LazyLedger protocol - - dependency on a large code-base with lots of features and options of which we only need a small subset of +- latency +- being connected to the public IPFS network might be overkill if peers should in fact only care about a subset that participates in the LazyLedger protocol +- dependency on a large code-base with lots of features and options of which we only need a small subset of ### Neutral - - two different p2p layers exist in lazyledger-core +- two different p2p layers exist in lazyledger-core ## References @@ -279,4 +275,3 @@ Proposed [p2p/ipld]: https://github.com/lazyledger/lazyledger-core/tree/master/p2p/ipld [lazyledger-core/types]: https://github.com/lazyledger/lazyledger-core/tree/master/types - From 69ea2ba79a15767a0b63a6427dd255183b3a29d1 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Wed, 3 Mar 2021 02:52:34 +0100 Subject: [PATCH 14/20] Apply suggestions from code review Co-authored-by: John Adler --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index 0a1885022b..0edde4cf21 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -45,21 +45,21 @@ will use the IPLD [`DagService`](https://github.com/ipfs/go-ipld-format/blob/d2e more precisely the [`NodeGetter`](https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/merkledag.go#L18-L27) and [`NodeAdder`](https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/merkledag.go#L29-L39). As an optimization, we can also use a [`Batch`](https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/batch.go#L29) -to batch add and remove nodes. +to batch adding and removing nodes. This will be achieved by passing around a [CoreAPI](https://github.com/ipfs/interface-go-ipfs-core/blob/b935dfe5375eac7ea3c65b14b3f9a0242861d0b3/coreapi.go#L15) -object, which derive from the ipfs node which is created along a with a tendermint node (see [#152]). +object, which derive from the IPFS node which is created along a with a tendermint node (see [#152]). This code snippet does exactly that (see the [go-ipfs documentation] for more examples): -````go +```go // This constructs an IPFS node instance node, _ := core.NewNode(ctx, nodeOptions) // This attaches the Core API to the constructed node coreApi := coreapi.NewCoreAPI(node) -```` +``` The above mentioned IPLD methods operate on so called [ipld.Nodes]. When computing the data root, we can pass in a [`NodeVisitor`](https://github.com/lazyledger/nmt/blob/b22170d6f23796a186c07e87e4ef9856282ffd1a/nmt.go#L22) into the Namespaced Merkle Tree library to create these (each inner- and leaf-node in the tree becomes an ipld node). -As a peer that requests such an ipld node, the LazyLedger ipld plugin provides the [function](https://github.com/lazyledger/lazyledger-core/blob/ceb881a177b6a4a7e456c7c4ab1dd0eb2b263066/p2p/ipld/plugin/nodes/nodes.go#L175) +As a peer that requests such an IPLD node, the LazyLedger IPLD plugin provides the [function](https://github.com/lazyledger/lazyledger-core/blob/ceb881a177b6a4a7e456c7c4ab1dd0eb2b263066/p2p/ipld/plugin/nodes/nodes.go#L175) `NmtNodeParser` to transform the retrieved raw data back into an `ipld.Node`. A more high-level description on the changes required to rip out the current block gossiping routine, @@ -274,4 +274,3 @@ Proposed [p2p]: https://github.com/lazyledger/lazyledger-core/tree/master/p2p [p2p/ipld]: https://github.com/lazyledger/lazyledger-core/tree/master/p2p/ipld [lazyledger-core/types]: https://github.com/lazyledger/lazyledger-core/tree/master/types - From 795056e500f79878671f574028c1df0e874189e4 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Wed, 3 Mar 2021 13:47:09 +0100 Subject: [PATCH 15/20] Address some more review feedback --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index 5ae4aa4a9d..a7a1c88c44 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -37,10 +37,10 @@ This new method is a sub-set of the proposed ABCI changes aka [ABCI++](https://g Mustafa Al-Bassam (@musalbas) implemented a [prototype](https://github.com/lazyledger/lazyledger-prototype) whose main purpose is to realistically analyse the protocol. -Although the prototype does make any network requests and only operates locally, it currently is the most advanced implementation of the protocol. +Although the prototype does not make any network requests and only operates locally, it can partly serve as a reference implementation. It uses the [rsmt2d] library. -The implementation will essentially use IPFS' APIs. For reading (and writing) chunks +The implementation will essentially use IPFS' APIs. For reading (and writing) chunks it will use the IPLD [`DagService`](https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/merkledag.go#L54), more precisely the [`NodeGetter`](https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/merkledag.go#L18-L27) and [`NodeAdder`](https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/merkledag.go#L29-L39). From bd45d7e6657bb3f825bc23643648d9cf649469fb Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 4 Mar 2021 09:45:41 +0100 Subject: [PATCH 16/20] add links --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index a7a1c88c44..7ec8c27c2f 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -74,7 +74,7 @@ Instead of creating a full IPFS node object and passing it around as explained a - use alternative client Also, for better performance - - use graph-sync, IPLD selectors (ipld-prime) + - use [graph-sync], [IPLD selectors], e.g. via [ipld-prime] Also, there is the idea, that nodes only receive the Header with the data root only and, in an additional step/request, download the DA header using the library, too. @@ -267,6 +267,9 @@ Proposed [go-ipfs documentation]: https://github.com/ipfs/go-ipfs/tree/master/docs/examples/go-ipfs-as-a-library#use-go-ipfs-as-a-library-to-spawn-a-node-and-add-a-file [ipld experiments]: https://github.com/lazyledger/ipld-plugin-experiments [ipld.Nodes]: https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/format.go#L22-L45 +[graph-sync]: https://github.com/ipld/specs/blob/master/block-layer/graphsync/graphsync.md +[IPLD selectors]: https://github.com/ipld/specs/blob/master/selectors/selectors.md +[ipld-prime]: https://github.com/ipld/go-ipld-prime [rsmt2d]: https://github.com/lazyledger/rsmt2d From dc84db8b5a5a89eb84ad4f4c3bb1d92ac8f1cd1e Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 4 Mar 2021 10:27:19 +0100 Subject: [PATCH 17/20] add more links --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index 7ec8c27c2f..b2a3b00ea2 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -214,7 +214,7 @@ resolving and getting to the leaf data. As fully integrating Data Available proofs into tendermint, is a rather larger change we break up the work into the following packages (not mentioning the implementation work that was already done): -1. Flesh out the changes in the consensus messages (lazyledger/lazyledger-specs#126, lazyledger/lazyledger-specs#127) +1. Flesh out the changes in the consensus messages ([lazyledger-specs#126], [lazyledger-specs#127]) 2. Flesh out the changes that would be necessary to replace the current block gossiping ([LAZY ADR 001](./adr-001-block-propagation.md)) 3. Add the possibility of storing and retrieving block data (samples or whole block) to lazyledger-core (this ADR and related PRs). 4. Integrate above API (3.) as an addition into lazyledger-core without directly replacing the tendermint counterparts (block gossip etc). @@ -264,6 +264,9 @@ Proposed [#152]: https://github.com/lazyledger/lazyledger-core/pull/152 +[lazyledger-specs#126]: https://github.com/lazyledger/lazyledger-specs/issues/126 +[lazyledger-specs#127]: https://github.com/lazyledger/lazyledger-specs/pulls/127 + [go-ipfs documentation]: https://github.com/ipfs/go-ipfs/tree/master/docs/examples/go-ipfs-as-a-library#use-go-ipfs-as-a-library-to-spawn-a-node-and-add-a-file [ipld experiments]: https://github.com/lazyledger/ipld-plugin-experiments [ipld.Nodes]: https://github.com/ipfs/go-ipld-format/blob/d2e09424ddee0d7e696d01143318d32d0fb1ae63/format.go#L22-L45 From 5deebfce9c0fa2dca2b878e70a5d181a62f63838 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 4 Mar 2021 12:18:04 +0100 Subject: [PATCH 18/20] permalinks as requested --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index b2a3b00ea2..1af06c6a51 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -277,6 +277,6 @@ Proposed [rsmt2d]: https://github.com/lazyledger/rsmt2d -[p2p]: https://github.com/lazyledger/lazyledger-core/tree/master/p2p -[p2p/ipld]: https://github.com/lazyledger/lazyledger-core/tree/master/p2p/ipld -[lazyledger-core/types]: https://github.com/lazyledger/lazyledger-core/tree/master/types +[p2p]: https://github.com/lazyledger/lazyledger-core/tree/0eccfb24e2aa1bb9c4428e20dd7828c93f300e60/p2p +[p2p/ipld]: https://github.com/lazyledger/lazyledger-core/tree/0eccfb24e2aa1bb9c4428e20dd7828c93f300e60/p2p/ipld +[lazyledger-core/types]: https://github.com/lazyledger/lazyledger-core/tree/0eccfb24e2aa1bb9c4428e20dd7828c93f300e60/types From 099f18cd90cca11a433c37934673152822240468 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 4 Mar 2021 12:36:31 +0100 Subject: [PATCH 19/20] link Header --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index 1af06c6a51..02f14f7fff 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -76,7 +76,7 @@ Instead of creating a full IPFS node object and passing it around as explained a Also, for better performance - use [graph-sync], [IPLD selectors], e.g. via [ipld-prime] -Also, there is the idea, that nodes only receive the Header with the data root only +Also, there is the idea, that nodes only receive the [Header] with the data root only and, in an additional step/request, download the DA header using the library, too. While this feature is not considered here, and we assume each node that uses this library has the DA header, this assumption is likely to change when flesh out other parts of the system in more detail. @@ -266,6 +266,7 @@ Proposed [lazyledger-specs#126]: https://github.com/lazyledger/lazyledger-specs/issues/126 [lazyledger-specs#127]: https://github.com/lazyledger/lazyledger-specs/pulls/127 +[Header]: https://github.com/lazyledger/lazyledger-specs/blob/master/specs/data_structures.md#header [go-ipfs documentation]: https://github.com/ipfs/go-ipfs/tree/master/docs/examples/go-ipfs-as-a-library#use-go-ipfs-as-a-library-to-spawn-a-node-and-add-a-file [ipld experiments]: https://github.com/lazyledger/ipld-plugin-experiments From 2ff8fc9d48b00e3d2d2d962a31e878161b5aafeb Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 4 Mar 2021 12:42:29 +0100 Subject: [PATCH 20/20] less abstract description of "store the block in the network" --- docs/lazy-adr/adr-002-ipds-da-sampling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/lazy-adr/adr-002-ipds-da-sampling.md b/docs/lazy-adr/adr-002-ipds-da-sampling.md index 02f14f7fff..cb21e75499 100644 --- a/docs/lazy-adr/adr-002-ipds-da-sampling.md +++ b/docs/lazy-adr/adr-002-ipds-da-sampling.md @@ -97,7 +97,7 @@ Note that this also means that light clients would still need to validate that t Add a package to the library that provides the following features: 1. sample a given number of random row/col indices of extended data square given a DA header and indicate if successful or timeout/other error occurred - 2. store the block in the network + 2. store the block in the network by adding it to the peer's local Merkle-DAG whose content is discoverable via a DHT 3. store the sampled chunks in the network 4. reconstruct the whole block from a given DA header 5. get all messages of a particular namespace ID.