UNPKG

@chainsafe/ssz

Version:

Simple Serialize

70 lines 3.3 kB
import { BranchNode } from "@chainsafe/persistent-merkle-tree"; /** Duplicated partial declaration to break circular dependency with CompositeType */ function isCompositeType(type) { return !type.isBasic; } /** * Navigates and mutates nodes to post process a tree created with `Tree.createFromProof`. * Tree returns regular a tree with only BranchNode and LeafNode instances. However, SSZ features * non-standard nodes that make proofs for those types to be un-usable. This include: * - BranchNodeStruct: Must contain complete data `tree_fromProofNode` transforms a BranchNode and * all of its data into a single BranchNodeStruct instance. * * @param bitstring Bitstring without the leading "1", since it's only used to compute horizontal indexes. */ export function treePostProcessFromProofNode(node, type, bitstring = "", currentDepth = 0) { // Must run tree_fromProofNode on the first received node (i.e. Validator object) if (currentDepth === 0) { const nodePost = type.tree_fromProofNode(node); if (nodePost.done) return nodePost.node; node = nodePost.node; } const atTypeDepth = type.depth === currentDepth; if (node.isLeaf()) { if (atTypeDepth) { const jsonPathProp = type.getIndexProperty(bitstringToIndex(bitstring)); if (jsonPathProp === null) { // bitstring is out of bounds, witness node return node; } const childType = type.getPropertyType(jsonPathProp); // If this type merkleized fits in a single chunk then this LeafNode includes all data if (childType.maxChunkCount === 1 && isCompositeType(childType)) { return childType.tree_fromProofNode(node).node; } // Witness node return node; } // LeafNode not at type depth is a witness or a length / selector nodes return node; } if (atTypeDepth) { const jsonPathProp = type.getIndexProperty(bitstringToIndex(bitstring)); // bitstring is out of bounds, witness node if (jsonPathProp === null) return node; const childType = type.getPropertyType(jsonPathProp); if (!isCompositeType(childType)) { throw Error("BranchNode does not map to CompositeType"); } const nodePost = childType.tree_fromProofNode(node); // If tree_fromProofNode is the identity function, keep going, otherwise stop navigating if (nodePost.done) return nodePost.node; return treePostProcessFromProofNode(nodePost.node, childType); } // BranchNode at not type depth, keep navigating const leftNode = treePostProcessFromProofNode(node.left, type, `${bitstring}0`, currentDepth + 1); const rightNode = treePostProcessFromProofNode(node.right, type, `${bitstring}1`, currentDepth + 1); if (leftNode === node.left && rightNode === node.right) return node; return new BranchNode(leftNode, rightNode); } /** Return the node horizontal index given a bitstring without the leading "1" */ function bitstringToIndex(bitstring) { if (bitstring === "") return 0; return parseInt(bitstring, 2); } //# sourceMappingURL=treePostProcessFromProofNode.js.map