github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/core/block_validator_test.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package core
    18  
    19  // Tests that simple header verification works, for both good and bad blocks.
    20  //func TestHeaderVerification(t *testing.T) {
    21  //	// Create a simple chain to verify
    22  //	var (
    23  //		testdb, _ = rawdb.NewMemoryDatabase()
    24  //		gspec     = &Genesis{Config: params.TestChainConfig}
    25  //		genesis   = gspec.MustCommit(testdb)
    26  //		blocks, _ = GenerateChain(params.TestChainConfig, genesis, ipbft.NewFaker(), testdb, 8, nil)
    27  //	)
    28  //	headers := make([]*types.Header, len(blocks))
    29  //	for i, block := range blocks {
    30  //		headers[i] = block.Header()
    31  //	}
    32  //	// Run the header checker for blocks one-by-one, checking for both valid and invalid nonces
    33  //	chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, nil, vm.Config{}, nil)
    34  //	defer chain.Stop()
    35  //
    36  //	for i := 0; i < len(blocks); i++ {
    37  //		for j, valid := range []bool{true, false} {
    38  //			var results <-chan error
    39  //
    40  //			if valid {
    41  //				engine := nil
    42  //				_, results = engine.VerifyHeaders(chain, []*types.Header{headers[i]}, []bool{true})
    43  //			} else {
    44  //				engine := ethash.NewFakeFailer(headers[i].Number.Uint64())
    45  //				_, results = engine.VerifyHeaders(chain, []*types.Header{headers[i]}, []bool{true})
    46  //			}
    47  //			// Wait for the verification result
    48  //			select {
    49  //			case result := <-results:
    50  //				if (result == nil) != valid {
    51  //					t.Errorf("test %d.%d: validity mismatch: have %v, want %v", i, j, result, valid)
    52  //				}
    53  //			case <-time.After(time.Second):
    54  //				t.Fatalf("test %d.%d: verification timeout", i, j)
    55  //			}
    56  //			// Make sure no more data is returned
    57  //			select {
    58  //			case result := <-results:
    59  //				t.Fatalf("test %d.%d: unexpected result returned: %v", i, j, result)
    60  //			case <-time.After(25 * time.Millisecond):
    61  //			}
    62  //		}
    63  //		chain.InsertChain(blocks[i : i+1])
    64  //	}
    65  //}
    66  
    67  // Tests that concurrent header verification works, for both good and bad blocks.
    68  //func TestHeaderConcurrentVerification2(t *testing.T)  { testHeaderConcurrentVerification(t, 2) }
    69  //func TestHeaderConcurrentVerification8(t *testing.T)  { testHeaderConcurrentVerification(t, 8) }
    70  //func TestHeaderConcurrentVerification32(t *testing.T) { testHeaderConcurrentVerification(t, 32) }
    71  
    72  //func testHeaderConcurrentVerification(t *testing.T, threads int) {
    73  //	// Create a simple chain to verify
    74  //	var (
    75  //		testdb, _ = rawdb.NewMemoryDatabase()
    76  //		gspec     = &Genesis{Config: params.TestChainConfig}
    77  //		genesis   = gspec.MustCommit(testdb)
    78  //		blocks, _ = GenerateChain(params.TestChainConfig, genesis, nil, testdb, 8, nil)
    79  //	)
    80  //	headers := make([]*types.Header, len(blocks))
    81  //	seals := make([]bool, len(blocks))
    82  //
    83  //	for i, block := range blocks {
    84  //		headers[i] = block.Header()
    85  //		seals[i] = true
    86  //	}
    87  //	// Set the number of threads to verify on
    88  //	old := runtime.GOMAXPROCS(threads)
    89  //	defer runtime.GOMAXPROCS(old)
    90  //
    91  //	// Run the header checker for the entire block chain at once both for a valid and
    92  //	// also an invalid chain (enough if one arbitrary block is invalid).
    93  //	for i, valid := range []bool{true, false} {
    94  //		var results <-chan error
    95  //
    96  //		if valid {
    97  //			chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, nil, vm.Config{}, nil)
    98  //			_, results = chain.engine.VerifyHeaders(chain, headers, seals)
    99  //			chain.Stop()
   100  //		} else {
   101  //			chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFakeFailer(uint64(len(headers)-1)), vm.Config{}, nil)
   102  //			_, results = chain.engine.VerifyHeaders(chain, headers, seals)
   103  //			chain.Stop()
   104  //		}
   105  //		// Wait for all the verification results
   106  //		checks := make(map[int]error)
   107  //		for j := 0; j < len(blocks); j++ {
   108  //			select {
   109  //			case result := <-results:
   110  //				checks[j] = result
   111  //
   112  //			case <-time.After(time.Second):
   113  //				t.Fatalf("test %d.%d: verification timeout", i, j)
   114  //			}
   115  //		}
   116  //		// Check nonce check validity
   117  //		for j := 0; j < len(blocks); j++ {
   118  //			want := valid || (j < len(blocks)-2) // We chose the last-but-one nonce in the chain to fail
   119  //			if (checks[j] == nil) != want {
   120  //				t.Errorf("test %d.%d: validity mismatch: have %v, want %v", i, j, checks[j], want)
   121  //			}
   122  //			if !want {
   123  //				// A few blocks after the first error may pass verification due to concurrent
   124  //				// workers. We don't care about those in this test, just that the correct block
   125  //				// errors out.
   126  //				break
   127  //			}
   128  //		}
   129  //		// Make sure no more data is returned
   130  //		select {
   131  //		case result := <-results:
   132  //			t.Fatalf("test %d: unexpected result returned: %v", i, result)
   133  //		case <-time.After(25 * time.Millisecond):
   134  //		}
   135  //	}
   136  //}
   137  
   138  // Tests that aborting a header validation indeed prevents further checks from being
   139  // run, as well as checks that no left-over goroutines are leaked.
   140  //func TestHeaderConcurrentAbortion2(t *testing.T)  { testHeaderConcurrentAbortion(t, 2) }
   141  //func TestHeaderConcurrentAbortion8(t *testing.T)  { testHeaderConcurrentAbortion(t, 8) }
   142  //func TestHeaderConcurrentAbortion32(t *testing.T) { testHeaderConcurrentAbortion(t, 32) }
   143  
   144  //func testHeaderConcurrentAbortion(t *testing.T, threads int) {
   145  //	// Create a simple chain to verify
   146  //	var (
   147  //		testdb, _ = rawdb.NewMemoryDatabase()
   148  //		gspec     = &Genesis{Config: params.TestChainConfig}
   149  //		genesis   = gspec.MustCommit(testdb)
   150  //		blocks, _ = GenerateChain(params.TestChainConfig, genesis, nil, testdb, 1024, nil)
   151  //	)
   152  //	headers := make([]*types.Header, len(blocks))
   153  //	seals := make([]bool, len(blocks))
   154  //
   155  //	for i, block := range blocks {
   156  //		headers[i] = block.Header()
   157  //		seals[i] = true
   158  //	}
   159  //	// Set the number of threads to verify on
   160  //	old := runtime.GOMAXPROCS(threads)
   161  //	defer runtime.GOMAXPROCS(old)
   162  //
   163  //	// Start the verifications and immediately abort
   164  //	chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFakeDelayer(time.Millisecond), vm.Config{}, nil)
   165  //	defer chain.Stop()
   166  //
   167  //	abort, results := chain.engine.VerifyHeaders(chain, headers, seals)
   168  //	close(abort)
   169  //
   170  //	// Deplete the results channel
   171  //	verified := 0
   172  //	for depleted := false; !depleted; {
   173  //		select {
   174  //		case result := <-results:
   175  //			if result != nil {
   176  //				t.Errorf("header %d: validation failed: %v", verified, result)
   177  //			}
   178  //			verified++
   179  //		case <-time.After(50 * time.Millisecond):
   180  //			depleted = true
   181  //		}
   182  //	}
   183  //	// Check that abortion was honored by not processing too many POWs
   184  //	if verified > 2*threads {
   185  //		t.Errorf("verification count too large: have %d, want below %d", verified, 2*threads)
   186  //	}
   187  //}