(t *testing.T, threads int)
| 93 | } |
| 94 | |
| 95 | func testHeaderConcurrentVerification(t *testing.T, threads int) { |
| 96 | // Create a simple chain to verify |
| 97 | var ( |
| 98 | testdb = database.NewMemDatabase() |
| 99 | ) |
| 100 | |
| 101 | genesis := DefaultGenesisBlock() |
| 102 | genesisBlock := genesis.MustCommit(testdb) |
| 103 | |
| 104 | remoteDB := database.NewIpfsDbWithAdapter(database.NewFakeIpfsAdapter()) |
| 105 | |
| 106 | config := configs.ChainConfigInfo().Dpor |
| 107 | d := dpor.NewDoNothingFaker(config, testdb) |
| 108 | |
| 109 | blocks, _ := GenerateChain(genesis.Config, genesisBlock, d, testdb, remoteDB, 8, nil) |
| 110 | |
| 111 | headers := make([]*types.Header, len(blocks)) |
| 112 | seals := make([]bool, len(blocks)) |
| 113 | |
| 114 | for i, block := range blocks { |
| 115 | headers[i] = block.Header() |
| 116 | seals[i] = true |
| 117 | } |
| 118 | // Set the number of threads to verify on |
| 119 | old := runtime.GOMAXPROCS(threads) |
| 120 | defer runtime.GOMAXPROCS(old) |
| 121 | |
| 122 | // Run the header checker for the entire block chain at once both for a valid and |
| 123 | // also an invalid chain (enough if one arbitrary block is invalid). |
| 124 | for i, valid := range []bool{true, false} { |
| 125 | var results <-chan error |
| 126 | |
| 127 | if valid { |
| 128 | engine := dpor.NewDoNothingFaker(config, testdb) |
| 129 | chain, _ := NewBlockChain(testdb, nil, genesis.Config, engine, vm.Config{}, remoteDB, nil) |
| 130 | _, results = chain.engine.VerifyHeaders(chain, headers, seals, headers) |
| 131 | chain.Stop() |
| 132 | } else { |
| 133 | engine := dpor.NewFakeFailer(config, testdb, uint64(len(headers)-1)) |
| 134 | chain, _ := NewBlockChain(testdb, nil, genesis.Config, engine, vm.Config{}, remoteDB, nil) |
| 135 | _, results = chain.engine.VerifyHeaders(chain, headers, seals, headers) |
| 136 | chain.Stop() |
| 137 | } |
| 138 | // Wait for all the verification results |
| 139 | checks := make(map[int]error) |
| 140 | for j := 0; j < len(blocks); j++ { |
| 141 | select { |
| 142 | case result := <-results: |
| 143 | checks[j] = result |
| 144 | |
| 145 | case <-time.After(time.Second): |
| 146 | t.Fatalf("test %d.%d: verification timeout", i, j) |
| 147 | } |
| 148 | } |
| 149 | // Check nonce check validity |
| 150 | for j := 0; j < len(blocks); j++ { |
| 151 | want := valid || (j < len(blocks)-2) // We chose the last-but-one nonce in the chain to fail |
| 152 | if (checks[j] == nil) != want { |
no test coverage detected