From 2714e8f091117b4f110198008348bfc19233ed60 Mon Sep 17 00:00:00 2001
From: Javier Peletier <jpeletier@users.noreply.github.com>
Date: Mon, 26 Nov 2018 16:10:22 +0100
Subject: [PATCH] Remove multihash from Swarm bzz:// for Feeds (#18175)

---
 cmd/swarm/swarm-smoke/feed_upload_and_sync.go |   6 +-
 swarm/OWNERS                                  |   1 -
 swarm/api/api.go                              |  25 ++--
 swarm/api/client/client_test.go               | 112 +++++++++++++-----
 swarm/api/http/server_test.go                 | 104 ++++++++++------
 swarm/multihash/multihash.go                  |  92 --------------
 swarm/multihash/multihash_test.go             |  53 ---------
 7 files changed, 167 insertions(+), 226 deletions(-)
 delete mode 100644 swarm/multihash/multihash.go
 delete mode 100644 swarm/multihash/multihash_test.go

diff --git a/cmd/swarm/swarm-smoke/feed_upload_and_sync.go b/cmd/swarm/swarm-smoke/feed_upload_and_sync.go
index 1371d6654..0328d656f 100644
--- a/cmd/swarm/swarm-smoke/feed_upload_and_sync.go
+++ b/cmd/swarm/swarm-smoke/feed_upload_and_sync.go
@@ -16,7 +16,6 @@ import (
 	"github.com/ethereum/go-ethereum/common/hexutil"
 	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/log"
-	"github.com/ethereum/go-ethereum/swarm/multihash"
 	"github.com/ethereum/go-ethereum/swarm/storage/feed"
 	colorable "github.com/mattn/go-colorable"
 	"github.com/pborman/uuid"
@@ -36,7 +35,7 @@ func cliFeedUploadAndSync(c *cli.Context) error {
 
 	generateEndpoints(scheme, cluster, from, to)
 
-	log.Info("generating and uploading MRUs to " + endpoints[0] + " and syncing")
+	log.Info("generating and uploading feeds to " + endpoints[0] + " and syncing")
 
 	// create a random private key to sign updates with and derive the address
 	pkFile, err := ioutil.TempFile("", "swarm-feed-smoke-test")
@@ -218,8 +217,7 @@ func cliFeedUploadAndSync(c *cli.Context) error {
 	if err != nil {
 		return err
 	}
-	multihashHex := hexutil.Encode(multihash.ToMultihash(hashBytes))
-
+	multihashHex := hexutil.Encode(hashBytes)
 	fileHash, err := digest(f)
 	if err != nil {
 		return err
diff --git a/swarm/OWNERS b/swarm/OWNERS
index d4204e08c..4b9ca96eb 100644
--- a/swarm/OWNERS
+++ b/swarm/OWNERS
@@ -7,7 +7,6 @@ swarm
 ├── fuse ────────────────── @jmozah, @holisticode
 ├── grafana_dashboards ──── @nonsense
 ├── metrics ─────────────── @nonsense, @holisticode
-├── multihash ───────────── @nolash
 ├── network ─────────────── ethersphere
 │   ├── bitvector ───────── @zelig, @janos, @gbalint
 │   ├── priorityqueue ───── @zelig, @janos, @gbalint
diff --git a/swarm/api/api.go b/swarm/api/api.go
index 099a46939..33a8e3539 100644
--- a/swarm/api/api.go
+++ b/swarm/api/api.go
@@ -42,7 +42,6 @@ import (
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/metrics"
 	"github.com/ethereum/go-ethereum/swarm/log"
-	"github.com/ethereum/go-ethereum/swarm/multihash"
 	"github.com/ethereum/go-ethereum/swarm/spancontext"
 	"github.com/ethereum/go-ethereum/swarm/storage"
 	"github.com/ethereum/go-ethereum/swarm/storage/feed"
@@ -417,7 +416,7 @@ func (a *API) Get(ctx context.Context, decrypt DecryptFunc, manifestAddr storage
 				return reader, mimeType, status, nil, err
 			}
 			// get the data of the update
-			_, rsrcData, err := a.feed.GetContent(entry.Feed)
+			_, contentAddr, err := a.feed.GetContent(entry.Feed)
 			if err != nil {
 				apiGetNotFound.Inc(1)
 				status = http.StatusNotFound
@@ -425,23 +424,23 @@ func (a *API) Get(ctx context.Context, decrypt DecryptFunc, manifestAddr storage
 				return reader, mimeType, status, nil, err
 			}
 
-			// extract multihash
-			decodedMultihash, err := multihash.FromMultihash(rsrcData)
-			if err != nil {
+			// extract content hash
+			if len(contentAddr) != storage.AddressLength {
 				apiGetInvalid.Inc(1)
 				status = http.StatusUnprocessableEntity
-				log.Warn("invalid multihash in feed update", "err", err)
-				return reader, mimeType, status, nil, err
+				errorMessage := fmt.Sprintf("invalid swarm hash in feed update. Expected %d bytes. Got %d", storage.AddressLength, len(contentAddr))
+				log.Warn(errorMessage)
+				return reader, mimeType, status, nil, errors.New(errorMessage)
 			}
-			manifestAddr = storage.Address(decodedMultihash)
-			log.Trace("feed update contains multihash", "key", manifestAddr)
+			manifestAddr = storage.Address(contentAddr)
+			log.Trace("feed update contains swarm hash", "key", manifestAddr)
 
-			// get the manifest the multihash digest points to
+			// get the manifest the swarm hash points to
 			trie, err := loadManifest(ctx, a.fileStore, manifestAddr, nil, NOOPDecrypt)
 			if err != nil {
 				apiGetNotFound.Inc(1)
 				status = http.StatusNotFound
-				log.Warn(fmt.Sprintf("loadManifestTrie (feed update multihash) error: %v", err))
+				log.Warn(fmt.Sprintf("loadManifestTrie (feed update) error: %v", err))
 				return reader, mimeType, status, nil, err
 			}
 
@@ -451,8 +450,8 @@ func (a *API) Get(ctx context.Context, decrypt DecryptFunc, manifestAddr storage
 			if entry == nil {
 				status = http.StatusNotFound
 				apiGetNotFound.Inc(1)
-				err = fmt.Errorf("manifest (feed update multihash) entry for '%s' not found", path)
-				log.Trace("manifest (feed update multihash) entry not found", "key", manifestAddr, "path", path)
+				err = fmt.Errorf("manifest (feed update) entry for '%s' not found", path)
+				log.Trace("manifest (feed update) entry not found", "key", manifestAddr, "path", path)
 				return reader, mimeType, status, nil, err
 			}
 		}
diff --git a/swarm/api/client/client_test.go b/swarm/api/client/client_test.go
index 76b349397..39f6e4797 100644
--- a/swarm/api/client/client_test.go
+++ b/swarm/api/client/client_test.go
@@ -25,13 +25,13 @@ import (
 	"sort"
 	"testing"
 
+	"github.com/ethereum/go-ethereum/swarm/storage"
 	"github.com/ethereum/go-ethereum/swarm/storage/feed/lookup"
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/swarm/api"
 	swarmhttp "github.com/ethereum/go-ethereum/swarm/api/http"
-	"github.com/ethereum/go-ethereum/swarm/multihash"
 	"github.com/ethereum/go-ethereum/swarm/storage/feed"
 )
 
@@ -368,58 +368,99 @@ func newTestSigner() (*feed.GenericSigner, error) {
 	return feed.NewGenericSigner(privKey), nil
 }
 
-// test the transparent resolving of multihash feed updates with bzz:// scheme
+// Test the transparent resolving of feed updates with bzz:// scheme
 //
-// first upload data, and store the multihash to the resulting manifest in a feed update
-// retrieving the update with the multihash should return the manifest pointing directly to the data
+// First upload data to bzz:, and store the Swarm hash to the resulting manifest in a feed update.
+// This effectively uses a feed to store a pointer to content rather than the content itself
+// Retrieving the update with the Swarm hash should return the manifest pointing directly to the data
 // and raw retrieve of that hash should return the data
-func TestClientCreateFeedMultihash(t *testing.T) {
+func TestClientBzzWithFeed(t *testing.T) {
 
 	signer, _ := newTestSigner()
 
+	// Initialize a Swarm test server
 	srv := swarmhttp.NewTestSwarmServer(t, serverFunc, nil)
-	client := NewClient(srv.URL)
+	swarmClient := NewClient(srv.URL)
 	defer srv.Close()
 
-	// add the data our multihash aliased manifest will point to
-	databytes := []byte("bar")
-
-	swarmHash, err := client.UploadRaw(bytes.NewReader(databytes), int64(len(databytes)), false)
+	// put together some data for our test:
+	dataBytes := []byte(`
+	//
+	// Create some data our manifest will point to. Data that could be very big and wouldn't fit in a feed update.
+	// So what we are going to do is upload it to Swarm bzz:// and obtain a **manifest hash** pointing to it:
+	//
+	// MANIFEST HASH --> DATA
+	//
+	// Then, we store that **manifest hash** into a Swarm Feed update. Once we have done this,
+	// we can use the **feed manifest hash** in bzz:// instead, this way: bzz://feed-manifest-hash.
+	//
+	// FEED MANIFEST HASH --> MANIFEST HASH --> DATA
+	//
+	// Given that we can update the feed at any time with a new **manifest hash** but the **feed manifest hash**
+	// stays constant, we have effectively created a fixed address to changing content. (Applause)
+	//
+	// FEED MANIFEST HASH (the same) --> MANIFEST HASH(2) --> DATA(2)
+	//
+	`)
+
+	// Create a virtual File out of memory containing the above data
+	f := &File{
+		ReadCloser: ioutil.NopCloser(bytes.NewReader(dataBytes)),
+		ManifestEntry: api.ManifestEntry{
+			ContentType: "text/plain",
+			Mode:        0660,
+			Size:        int64(len(dataBytes)),
+		},
+	}
+
+	// upload data to bzz:// and retrieve the content-addressed manifest hash, hex-encoded.
+	manifestAddressHex, err := swarmClient.Upload(f, "", false)
 	if err != nil {
-		t.Fatalf("Error uploading raw test data: %s", err)
+		t.Fatalf("Error creating manifest: %s", err)
 	}
 
-	s := common.FromHex(swarmHash)
-	mh := multihash.ToMultihash(s)
+	// convert the hex-encoded manifest hash to a 32-byte slice
+	manifestAddress := common.FromHex(manifestAddressHex)
+
+	if len(manifestAddress) != storage.AddressLength {
+		t.Fatalf("Something went wrong. Got a hash of an unexpected length. Expected %d bytes. Got %d", storage.AddressLength, len(manifestAddress))
+	}
 
-	// our feed topic
-	topic, _ := feed.NewTopic("foo.eth", nil)
+	// Now create a **feed manifest**. For that, we need a topic:
+	topic, _ := feed.NewTopic("interesting topic indeed", nil)
 
-	createRequest := feed.NewFirstRequest(topic)
+	// Build a feed request to update data
+	request := feed.NewFirstRequest(topic)
 
-	createRequest.SetData(mh)
-	if err := createRequest.Sign(signer); err != nil {
+	// Put the 32-byte address of the manifest into the feed update
+	request.SetData(manifestAddress)
+
+	// Sign the update
+	if err := request.Sign(signer); err != nil {
 		t.Fatalf("Error signing update: %s", err)
 	}
 
-	feedManifestHash, err := client.CreateFeedWithManifest(createRequest)
-
+	// Publish the update and at the same time request a **feed manifest** to be created
+	feedManifestAddressHex, err := swarmClient.CreateFeedWithManifest(request)
 	if err != nil {
 		t.Fatalf("Error creating feed manifest: %s", err)
 	}
 
-	correctManifestAddrHex := "bb056a5264c295c2b0f613c8409b9c87ce9d71576ace02458160df4cc894210b"
-	if feedManifestHash != correctManifestAddrHex {
-		t.Fatalf("Response feed manifest mismatch, expected '%s', got '%s'", correctManifestAddrHex, feedManifestHash)
+	// Check we have received the exact **feed manifest** to be expected
+	// given the topic and user signing the updates:
+	correctFeedManifestAddrHex := "747c402e5b9dc715a25a4393147512167bab018a007fad7cdcd9adc7fce1ced2"
+	if feedManifestAddressHex != correctFeedManifestAddrHex {
+		t.Fatalf("Response feed manifest mismatch, expected '%s', got '%s'", correctFeedManifestAddrHex, feedManifestAddressHex)
 	}
 
 	// Check we get a not found error when trying to get feed updates with a made-up manifest
-	_, err = client.QueryFeed(nil, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
+	_, err = swarmClient.QueryFeed(nil, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
 	if err != ErrNoFeedUpdatesFound {
 		t.Fatalf("Expected to receive ErrNoFeedUpdatesFound error. Got: %s", err)
 	}
 
-	reader, err := client.QueryFeed(nil, correctManifestAddrHex)
+	// If we query the feed directly we should get **manifest hash** back:
+	reader, err := swarmClient.QueryFeed(nil, correctFeedManifestAddrHex)
 	if err != nil {
 		t.Fatalf("Error retrieving feed updates: %s", err)
 	}
@@ -428,10 +469,27 @@ func TestClientCreateFeedMultihash(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	if !bytes.Equal(mh, gotData) {
-		t.Fatalf("Expected: %v, got %v", mh, gotData)
+
+	//Check that indeed the **manifest hash** is retrieved
+	if !bytes.Equal(manifestAddress, gotData) {
+		t.Fatalf("Expected: %v, got %v", manifestAddress, gotData)
+	}
+
+	// Now the final test we were looking for: Use bzz://<feed-manifest> and that should resolve all manifests
+	// and return the original data directly:
+	f, err = swarmClient.Download(feedManifestAddressHex, "")
+	if err != nil {
+		t.Fatal(err)
+	}
+	gotData, err = ioutil.ReadAll(f)
+	if err != nil {
+		t.Fatal(err)
 	}
 
+	// Check that we get back the original data:
+	if !bytes.Equal(dataBytes, gotData) {
+		t.Fatalf("Expected: %v, got %v", manifestAddress, gotData)
+	}
 }
 
 // TestClientCreateUpdateFeed will check that feeds can be created and updated via the HTTP client.
diff --git a/swarm/api/http/server_test.go b/swarm/api/http/server_test.go
index 1ef3deece..e82762ce0 100644
--- a/swarm/api/http/server_test.go
+++ b/swarm/api/http/server_test.go
@@ -45,7 +45,6 @@ import (
 	"github.com/ethereum/go-ethereum/log"
 	"github.com/ethereum/go-ethereum/swarm/api"
 	swarm "github.com/ethereum/go-ethereum/swarm/api/client"
-	"github.com/ethereum/go-ethereum/swarm/multihash"
 	"github.com/ethereum/go-ethereum/swarm/storage"
 	"github.com/ethereum/go-ethereum/swarm/storage/feed"
 	"github.com/ethereum/go-ethereum/swarm/testutil"
@@ -69,60 +68,91 @@ func newTestSigner() (*feed.GenericSigner, error) {
 	return feed.NewGenericSigner(privKey), nil
 }
 
-// test the transparent resolving of multihash-containing feed updates with bzz:// scheme
+// Test the transparent resolving of feed updates with bzz:// scheme
 //
-// first upload data, and store the multihash to the resulting manifest in a feed update
-// retrieving the update with the multihash should return the manifest pointing directly to the data
+// First upload data to bzz:, and store the Swarm hash to the resulting manifest in a feed update.
+// This effectively uses a feed to store a pointer to content rather than the content itself
+// Retrieving the update with the Swarm hash should return the manifest pointing directly to the data
 // and raw retrieve of that hash should return the data
-func TestBzzFeedMultihash(t *testing.T) {
+func TestBzzWithFeed(t *testing.T) {
 
 	signer, _ := newTestSigner()
 
+	// Initialize Swarm test server
 	srv := NewTestSwarmServer(t, serverFunc, nil)
 	defer srv.Close()
 
-	// add the data our multihash aliased manifest will point to
-	databytes := "bar"
-	testBzzUrl := fmt.Sprintf("%s/bzz:/", srv.URL)
-	resp, err := http.Post(testBzzUrl, "text/plain", bytes.NewReader([]byte(databytes)))
+	// put together some data for our test:
+	dataBytes := []byte(`
+	//
+	// Create some data our manifest will point to. Data that could be very big and wouldn't fit in a feed update.
+	// So what we are going to do is upload it to Swarm bzz:// and obtain a **manifest hash** pointing to it:
+	//
+	// MANIFEST HASH --> DATA
+	//
+	// Then, we store that **manifest hash** into a Swarm Feed update. Once we have done this,
+	// we can use the **feed manifest hash** in bzz:// instead, this way: bzz://feed-manifest-hash.
+	//
+	// FEED MANIFEST HASH --> MANIFEST HASH --> DATA
+	//
+	// Given that we can update the feed at any time with a new **manifest hash** but the **feed manifest hash**
+	// stays constant, we have effectively created a fixed address to changing content. (Applause)
+	//
+	// FEED MANIFEST HASH (the same) --> MANIFEST HASH(2) --> DATA(2) ...
+	//
+	`)
+
+	// POST data to bzz and get back a content-addressed **manifest hash** pointing to it.
+	resp, err := http.Post(fmt.Sprintf("%s/bzz:/", srv.URL), "text/plain", bytes.NewReader([]byte(dataBytes)))
 	if err != nil {
 		t.Fatal(err)
 	}
+
 	defer resp.Body.Close()
 	if resp.StatusCode != http.StatusOK {
 		t.Fatalf("err %s", resp.Status)
 	}
-	b, err := ioutil.ReadAll(resp.Body)
+	manifestAddressHex, err := ioutil.ReadAll(resp.Body)
 
 	if err != nil {
 		t.Fatal(err)
 	}
-	s := common.FromHex(string(b))
-	mh := multihash.ToMultihash(s)
 
-	log.Info("added data", "manifest", string(b), "data", common.ToHex(mh))
+	manifestAddress := common.FromHex(string(manifestAddressHex))
 
-	topic, _ := feed.NewTopic("foo.eth", nil)
+	log.Info("added data", "manifest", string(manifestAddressHex))
+
+	// At this point we have uploaded the data and have a manifest pointing to it
+	// Now store that manifest address in a feed update.
+	// We also want a feed manifest, so we can use it to refer to the feed.
+
+	// First, create a topic for our feed:
+	topic, _ := feed.NewTopic("interesting topic indeed", nil)
+
+	// Create a feed update request:
 	updateRequest := feed.NewFirstRequest(topic)
 
-	updateRequest.SetData(mh)
+	// Store the **manifest address** as data into the feed update.
+	updateRequest.SetData(manifestAddress)
 
+	// Sign the update
 	if err := updateRequest.Sign(signer); err != nil {
 		t.Fatal(err)
 	}
-	log.Info("added data", "manifest", string(b), "data", common.ToHex(mh))
+	log.Info("added data", "data", common.ToHex(manifestAddress))
 
-	testUrl, err := url.Parse(fmt.Sprintf("%s/bzz-feed:/", srv.URL))
+	// Build the feed update http request:
+	feedUpdateURL, err := url.Parse(fmt.Sprintf("%s/bzz-feed:/", srv.URL))
 	if err != nil {
 		t.Fatal(err)
 	}
-	query := testUrl.Query()
+	query := feedUpdateURL.Query()
 	body := updateRequest.AppendValues(query) // this adds all query parameters and returns the data to be posted
-	query.Set("manifest", "1")                // indicate we want a manifest back
-	testUrl.RawQuery = query.Encode()
+	query.Set("manifest", "1")                // indicate we want a feed manifest back
+	feedUpdateURL.RawQuery = query.Encode()
 
-	// create the multihash update
-	resp, err = http.Post(testUrl.String(), "application/octet-stream", bytes.NewReader(body))
+	// submit the feed update request to Swarm
+	resp, err = http.Post(feedUpdateURL.String(), "application/octet-stream", bytes.NewReader(body))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -130,24 +160,25 @@ func TestBzzFeedMultihash(t *testing.T) {
 	if resp.StatusCode != http.StatusOK {
 		t.Fatalf("err %s", resp.Status)
 	}
-	b, err = ioutil.ReadAll(resp.Body)
+
+	feedManifestAddressHex, err := ioutil.ReadAll(resp.Body)
 	if err != nil {
 		t.Fatal(err)
 	}
-	rsrcResp := &storage.Address{}
-	err = json.Unmarshal(b, rsrcResp)
+	feedManifestAddress := &storage.Address{}
+	err = json.Unmarshal(feedManifestAddressHex, feedManifestAddress)
 	if err != nil {
-		t.Fatalf("data %s could not be unmarshaled: %v", b, err)
+		t.Fatalf("data %s could not be unmarshaled: %v", feedManifestAddressHex, err)
 	}
 
-	correctManifestAddrHex := "bb056a5264c295c2b0f613c8409b9c87ce9d71576ace02458160df4cc894210b"
-	if rsrcResp.Hex() != correctManifestAddrHex {
-		t.Fatalf("Response feed manifest address mismatch, expected '%s', got '%s'", correctManifestAddrHex, rsrcResp.Hex())
+	correctManifestAddrHex := "747c402e5b9dc715a25a4393147512167bab018a007fad7cdcd9adc7fce1ced2"
+	if feedManifestAddress.Hex() != correctManifestAddrHex {
+		t.Fatalf("Response feed manifest address mismatch, expected '%s', got '%s'", correctManifestAddrHex, feedManifestAddress.Hex())
 	}
 
 	// get bzz manifest transparent feed update resolve
-	testBzzUrl = fmt.Sprintf("%s/bzz:/%s", srv.URL, rsrcResp)
-	resp, err = http.Get(testBzzUrl)
+	getBzzURL := fmt.Sprintf("%s/bzz:/%s", srv.URL, feedManifestAddress)
+	resp, err = http.Get(getBzzURL)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -155,12 +186,12 @@ func TestBzzFeedMultihash(t *testing.T) {
 	if resp.StatusCode != http.StatusOK {
 		t.Fatalf("err %s", resp.Status)
 	}
-	b, err = ioutil.ReadAll(resp.Body)
+	retrievedData, err := ioutil.ReadAll(resp.Body)
 	if err != nil {
 		t.Fatal(err)
 	}
-	if !bytes.Equal(b, []byte(databytes)) {
-		t.Fatalf("retrieved data mismatch, expected %x, got %x", databytes, b)
+	if !bytes.Equal(retrievedData, []byte(dataBytes)) {
+		t.Fatalf("retrieved data mismatch, expected %x, got %x", dataBytes, retrievedData)
 	}
 }
 
@@ -245,7 +276,8 @@ func TestBzzFeed(t *testing.T) {
 		t.Fatalf("Expected manifest Feed '%s', got '%s'", correctFeedHex, manifest.Entries[0].Feed.Hex())
 	}
 
-	// get bzz manifest transparent feed update resolve
+	// take the chance to have bzz: crash on resolving a feed update that does not contain
+	// a swarm hash:
 	testBzzUrl := fmt.Sprintf("%s/bzz:/%s", srv.URL, rsrcResp)
 	resp, err = http.Get(testBzzUrl)
 	if err != nil {
@@ -253,7 +285,7 @@ func TestBzzFeed(t *testing.T) {
 	}
 	defer resp.Body.Close()
 	if resp.StatusCode == http.StatusOK {
-		t.Fatal("Expected error status since feed update does not contain multihash. Received 200 OK")
+		t.Fatal("Expected error status since feed update does not contain a Swarm hash. Received 200 OK")
 	}
 	_, err = ioutil.ReadAll(resp.Body)
 	if err != nil {
diff --git a/swarm/multihash/multihash.go b/swarm/multihash/multihash.go
deleted file mode 100644
index 3306e3a6d..000000000
--- a/swarm/multihash/multihash.go
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2018 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library 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 Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package multihash
-
-import (
-	"bytes"
-	"encoding/binary"
-	"errors"
-	"fmt"
-)
-
-const (
-	defaultMultihashLength   = 32
-	defaultMultihashTypeCode = 0x1b
-)
-
-var (
-	multihashTypeCode uint8
-	MultihashLength   = defaultMultihashLength
-)
-
-func init() {
-	multihashTypeCode = defaultMultihashTypeCode
-	MultihashLength = defaultMultihashLength
-}
-
-// check if valid swarm multihash
-func isSwarmMultihashType(code uint8) bool {
-	return code == multihashTypeCode
-}
-
-// GetMultihashLength returns the digest length of the provided multihash
-// It will fail if the multihash is not a valid swarm mulithash
-func GetMultihashLength(data []byte) (int, int, error) {
-	cursor := 0
-	typ, c := binary.Uvarint(data)
-	if c <= 0 {
-		return 0, 0, errors.New("unreadable hashtype field")
-	}
-	if !isSwarmMultihashType(uint8(typ)) {
-		return 0, 0, fmt.Errorf("hash code %x is not a swarm hashtype", typ)
-	}
-	cursor += c
-	hashlength, c := binary.Uvarint(data[cursor:])
-	if c <= 0 {
-		return 0, 0, errors.New("unreadable length field")
-	}
-	cursor += c
-
-	// we cheekily assume hashlength < maxint
-	inthashlength := int(hashlength)
-	if len(data[c:]) < inthashlength {
-		return 0, 0, errors.New("length mismatch")
-	}
-	return inthashlength, cursor, nil
-}
-
-// FromMulithash returns the digest portion of the multihash
-// It will fail if the multihash is not a valid swarm multihash
-func FromMultihash(data []byte) ([]byte, error) {
-	hashLength, _, err := GetMultihashLength(data)
-	if err != nil {
-		return nil, err
-	}
-	return data[len(data)-hashLength:], nil
-}
-
-// ToMulithash wraps the provided digest data with a swarm mulithash header
-func ToMultihash(hashData []byte) []byte {
-	buf := bytes.NewBuffer(nil)
-	b := make([]byte, 8)
-	c := binary.PutUvarint(b, uint64(multihashTypeCode))
-	buf.Write(b[:c])
-	c = binary.PutUvarint(b, uint64(len(hashData)))
-	buf.Write(b[:c])
-	buf.Write(hashData)
-	return buf.Bytes()
-}
diff --git a/swarm/multihash/multihash_test.go b/swarm/multihash/multihash_test.go
deleted file mode 100644
index 85df741dd..000000000
--- a/swarm/multihash/multihash_test.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2018 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library 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 Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package multihash
-
-import (
-	"bytes"
-	"math/rand"
-	"testing"
-)
-
-// parse multihash, and check that invalid multihashes fail
-func TestCheckMultihash(t *testing.T) {
-	hashbytes := make([]byte, 32)
-	c, err := rand.Read(hashbytes)
-	if err != nil {
-		t.Fatal(err)
-	} else if c < 32 {
-		t.Fatal("short read")
-	}
-
-	expected := ToMultihash(hashbytes)
-
-	l, hl, _ := GetMultihashLength(expected)
-	if l != 32 {
-		t.Fatalf("expected length %d, got %d", 32, l)
-	} else if hl != 2 {
-		t.Fatalf("expected header length %d, got %d", 2, hl)
-	}
-	if _, _, err := GetMultihashLength(expected[1:]); err == nil {
-		t.Fatal("expected failure on corrupt header")
-	}
-	if _, _, err := GetMultihashLength(expected[:len(expected)-2]); err == nil {
-		t.Fatal("expected failure on short content")
-	}
-	dh, _ := FromMultihash(expected)
-	if !bytes.Equal(dh, hashbytes) {
-		t.Fatalf("expected content hash %x, got %x", hashbytes, dh)
-	}
-}
-- 
GitLab