From 03ba95968373a503bb7f6d10a510823682c7e24d Mon Sep 17 00:00:00 2001 From: Quentin McGaw Date: Thu, 12 May 2022 12:55:43 +0000 Subject: [PATCH] Update documentation - Remove `encode_doc.go` - Add `README.md` with Codec section - Update comments for `Encode` and `Decode` methods - Add `node` package comment --- internal/trie/node/README.md | 31 +++++++++++++++++++++++++++++++ internal/trie/node/decode.go | 7 +++++-- internal/trie/node/encode.go | 4 +++- internal/trie/node/encode_doc.go | 23 ----------------------- internal/trie/node/node.go | 2 ++ 5 files changed, 41 insertions(+), 26 deletions(-) create mode 100644 internal/trie/node/README.md delete mode 100644 internal/trie/node/encode_doc.go diff --git a/internal/trie/node/README.md b/internal/trie/node/README.md new file mode 100644 index 00000000000..cae00b0ff04 --- /dev/null +++ b/internal/trie/node/README.md @@ -0,0 +1,31 @@ +# Trie node + +Package node defines the `Node` structure with methods to be used in the modified Merkle-Patricia Radix-16 trie. + +## Codec + +The following sub-sections precise the encoding of a node. +This encoding is formally described in [the Polkadot specification](https://spec.polkadot.network/#sect-state-storage). + +### Header + +Each node encoding has a header of one or more bytes. +The first byte contains the node variant and some or all of the partial key length of the node. +If the partial key length cannot fit in the first byte, additional bytes are added to the header to represent the total partial key length. + +### Partial key + +The header is then concatenated with the partial key of the node, encoded as Little Endian bytes. + +### Remaining bytes + +The remaining bytes appended depend on the node variant. + +- For leaves, the SCALE-encoded leaf value is appended. +- For branches, the following elements are concatenated in this order and appended to the previous header+partial key: + - Children bitmap (2 bytes) + - SCALE-encoded node value + - Hash(Encoding(Child[0])) + - Hash(Encoding(Child[1])) + - ... + - Hash(Encoding(Child[15])) diff --git a/internal/trie/node/decode.go b/internal/trie/node/decode.go index 5a9cbba4b98..6861c3ed23e 100644 --- a/internal/trie/node/decode.go +++ b/internal/trie/node/decode.go @@ -19,6 +19,9 @@ var ( ) // Decode decodes a node from a reader. +// The encoding format is documented in the README.md +// of this package, and specified in the Polkadot spec at +// https://spec.polkadot.network/#sect-state-storage // For branch decoding, see the comments on decodeBranch. // For leaf decoding, see the comments on decodeLeaf. func Decode(reader io.Reader) (n *Node, err error) { @@ -47,7 +50,7 @@ func Decode(reader io.Reader) (n *Node, err error) { } } -// decodeBranch reads and decodes from a reader with the encoding specified in internal/trie/node/encode_doc.go. +// decodeBranch reads from a reader and decodes to a node branch. // Note that since the encoded branch stores the hash of the children nodes, we are not // reconstructing the child nodes from the encoding. This function instead stubs where the // children are known to be with an empty leaf. The children nodes hashes are then used to @@ -115,7 +118,7 @@ func decodeBranch(reader io.Reader, variant byte, partialKeyLength uint16) ( return node, nil } -// decodeLeaf reads and decodes from a reader with the encoding specified in lib/trie/node/encode_doc.go. +// decodeLeaf reads from a reader and decodes to a leaf node. func decodeLeaf(reader io.Reader, partialKeyLength uint16) (node *Node, err error) { node = &Node{ Dirty: true, diff --git a/internal/trie/node/encode.go b/internal/trie/node/encode.go index c7890e16a82..5bea739c0ce 100644 --- a/internal/trie/node/encode.go +++ b/internal/trie/node/encode.go @@ -12,7 +12,9 @@ import ( ) // Encode encodes the node to the buffer given. -// The encoding format is documented in encode_doc.go. +// The encoding format is documented in the README.md +// of this package, and specified in the Polkadot spec at +// https://spec.polkadot.network/#sect-state-storage func (n *Node) Encode(buffer Buffer) (err error) { if !n.Dirty && n.Encoding != nil { _, err = buffer.Write(n.Encoding) diff --git a/internal/trie/node/encode_doc.go b/internal/trie/node/encode_doc.go deleted file mode 100644 index 416d49c9b58..00000000000 --- a/internal/trie/node/encode_doc.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2021 ChainSafe Systems (ON) -// SPDX-License-Identifier: LGPL-3.0-only - -package node - -// Each node encoding has a header of one or more bytes. -// The first byte contains the node variant and some -// or all of the partial key length of the node. -// If the partial key length cannot fit in the first byte, -// additional bytes are added to the header to represent -// the total partial key length. -// The header is then concatenated with the partial key, -// encoded as Little Endian bytes. -// The rest concatenated depends on the node variant. -// -// For leaves, the SCALE-encoded leaf value is concatenated. -// For branches, the following is concatenated, where -// `|` denotes concatenation: -// 2 bytes children bitmap | SCALE-encoded branch value | -// Hash(Encoding(Child[0])) | ... | Hash(Encoding(Child[n])) -// -// See https://spec.polkadot.network/#sect-state-storage -// for more details. diff --git a/internal/trie/node/node.go b/internal/trie/node/node.go index 493ca1de915..a40cf31fd7a 100644 --- a/internal/trie/node/node.go +++ b/internal/trie/node/node.go @@ -1,6 +1,8 @@ // Copyright 2021 ChainSafe Systems (ON) // SPDX-License-Identifier: LGPL-3.0-only +// Package node defines the `Node` structure with methods +// to be used in the modified Merkle-Patricia Radix-16 trie. package node import (