(chain []*types.Header, checkFreq int)
| 192 | type WhCallback func(*types.Header) error |
| 193 | |
| 194 | func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int) (int, error) { |
| 195 | // Do a sanity check that the provided chain is actually ordered and linked |
| 196 | for i := 1; i < len(chain); i++ { |
| 197 | if chain[i].Number.Uint64() != chain[i-1].Number.Uint64()+1 || chain[i].ParentHash != chain[i-1].Hash() { |
| 198 | // Chain broke ancestry, log a messge (programming error) and skip insertion |
| 199 | log.Error("Non contiguous header insert", "number", chain[i].Number, "hash", chain[i].Hash(), |
| 200 | "parent", chain[i].ParentHash, "prevnumber", chain[i-1].Number, "prevhash", chain[i-1].Hash()) |
| 201 | |
| 202 | return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, chain[i-1].Number, |
| 203 | chain[i-1].Hash().Bytes()[:4], i, chain[i].Number, chain[i].Hash().Bytes()[:4], chain[i].ParentHash[:4]) |
| 204 | } |
| 205 | } |
| 206 | |
| 207 | // Generate the list of seal verification requests, and start the parallel verifier |
| 208 | seals := make([]bool, len(chain)) |
| 209 | for i := 0; i < len(seals)/checkFreq; i++ { |
| 210 | index := i*checkFreq + hc.rand.Intn(checkFreq) |
| 211 | if index >= len(seals) { |
| 212 | index = len(seals) - 1 |
| 213 | } |
| 214 | seals[index] = true |
| 215 | } |
| 216 | seals[len(seals)-1] = true // Last should always be verified to avoid junk |
| 217 | |
| 218 | abort, results := hc.engine.VerifyHeaders(hc, chain, seals, chain) |
| 219 | defer close(abort) |
| 220 | |
| 221 | // Iterate over the headers and ensure they all check out |
| 222 | for i, header := range chain { |
| 223 | // If the chain is terminating, stop processing blocks |
| 224 | if hc.procInterrupt() { |
| 225 | log.Debug("Premature abort during headers verification") |
| 226 | return 0, errors.New("aborted") |
| 227 | } |
| 228 | // If the header is a banned one, straight out abort |
| 229 | if BadHashes[header.Hash()] { |
| 230 | return i, ErrBlacklistedHash |
| 231 | } |
| 232 | // Otherwise wait for headers checks and ensure they pass |
| 233 | if err := <-results; err != nil { |
| 234 | return i, err |
| 235 | } |
| 236 | } |
| 237 | |
| 238 | return 0, nil |
| 239 | } |
| 240 | |
| 241 | // ValidateBlockBody validates transactions in a block based on known states |
| 242 | func (hc *HeaderChain) ValidateBlockBody(block *types.Block) error { |
no test coverage detected