// Execute is the main entry point for the command. It's invoked by the parser. func (cmd *blockRegionCmd) Execute(args []string) error { // Setup the global config options and ensure they are valid. if err := setupGlobalConfig(); err != nil { return err } // Ensure expected arguments. if len(args) < 1 { return errors.New("required block hash parameter not specified") } if len(args) < 2 { return errors.New("required start offset parameter not " + "specified") } if len(args) < 3 { return errors.New("required region length parameter not " + "specified") } // Parse arguments. blockHash, err := wire.NewShaHashFromStr(args[0]) if err != nil { return err } startOffset, err := strconv.ParseUint(args[1], 10, 32) if err != nil { return err } regionLen, err := strconv.ParseUint(args[2], 10, 32) if err != nil { return err } // Load the block database. db, err := loadBlockDB() if err != nil { return err } defer db.Close() return db.View(func(tx database.Tx) error { log.Infof("Fetching block region %s<%d:%d>", blockHash, startOffset, startOffset+regionLen-1) region := database.BlockRegion{ Hash: blockHash, Offset: uint32(startOffset), Len: uint32(regionLen), } startTime := time.Now() regionBytes, err := tx.FetchBlockRegion(®ion) if err != nil { return err } log.Infof("Loaded block region in %v", time.Now().Sub(startTime)) log.Infof("Double SHA256: %s", wire.DoubleSha256SH(regionBytes)) log.Infof("Region Hex: %s", hex.EncodeToString(regionBytes)) return nil }) }
// HashMerkleBranches takes two hashes, treated as the left and right tree // nodes, and returns the hash of their concatenation. This is a helper // function used to aid in the generation of a merkle tree. func HashMerkleBranches(left *wire.ShaHash, right *wire.ShaHash) *wire.ShaHash { // Concatenate the left and right nodes. var sha [wire.HashSize * 2]byte copy(sha[:wire.HashSize], left[:]) copy(sha[wire.HashSize:], right[:]) newSha := wire.DoubleSha256SH(sha[:]) return &newSha }