| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | // 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 storage | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 	"io/ioutil" | 
					
						
							|  |  |  | 	"os" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2018-08-14 16:03:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	ch "github.com/ethereum/go-ethereum/swarm/chunk" | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ( | 
					
						
							|  |  |  | 	hashfunc = MakeHashFunc(DefaultHash) | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // tests that the content address validator correctly checks the data | 
					
						
							| 
									
										
										
										
											2018-10-02 09:32:46 +02:00
										 |  |  | // tests that feed update chunks are passed through content address validator | 
					
						
							| 
									
										
										
										
											2018-09-30 09:43:10 +02:00
										 |  |  | // the test checking the resouce update validator internal correctness is found in storage/feeds/handler_test.go | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | func TestValidator(t *testing.T) { | 
					
						
							|  |  |  | 	// set up localstore | 
					
						
							|  |  |  | 	datadir, err := ioutil.TempDir("", "storage-testvalidator") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer os.RemoveAll(datadir) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	params := NewDefaultLocalStoreParams() | 
					
						
							|  |  |  | 	params.Init(datadir) | 
					
						
							|  |  |  | 	store, err := NewLocalStore(params, nil) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// check puts with no validators, both succeed | 
					
						
							|  |  |  | 	chunks := GenerateRandomChunks(259, 2) | 
					
						
							|  |  |  | 	goodChunk := chunks[0] | 
					
						
							|  |  |  | 	badChunk := chunks[1] | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	copy(badChunk.Data(), goodChunk.Data()) | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	errs := putChunks(store, goodChunk, badChunk) | 
					
						
							|  |  |  | 	if errs[0] != nil { | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 		t.Fatalf("expected no error on good content address chunk in spite of no validation, but got: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	if errs[1] != nil { | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 		t.Fatalf("expected no error on bad content address chunk in spite of no validation, but got: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// add content address validator and check puts | 
					
						
							|  |  |  | 	// bad should fail, good should pass | 
					
						
							|  |  |  | 	store.Validators = append(store.Validators, NewContentAddressValidator(hashfunc)) | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	chunks = GenerateRandomChunks(ch.DefaultSize, 2) | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 	goodChunk = chunks[0] | 
					
						
							|  |  |  | 	badChunk = chunks[1] | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	copy(badChunk.Data(), goodChunk.Data()) | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	errs = putChunks(store, goodChunk, badChunk) | 
					
						
							|  |  |  | 	if errs[0] != nil { | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 		t.Fatalf("expected no error on good content address chunk with content address validator only, but got: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	if errs[1] == nil { | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 		t.Fatal("expected error on bad content address chunk with content address validator only, but got nil") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// append a validator that always denies | 
					
						
							|  |  |  | 	// bad should fail, good should pass, | 
					
						
							|  |  |  | 	var negV boolTestValidator | 
					
						
							|  |  |  | 	store.Validators = append(store.Validators, negV) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	chunks = GenerateRandomChunks(ch.DefaultSize, 2) | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 	goodChunk = chunks[0] | 
					
						
							|  |  |  | 	badChunk = chunks[1] | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	copy(badChunk.Data(), goodChunk.Data()) | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	errs = putChunks(store, goodChunk, badChunk) | 
					
						
							|  |  |  | 	if errs[0] != nil { | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 		t.Fatalf("expected no error on good content address chunk with content address validator only, but got: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	if errs[1] == nil { | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 		t.Fatal("expected error on bad content address chunk with content address validator only, but got nil") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// append a validator that always approves | 
					
						
							|  |  |  | 	// all shall pass | 
					
						
							|  |  |  | 	var posV boolTestValidator = true | 
					
						
							|  |  |  | 	store.Validators = append(store.Validators, posV) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	chunks = GenerateRandomChunks(ch.DefaultSize, 2) | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 	goodChunk = chunks[0] | 
					
						
							|  |  |  | 	badChunk = chunks[1] | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	copy(badChunk.Data(), goodChunk.Data()) | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	errs = putChunks(store, goodChunk, badChunk) | 
					
						
							|  |  |  | 	if errs[0] != nil { | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 		t.Fatalf("expected no error on good content address chunk with content address validator only, but got: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 	if errs[1] != nil { | 
					
						
							|  |  |  | 		t.Fatalf("expected no error on bad content address chunk in spite of no validation, but got: %s", err) | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type boolTestValidator bool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self boolTestValidator) Validate(addr Address, data []byte) bool { | 
					
						
							|  |  |  | 	return bool(self) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-09-13 11:42:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // putChunks adds chunks  to localstore | 
					
						
							|  |  |  | // It waits for receive on the stored channel | 
					
						
							|  |  |  | // It logs but does not fail on delivery error | 
					
						
							|  |  |  | func putChunks(store *LocalStore, chunks ...Chunk) []error { | 
					
						
							|  |  |  | 	i := 0 | 
					
						
							|  |  |  | 	f := func(n int64) Chunk { | 
					
						
							|  |  |  | 		chunk := chunks[i] | 
					
						
							|  |  |  | 		i++ | 
					
						
							|  |  |  | 		return chunk | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	_, errs := put(store, len(chunks), f) | 
					
						
							|  |  |  | 	return errs | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func put(store *LocalStore, n int, f func(i int64) Chunk) (hs []Address, errs []error) { | 
					
						
							|  |  |  | 	for i := int64(0); i < int64(n); i++ { | 
					
						
							|  |  |  | 		chunk := f(ch.DefaultSize) | 
					
						
							|  |  |  | 		err := store.Put(context.TODO(), chunk) | 
					
						
							|  |  |  | 		errs = append(errs, err) | 
					
						
							|  |  |  | 		hs = append(hs, chunk.Address()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return hs, errs | 
					
						
							|  |  |  | } |