mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
eth/downloader: updates to tests
This commit is contained in:
parent
40114c9956
commit
43946c6beb
1 changed files with 43 additions and 24 deletions
|
|
@ -19,6 +19,7 @@ package downloader
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"math/big"
|
||||
"strings"
|
||||
"sync"
|
||||
|
|
@ -238,14 +239,30 @@ func (dl *downloadTester) GetTd(hash common.Hash, number uint64) *big.Int {
|
|||
return dl.ownChainTd[hash]
|
||||
}
|
||||
|
||||
// Checks either dl.ownBlocks or dl.ancientBlocks for presence of the given hash
|
||||
// assumes dl.lock is held
|
||||
func (dl *downloadTester) getHeader(hash common.Hash) (*types.Header, bool) {
|
||||
if h, ok := dl.ownHeaders[hash]; ok {
|
||||
return h, true
|
||||
}
|
||||
h, ok := dl.ancientHeaders[hash]
|
||||
return h, ok
|
||||
}
|
||||
|
||||
func (dl *downloadTester) getTd(hash common.Hash) *big.Int {
|
||||
if td, ok := dl.ownChainTd[hash]; ok {
|
||||
return td
|
||||
}
|
||||
return dl.ancientChainTd[hash]
|
||||
}
|
||||
|
||||
// InsertHeaderChain injects a new batch of headers into the simulated chain.
|
||||
func (dl *downloadTester) InsertHeaderChain(headers []*types.Header, checkFreq int) (i int, err error) {
|
||||
dl.lock.Lock()
|
||||
defer dl.lock.Unlock()
|
||||
|
||||
// Do a quick check, as the blockchain.InsertHeaderChain doesn't insert anything in case of errors
|
||||
if _, ok := dl.ownHeaders[headers[0].ParentHash]; !ok {
|
||||
return 0, errors.New("unknown parent")
|
||||
if _, ok := dl.getHeader(headers[0].ParentHash); !ok {
|
||||
return 0, errors.New("unknown parentx")
|
||||
}
|
||||
for i := 1; i < len(headers); i++ {
|
||||
if headers[i].ParentHash != headers[i-1].Hash() {
|
||||
|
|
@ -254,15 +271,15 @@ func (dl *downloadTester) InsertHeaderChain(headers []*types.Header, checkFreq i
|
|||
}
|
||||
// Do a full insert if pre-checks passed
|
||||
for i, header := range headers {
|
||||
if _, ok := dl.ownHeaders[header.Hash()]; ok {
|
||||
if _, ok := dl.getHeader(header.Hash()); ok {
|
||||
continue
|
||||
}
|
||||
if _, ok := dl.ownHeaders[header.ParentHash]; !ok {
|
||||
if _, ok := dl.getHeader(header.ParentHash); !ok {
|
||||
return i, errors.New("unknown parent")
|
||||
}
|
||||
dl.ownHashes = append(dl.ownHashes, header.Hash())
|
||||
dl.ownHeaders[header.Hash()] = header
|
||||
dl.ownChainTd[header.Hash()] = new(big.Int).Add(dl.ownChainTd[header.ParentHash], header.Difficulty)
|
||||
dl.ownChainTd[header.Hash()] = new(big.Int).Add(dl.getTd(header.ParentHash), header.Difficulty)
|
||||
}
|
||||
return len(headers), nil
|
||||
}
|
||||
|
|
@ -278,14 +295,14 @@ func (dl *downloadTester) InsertChain(blocks types.Blocks) (i int, err error) {
|
|||
} else if _, err := dl.stateDb.Get(parent.Root().Bytes()); err != nil {
|
||||
return i, fmt.Errorf("unknown parent state %x: %v", parent.Root(), err)
|
||||
}
|
||||
if _, ok := dl.ownHeaders[block.Hash()]; !ok {
|
||||
if _, ok := dl.getHeader(block.Hash()); !ok {
|
||||
dl.ownHashes = append(dl.ownHashes, block.Hash())
|
||||
dl.ownHeaders[block.Hash()] = block.Header()
|
||||
}
|
||||
dl.ownBlocks[block.Hash()] = block
|
||||
dl.ownReceipts[block.Hash()] = make(types.Receipts, 0)
|
||||
dl.stateDb.Put(block.Root().Bytes(), []byte{0x00})
|
||||
dl.ownChainTd[block.Hash()] = new(big.Int).Add(dl.ownChainTd[block.ParentHash()], block.Difficulty())
|
||||
dl.ownChainTd[block.Hash()] = new(big.Int).Add(dl.getTd(block.ParentHash()), block.Difficulty())
|
||||
}
|
||||
return len(blocks), nil
|
||||
}
|
||||
|
|
@ -516,7 +533,6 @@ func TestThrottling64Fast(t *testing.T) { testThrottling(t, 64, FastSync) }
|
|||
func testThrottling(t *testing.T, protocol int, mode SyncMode) {
|
||||
t.Parallel()
|
||||
tester := newTester()
|
||||
defer tester.terminate()
|
||||
|
||||
// Create a long block chain to download and the tester
|
||||
targetBlocks := testChainBase.len() - 1
|
||||
|
|
@ -548,31 +564,32 @@ func testThrottling(t *testing.T, protocol int, mode SyncMode) {
|
|||
time.Sleep(25 * time.Millisecond)
|
||||
|
||||
tester.lock.Lock()
|
||||
tester.downloader.queue.lock.Lock()
|
||||
cached = len(tester.downloader.queue.blockDonePool)
|
||||
if mode == FastSync {
|
||||
if receipts := len(tester.downloader.queue.receiptDonePool); receipts < cached {
|
||||
cached = receipts
|
||||
}
|
||||
{
|
||||
tester.downloader.queue.resultCache.lock.Lock()
|
||||
cached = tester.downloader.queue.resultCache.countCompleted()
|
||||
tester.downloader.queue.resultCache.lock.Unlock()
|
||||
frozen = int(atomic.LoadUint32(&blocked))
|
||||
retrieved = len(tester.ownBlocks)
|
||||
|
||||
}
|
||||
frozen = int(atomic.LoadUint32(&blocked))
|
||||
retrieved = len(tester.ownBlocks)
|
||||
tester.downloader.queue.lock.Unlock()
|
||||
tester.lock.Unlock()
|
||||
|
||||
if cached == blockCacheItems || cached == blockCacheItems-reorgProtHeaderDelay || retrieved+cached+frozen == targetBlocks+1 || retrieved+cached+frozen == targetBlocks+1-reorgProtHeaderDelay {
|
||||
if cached == 2*blockCacheItems*3/4 ||
|
||||
cached == blockCacheItems-reorgProtHeaderDelay ||
|
||||
retrieved+cached+frozen == targetBlocks+1 ||
|
||||
retrieved+cached+frozen == targetBlocks+1-reorgProtHeaderDelay {
|
||||
break
|
||||
}
|
||||
}
|
||||
// Make sure we filled up the cache, then exhaust it
|
||||
time.Sleep(25 * time.Millisecond) // give it a chance to screw up
|
||||
|
||||
tester.lock.RLock()
|
||||
retrieved = len(tester.ownBlocks)
|
||||
tester.lock.RUnlock()
|
||||
if cached != blockCacheItems && cached != blockCacheItems-reorgProtHeaderDelay && retrieved+cached+frozen != targetBlocks+1 && retrieved+cached+frozen != targetBlocks+1-reorgProtHeaderDelay {
|
||||
if cached != 2*blockCacheItems*3/4 && cached != blockCacheItems-reorgProtHeaderDelay && retrieved+cached+frozen != targetBlocks+1 && retrieved+cached+frozen != targetBlocks+1-reorgProtHeaderDelay {
|
||||
t.Fatalf("block count mismatch: have %v, want %v (owned %v, blocked %v, target %v)", cached, blockCacheItems, retrieved, frozen, targetBlocks+1)
|
||||
}
|
||||
|
||||
// Permit the blocked blocks to import
|
||||
if atomic.LoadUint32(&blocked) > 0 {
|
||||
atomic.StoreUint32(&blocked, uint32(0))
|
||||
|
|
@ -584,6 +601,8 @@ func testThrottling(t *testing.T, protocol int, mode SyncMode) {
|
|||
if err := <-errc; err != nil {
|
||||
t.Fatalf("block synchronization failed: %v", err)
|
||||
}
|
||||
tester.terminate()
|
||||
|
||||
}
|
||||
|
||||
// Tests that simple synchronization against a forked chain works correctly. In
|
||||
|
|
@ -698,15 +717,12 @@ func TestBoundedHeavyForkedSync64Light(t *testing.T) { testBoundedHeavyForkedSyn
|
|||
|
||||
func testBoundedHeavyForkedSync(t *testing.T, protocol int, mode SyncMode) {
|
||||
t.Parallel()
|
||||
|
||||
tester := newTester()
|
||||
defer tester.terminate()
|
||||
|
||||
// Create a long enough forked chain
|
||||
chainA := testChainForkLightA
|
||||
chainB := testChainForkHeavy
|
||||
tester.newPeer("original", protocol, chainA)
|
||||
tester.newPeer("heavy-rewriter", protocol, chainB)
|
||||
|
||||
// Synchronise with the peer and make sure all blocks were retrieved
|
||||
if err := tester.sync("original", nil, mode); err != nil {
|
||||
|
|
@ -714,10 +730,13 @@ func testBoundedHeavyForkedSync(t *testing.T, protocol int, mode SyncMode) {
|
|||
}
|
||||
assertOwnChain(t, tester, chainA.len())
|
||||
|
||||
tester.newPeer("heavy-rewriter", protocol, chainB)
|
||||
// Synchronise with the second peer and ensure that the fork is rejected to being too old
|
||||
if err := tester.sync("heavy-rewriter", nil, mode); err != errInvalidAncestor {
|
||||
t.Fatalf("sync failure mismatch: have %v, want %v", err, errInvalidAncestor)
|
||||
}
|
||||
fmt.Printf("terminating\n")
|
||||
tester.terminate()
|
||||
}
|
||||
|
||||
// Tests that an inactive downloader will not accept incoming block headers and
|
||||
|
|
|
|||
Loading…
Reference in a new issue