code: func readBlockTree(v1BlockIdxBucket database.Bucket) (map[chainhash.Hash]*blockChainContext, error) {
  	blocksMap := make(map[chainhash.Hash]*blockChainContext)
  	err := v1BlockIdxBucket.ForEach(func(_, blockRow []byte) error {
  		var header wire.BlockHeader
  		endOffset := blockHdrOffset + blockHdrSize
  		headerBytes := blockRow[blockHdrOffset:endOffset:endOffset]
  		err := header.Deserialize(bytes.NewReader(headerBytes))
  		if err != nil {
  			return err
  		}
  
  		blockHash := header.BlockHash()
  		prevHash := header.PrevBlock
  
  		if blocksMap[blockHash] == nil {
  			blocksMap[blockHash] = &blockChainContext{height: -1}
  		}
  		if blocksMap[prevHash] == nil {
  			blocksMap[prevHash] = &blockChainContext{height: -1}
  		}
  
  		blocksMap[blockHash].parent = &prevHash
  		blocksMap[prevHash].children =
  			append(blocksMap[prevHash].children, &blockHash)
  		return nil
  	})
  	return blocksMap, err
  }
docs: // readBlockTree reads the old block index bucket and constructs a mapping of
  // each block to its parent block and all child blocks. This mapping represents
  // the full tree of blocks. This function does not populate the height or
  // mainChain fields of the returned blockChainContext values.