aboutsummaryrefslogtreecommitdiffstats
path: root/eth/downloader/downloader_test.go
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2015-05-15 18:14:46 +0800
committerPéter Szilágyi <peterke@gmail.com>2015-05-15 20:01:58 +0800
commit83226762c20dbf48939d76046ad32422a44feda0 (patch)
treedbef36842a0c42a8e9543393eb1b5208aaaf227b /eth/downloader/downloader_test.go
parent9ad515d2dc62c5d1ce1099efa89bd0a0b3f06a67 (diff)
downloadgo-tangerine-83226762c20dbf48939d76046ad32422a44feda0.tar.gz
go-tangerine-83226762c20dbf48939d76046ad32422a44feda0.tar.zst
go-tangerine-83226762c20dbf48939d76046ad32422a44feda0.zip
eth, eth/downloader: detect and handle madeup hash attacks
Diffstat (limited to 'eth/downloader/downloader_test.go')
-rw-r--r--eth/downloader/downloader_test.go45
1 files changed, 39 insertions, 6 deletions
diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go
index 4b8ee93d2..60dcc06cd 100644
--- a/eth/downloader/downloader_test.go
+++ b/eth/downloader/downloader_test.go
@@ -130,8 +130,23 @@ func (dl *downloadTester) getBlock(hash common.Hash) *types.Block {
return dl.blocks[knownHash]
}
-func (dl *downloadTester) getHashes(hash common.Hash) error {
- dl.downloader.DeliverHashes(dl.activePeerId, dl.hashes)
+// getHashes retrieves a batch of hashes for reconstructing the chain.
+func (dl *downloadTester) getHashes(head common.Hash) error {
+ // Gather the next batch of hashes
+ hashes := make([]common.Hash, 0, maxHashFetch)
+ for i, hash := range dl.hashes {
+ if hash == head {
+ for len(hashes) < cap(hashes) && i < len(dl.hashes) {
+ hashes = append(hashes, dl.hashes[i])
+ i++
+ }
+ break
+ }
+ }
+ // Delay delivery a bit to allow attacks to unfold
+ time.Sleep(time.Millisecond)
+
+ dl.downloader.DeliverHashes(dl.activePeerId, hashes)
return nil
}
@@ -166,7 +181,7 @@ func (dl *downloadTester) badBlocksPeer(id string, td *big.Int, hash common.Hash
func TestDownload(t *testing.T) {
minDesiredPeerCount = 4
- blockTtl = 1 * time.Second
+ blockTTL = 1 * time.Second
targetBlocks := 1000
hashes := createHashes(0, targetBlocks)
@@ -215,7 +230,7 @@ func TestMissing(t *testing.T) {
func TestTaking(t *testing.T) {
minDesiredPeerCount = 4
- blockTtl = 1 * time.Second
+ blockTTL = 1 * time.Second
targetBlocks := 1000
hashes := createHashes(0, targetBlocks)
@@ -256,7 +271,7 @@ func TestInactiveDownloader(t *testing.T) {
func TestCancel(t *testing.T) {
minDesiredPeerCount = 4
- blockTtl = 1 * time.Second
+ blockTTL = 1 * time.Second
targetBlocks := 1000
hashes := createHashes(0, targetBlocks)
@@ -282,7 +297,7 @@ func TestCancel(t *testing.T) {
func TestThrottling(t *testing.T) {
minDesiredPeerCount = 4
- blockTtl = 1 * time.Second
+ blockTTL = 1 * time.Second
targetBlocks := 16 * blockCacheLimit
hashes := createHashes(0, targetBlocks)
@@ -429,3 +444,21 @@ func TestInvalidHashOrderAttack(t *testing.T) {
t.Fatalf("failed to synchronise blocks: %v", err)
}
}
+
+// Tests that if a malicious peer makes up a random hash chain and tries to push
+// indefinitely, it actually gets caught with it.
+func TestMadeupHashChainAttack(t *testing.T) {
+ blockTTL = 100 * time.Millisecond
+ crossCheckCycle = 25 * time.Millisecond
+
+ // Create a long chain of hashes without backing blocks
+ hashes := createHashes(0, 1024*blockCacheLimit)
+ hashes = hashes[:len(hashes)-1]
+
+ // Try and sync with the malicious node and check that it fails
+ tester := newTester(t, hashes, nil)
+ tester.newPeer("attack", big.NewInt(10000), hashes[0])
+ if _, err := tester.syncTake("attack", hashes[0]); err != ErrCrossCheckFailed {
+ t.Fatalf("synchronisation error mismatch: have %v, want %v", err, ErrCrossCheckFailed)
+ }
+}