From 7f55b0cbd8618a1b0de8d7e37d2b0143ebae4abf Mon Sep 17 00:00:00 2001
From: holisticode <holistic.computing@gmail.com>
Date: Thu, 7 Feb 2019 07:51:24 -0500
Subject: [PATCH] cmd/swarm: hashes command (#19008)

---
 cmd/swarm/explore.go            | 59 +++++++++++++++++++++++++++++++++
 cmd/swarm/main.go               |  2 ++
 swarm/storage/filestore.go      |  6 ++--
 swarm/storage/filestore_test.go | 18 ++++------
 4 files changed, 71 insertions(+), 14 deletions(-)
 create mode 100644 cmd/swarm/explore.go

diff --git a/cmd/swarm/explore.go b/cmd/swarm/explore.go
new file mode 100644
index 000000000..5b5b8bf41
--- /dev/null
+++ b/cmd/swarm/explore.go
@@ -0,0 +1,59 @@
+// Copyright 2019 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
+// Command bzzhash computes a swarm tree hash.
+package main
+
+import (
+	"context"
+	"fmt"
+	"os"
+
+	"github.com/ethereum/go-ethereum/cmd/utils"
+	"github.com/ethereum/go-ethereum/swarm/storage"
+	"gopkg.in/urfave/cli.v1"
+)
+
+var hashesCommand = cli.Command{
+	Action:             hashes,
+	CustomHelpTemplate: helpTemplate,
+	Name:               "hashes",
+	Usage:              "print all hashes of a file to STDOUT",
+	ArgsUsage:          "<file>",
+	Description:        "Prints all hashes of a file to STDOUT",
+}
+
+func hashes(ctx *cli.Context) {
+	args := ctx.Args()
+	if len(args) < 1 {
+		utils.Fatalf("Usage: swarm hashes <file name>")
+	}
+	f, err := os.Open(args[0])
+	if err != nil {
+		utils.Fatalf("Error opening file " + args[1])
+	}
+	defer f.Close()
+
+	fileStore := storage.NewFileStore(&storage.FakeChunkStore{}, storage.NewFileStoreParams())
+	refs, err := fileStore.GetAllReferences(context.TODO(), f, false)
+	if err != nil {
+		utils.Fatalf("%v\n", err)
+	} else {
+		for _, r := range refs {
+			fmt.Println(r.String())
+		}
+	}
+}
diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go
index 11b51124d..839227b2b 100644
--- a/cmd/swarm/main.go
+++ b/cmd/swarm/main.go
@@ -142,6 +142,8 @@ func init() {
 		dbCommand,
 		// See config.go
 		DumpConfigCommand,
+		// hashesCommand
+		hashesCommand,
 	}
 
 	// append a hidden help subcommand to all commands that have subcommands
diff --git a/swarm/storage/filestore.go b/swarm/storage/filestore.go
index aebe03c1e..4240f5b1c 100644
--- a/swarm/storage/filestore.go
+++ b/swarm/storage/filestore.go
@@ -75,7 +75,7 @@ func NewFileStore(store ChunkStore, params *FileStoreParams) *FileStore {
 	}
 }
 
-// Public API. Main entry point for document retrieval directly. Used by the
+// Retrieve is a public API. Main entry point for document retrieval directly. Used by the
 // FS-aware API and httpaccess
 // Chunk retrieval blocks on netStore requests with a timeout so reader will
 // report error if retrieval of chunks within requested range time out.
@@ -87,7 +87,7 @@ func (f *FileStore) Retrieve(ctx context.Context, addr Address) (reader *LazyChu
 	return
 }
 
-// Public API. Main entry point for document storage directly. Used by the
+// Store is a public API. Main entry point for document storage directly. Used by the
 // FS-aware API and httpaccess
 func (f *FileStore) Store(ctx context.Context, data io.Reader, size int64, toEncrypt bool) (addr Address, wait func(context.Context) error, err error) {
 	putter := NewHasherStore(f.ChunkStore, f.hashFunc, toEncrypt)
@@ -98,7 +98,7 @@ func (f *FileStore) HashSize() int {
 	return f.hashFunc().Size()
 }
 
-// Public API. This endpoint returns all chunk hashes (only) for a given file
+// GetAllReferences is a public API. This endpoint returns all chunk hashes (only) for a given file
 func (f *FileStore) GetAllReferences(ctx context.Context, data io.Reader, toEncrypt bool) (addrs AddressCollection, err error) {
 	// create a special kind of putter, which only will store the references
 	putter := &HashExplorer{
diff --git a/swarm/storage/filestore_test.go b/swarm/storage/filestore_test.go
index 2dbccdf11..06c4be1d7 100644
--- a/swarm/storage/filestore_test.go
+++ b/swarm/storage/filestore_test.go
@@ -190,22 +190,18 @@ func TestGetAllReferences(t *testing.T) {
 	}
 	fileStore := NewFileStore(localStore, NewFileStoreParams())
 
-	checkRefs := func(dataSize int, expectedLen int) {
-		slice := testutil.RandomBytes(1, dataSize)
+	// testRuns[i] and expectedLen[i] are dataSize and expected length respectively
+	testRuns := []int{1024, 8192, 16000, 30000, 1000000}
+	expectedLens := []int{1, 3, 5, 9, 248}
+	for i, r := range testRuns {
+		slice := testutil.RandomBytes(1, r)
 
 		addrs, err := fileStore.GetAllReferences(context.Background(), bytes.NewReader(slice), false)
 		if err != nil {
 			t.Fatal(err)
 		}
-		if len(addrs) != expectedLen {
-			t.Fatalf("Expected reference array length to be %d, but is %d", expectedLen, len(addrs))
+		if len(addrs) != expectedLens[i] {
+			t.Fatalf("Expected reference array length to be %d, but is %d", expectedLens[i], len(addrs))
 		}
 	}
-
-	// testRuns[i] and expectedLen[i] are dataSize and expected length respectively
-	testRuns := []int{1024, 8192, 16000, 30000, 1000000}
-	expectedLens := []int{1, 3, 5, 9, 248}
-	for i, r := range testRuns {
-		checkRefs(r, expectedLens[i])
-	}
 }
-- 
GitLab