diff --git a/swarm/storage/hasherstore_test.go b/swarm/storage/hasherstore_test.go new file mode 100644 index 0000000000..055e85a11b --- /dev/null +++ b/swarm/storage/hasherstore_test.go @@ -0,0 +1,125 @@ +// 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 . + +package storage + +import ( + "bytes" + "crypto/rand" + "encoding/binary" + "testing" + + "github.com/ethereum/go-ethereum/swarm/storage/encryption" + + "github.com/ethereum/go-ethereum/common" +) + +func TestHasherStore(t *testing.T) { + testHasherStore(10, false, t) + testHasherStore(100, false, t) + testHasherStore(1000, false, t) + testHasherStore(4096, false, t) + testHasherStore(10, true, t) + testHasherStore(100, true, t) + testHasherStore(1000, true, t) + testHasherStore(4096, true, t) +} + +func testHasherStore(chunkLength int, toEncrypt bool, t *testing.T) { + chunkStore := newTestChunkStore() + hasherStore := NewHasherStore(chunkStore, MakeHashFunc(SHA3Hash), toEncrypt) + + // Put two random chunks into the hasherStore + + chunkData1 := generateRandomChunkData(chunkLength) + key1, err := hasherStore.Put(chunkData1) + if err != nil { + t.Fatalf("Expected no error got \"%v\"", err) + } + + chunkData2 := generateRandomChunkData(chunkLength) + key2, err := hasherStore.Put(chunkData2) + if err != nil { + t.Fatalf("Expected no error got \"%v\"", err) + } + + hasherStore.Close() + + // Wait until chunks are really stored + hasherStore.Wait() + + // Get the first chunk + retrievedChunkData1, err := hasherStore.Get(key1) + if err != nil { + t.Fatalf("Expected no error got \"%v\"", err) + } + + // Retrieved data should be same as the original + if !bytes.Equal(chunkData1, retrievedChunkData1) { + t.Fatalf("Expected retrieved chunk data %v got %v", common.Bytes2Hex(chunkData1), common.Bytes2Hex(retrievedChunkData1)) + } + + // Get the second chunk + retrievedChunkData2, err := hasherStore.Get(key2) + if err != nil { + t.Fatalf("Expected no error got \"%v\"", err) + } + + // Retrieved data should be same as the original + if !bytes.Equal(chunkData2, retrievedChunkData2) { + t.Fatalf("Expected retrieved chunk data %v got %v", common.Bytes2Hex(chunkData2), common.Bytes2Hex(retrievedChunkData2)) + } + + hash1, encryptionKey1, err := parseReference(key1) + if err != nil { + t.Fatalf("Expected no error got \"%v\"", err) + } + + if toEncrypt { + if encryptionKey1 == nil { + t.Fatal("Expected non-nil encryption key got nil") + } else if len(encryptionKey1) != encryption.KeyLength { + t.Fatalf("Expected encryption key length %v got %v", encryption.KeyLength, len(encryptionKey1)) + } + } + if !toEncrypt && encryptionKey1 != nil { + t.Fatalf("Expected nil encryption key got key with length %v", len(encryptionKey1)) + } + + // Check if chunk data in store is encrypted or not + chunkInStore, err := chunkStore.Get(hash1) + if err != nil { + t.Fatalf("Expected no error got \"%v\"", err) + } + + chunkDataInStore := chunkInStore.SData + + if toEncrypt && bytes.Equal(chunkData1, chunkDataInStore) { + t.Fatalf("Chunk expected to be encrypted but it is stored without encryption") + } + if !toEncrypt && !bytes.Equal(chunkData1, chunkDataInStore) { + t.Fatalf("Chunk expected to be not encrypted but stored content is different. Expected %v got %v", common.Bytes2Hex(chunkData1), common.Bytes2Hex(chunkDataInStore)) + } + +} + +func generateRandomChunkData(length int) ChunkData { + chunkData := make([]byte, length) + + rand.Read(chunkData) + binary.LittleEndian.PutUint64(chunkData[:8], uint64(len(chunkData)-8)) + return chunkData +}