protected void BuildAuditTrail(List <MerkleProofHash> auditTrail, MerkleNode parent, MerkleNode child) { if (parent != null) { Contract(() => child.Parent == parent, "Parent of child is not expected parent."); var nextChild = parent.LeftNode == child ? parent.RightNode : parent.LeftNode; var direction = parent.LeftNode == child ? MerkleProofHash.Branch.Left : MerkleProofHash.Branch.Right; // For the last leaf, the right node may not exist. In that case, we ignore it because it's // the hash we are given to verify. if (nextChild != null) { auditTrail.Add(new MerkleProofHash(nextChild.Hash, direction)); } BuildAuditTrail(auditTrail, child.Parent.Parent, child.Parent); } }
protected virtual MerkleNode CreateNode(MerkleNode left, MerkleNode right) { return(new MerkleNode(left, right)); }
/// <summary> /// 함수 이름이 일관적인 감사다..;; /// </summary> /// <param name="m"></param> /// <returns></returns> public List <MerkleProofHash> ConsistencyProof(int m) { // Rule 1: // 일관성 증명을 시작할 수 있는 트리의 가장 왼쪽 노드를 찾는다. // 이 노드의 입사귀 갯수를 k로 설정한다. List <MerkleProofHash> hashNodes = new List <MerkleProofHash>(); int idx = (int)Math.Log(m, 2); // 맨 왼쪽 노드를 가져온다. MerkleNode node = leaves[0]; // idx가 지정된 노드에 도달할 때까지 트리를 탐색. while (idx > 0) { node = node.Parent; --idx; } int k = node.Leaves().Count(); hashNodes.Add(new MerkleProofHash(node.Hash, MerkleProofHash.Branch.OldRoot)); if (m == k) { // Continue with Rule 3 -- the remainder is the audit proof } else { // Rule 2: // 초기 형제 노드 (SN)를 규칙 1에 의해 획득 된 노드의 형제로 설정합니다. // m-k == # SN의 잎의 # 경우 형제 SN의 해시를 연결하고 규칙 2를 종료하십시오. 이는 이전 루트의 해시를 나타냅니다. // m-k <SN의 잎수이면 SN을 왼쪽 자식 노드로 설정하고 규칙 2를 반복합니다. // sibling node: MerkleNode sn = node.Parent.RightNode; bool traverseTree = true; while (traverseTree) { Contract(() => sn != null, "Sibling node must exist because m != k"); int sncount = sn.Leaves().Count(); if (m - k == sncount) { hashNodes.Add(new MerkleProofHash(sn.Hash, MerkleProofHash.Branch.OldRoot)); break; } if (m - k > sncount) { hashNodes.Add(new MerkleProofHash(sn.Hash, MerkleProofHash.Branch.OldRoot)); sn = sn.Parent.RightNode; k += sncount; } else // (m - k < sncount) { sn = sn.LeftNode; } } } // Rule 3: Apply ConsistencyAuditProof below. return(hashNodes); }