func (h *Hasher) writeFinalNode(level int, n *node, isLeft bool, s []byte) {
	var err error
	for {
		// at the root of the bmt just write the result to the result channel
		if n == nil {
			if s != nil {
				h.result <- s
			}
			return
		}
		var noHash bool
		if isLeft {
			// coming from left sister branch
			// when the final section's path is going via left child node
			// we include an all-zero subtree hash for the right level and toggle the node.
			n.right = h.zerohashes[level]
			if s != nil {
				n.left = s
				// if a left final node carries a hash, it must be the first (and only thread)
				// so the toggle is already in passive state no need no call
				// yet thread needs to carry on pushing hash to parent
				noHash = false
			} else {
				// if again first thread then propagate nil and calculate no hash
				noHash = n.toggle()
			}
		} else {
			// right sister branch
			if s != nil {
				// if hash was pushed from right child node, write right segment change state
				n.right = s
				// if toggle is true, we arrived first so no hashing just push nil to parent
				noHash = n.toggle()
			} else {
				// if s is nil, then thread arrived first at previous node and here there will be two,
				// so no need to do anything and keep s = nil for parent
				noHash = true
			}
		}
		// the child-thread first arriving will just continue resetting s to nil
		// the second thread now can be sure both left and right children are written
		// it calculates the hash of left|right and pushes it to the parent
		if noHash {
			s = nil
		} else {
			s, err = doHash(n.hasher, n.left, n.right)
			if err != nil {
				select {
				case h.errc <- err:
				default:
				}
				return
			}
		}
		// iterate to parent
		isLeft = n.isLeft
		n = n.parent
		level++
	}
}
// writeFinalNode is following the path starting from the final datasegment to the
// BMT root via parents.
// For unbalanced trees it fills in the missing right sister nodes using
// the pool's lookup table for BMT subtree root hashes for all-zero sections.
// Otherwise behaves like `writeNode`.
writeFinalNode is following the path starting from the final datasegment to the
BMT root via parents.
For unbalanced trees it fills in the missing right sister nodes using
the pool's lookup table for BMT subtree root hashes for all-zero sections.
Otherwise behaves like `writeNode`.
// writeFinalNode is following the path starting from the final datasegment to the // BMT root via parents . // For unbalanced trees it fills in the missing right sister nodes using // the pool ' s lookup table for BMT subtree root hashes for all - zero sections . // Otherwise behaves like ` writeNode ` .
func (h *Hasher) writeFinalNode(level int, n *node, isLeft bool, s []byte) {
	var err error
	for {
		if n == nil {
			if s != nil {
				h.result <- s
			}
			return
		}
		var noHash bool
		if isLeft {
			n.right = h.zerohashes[level]
			if s != nil {
				n.left = s
				noHash = false
			} else {
				noHash = n.toggle()
			}
		} else {
			if s != nil {
				n.right = s
				noHash = n.toggle()
			} else {
				noHash = true
			}
		}
		if noHash {
			s = nil
		} else {
			s, err = doHash(n.hasher, n.left, n.right)
			if err != nil {
				select {
				case h.errc <- err:
				default:
				}
				return
			}
		}
		isLeft = n.isLeft
		n = n.parent
		level++
	}
}
func ( h * Hasher ) writeFinalNode ( level int , n * node , isLeft bool , s [ ] byte ) { var err error for { if n == nil { if s != nil { h . result <- s } return } var noHash bool if isLeft { n . right = h . zerohashes [ level ] if s != nil { n . left = s noHash = false } else { noHash = n . toggle ( ) } } else { if s != nil { n . right = s noHash = n . toggle ( ) } else { noHash = true } } if noHash { s = nil } else { s , err = doHash ( n . hasher , n . left , n . right ) if err != nil { select { case h . errc <- err : default : } return } } isLeft = n . isLeft n = n . parent level ++ } }
writeFinalNode is following the path starting from the final datasegment to the
BMT root via parents.
writeFinalNode is following the path starting from the final datasegment to the BMT root via parents .
// at the root of the bmt just write the result to the result channel // coming from left sister branch // when the final section's path is going via left child node // we include an all-zero subtree hash for the right level and toggle the node. // if a left final node carries a hash, it must be the first (and only thread) // so the toggle is already in passive state no need no call // yet thread needs to carry on pushing hash to parent // if again first thread then propagate nil and calculate no hash // right sister branch // if hash was pushed from right child node, write right segment change state // if toggle is true, we arrived first so no hashing just push nil to parent // if s is nil, then thread arrived first at previous node and here there will be two, // so no need to do anything and keep s = nil for parent // the child-thread first arriving will just continue resetting s to nil // the second thread now can be sure both left and right children are written // it calculates the hash of left|right and pushes it to the parent // iterate to parent