blockchain.go 40.0 KB
Newer Older
F
Felix Lange 已提交
1
// Copyright 2014 The go-ethereum Authors
2
// This file is part of the go-ethereum library.
F
Felix Lange 已提交
3
//
4
// The go-ethereum library is free software: you can redistribute it and/or modify
F
Felix Lange 已提交
5 6 7 8
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
9
// The go-ethereum library is distributed in the hope that it will be useful,
F
Felix Lange 已提交
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
F
Felix Lange 已提交
12 13 14
// GNU Lesser General Public License for more details.
//
// 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/>.
F
Felix Lange 已提交
16

17
// Package core implements the Ethereum consensus protocol.
O
obscuren 已提交
18
package core
O
obscuren 已提交
19 20

import (
21
	"errors"
O
obscuren 已提交
22
	"fmt"
23
	"io"
24
	"math/big"
25
	mrand "math/rand"
26
	"runtime"
O
obscuren 已提交
27
	"sync"
O
obscuren 已提交
28
	"sync/atomic"
29
	"time"
30

O
obscuren 已提交
31
	"github.com/ethereum/go-ethereum/common"
O
obscuren 已提交
32
	"github.com/ethereum/go-ethereum/core/state"
O
obscuren 已提交
33
	"github.com/ethereum/go-ethereum/core/types"
34
	"github.com/ethereum/go-ethereum/core/vm"
35
	"github.com/ethereum/go-ethereum/crypto"
36
	"github.com/ethereum/go-ethereum/ethdb"
O
obscuren 已提交
37
	"github.com/ethereum/go-ethereum/event"
O
obscuren 已提交
38
	"github.com/ethereum/go-ethereum/logger"
O
obscuren 已提交
39
	"github.com/ethereum/go-ethereum/logger/glog"
40
	"github.com/ethereum/go-ethereum/metrics"
41
	"github.com/ethereum/go-ethereum/pow"
42
	"github.com/ethereum/go-ethereum/rlp"
43
	"github.com/ethereum/go-ethereum/trie"
O
obscuren 已提交
44
	"github.com/hashicorp/golang-lru"
O
obscuren 已提交
45 46
)

47 48 49
var (
	chainlogger = logger.NewLogger("CHAIN")
	jsonlogger  = logger.NewJsonLogger()
50

51
	blockInsertTimer = metrics.NewTimer("chain/inserts")
52 53

	ErrNoGenesis = errors.New("Genesis not found in chain")
54
)
Z
zelig 已提交
55

O
obscuren 已提交
56
const (
57
	headerCacheLimit    = 512
58
	bodyCacheLimit      = 256
59
	tdCacheLimit        = 1024
O
obscuren 已提交
60
	blockCacheLimit     = 256
O
wip  
obscuren 已提交
61 62
	maxFutureBlocks     = 256
	maxTimeFutureBlocks = 30
63 64 65
	// must be bumped when consensus algorithm is changed, this forces the upgradedb
	// command to be run (forces the blocks to be imported again using the new algorithm)
	BlockChainVersion = 3
O
obscuren 已提交
66
)
67

68 69 70 71 72 73 74 75 76 77 78 79 80 81
// BlockChain represents the canonical chain given a database with a genesis
// block. The Blockchain manages chain imports, reverts, chain reorganisations.
//
// Importing blocks in to the block chain happens according to the set of rules
// defined by the two stage Validator. Processing of blocks is done using the
// Processor which processes the included transaction. The validation of the state
// is done in the second part of the Validator. Failing results in aborting of
// the import.
//
// The BlockChain also helps in returning blocks from **any** chain included
// in the database as well as blocks that represents the canonical chain. It's
// important to note that GetBlock can return any block and does not need to be
// included in the canonical one where as GetBlockByNumber always represents the
// canonical chain.
82
type BlockChain struct {
83 84
	config *ChainConfig // chain & network configuration

85
	hc           *HeaderChain
86
	chainDb      ethdb.Database
O
obscuren 已提交
87
	eventMux     *event.TypeMux
88
	genesisBlock *types.Block
89

90 91 92
	mu      sync.RWMutex // global mutex for locking chain operations
	chainmu sync.RWMutex // blockchain insertion lock
	procmu  sync.RWMutex // block processor lock
93

94 95 96
	checkpoint       int          // checkpoint counts towards the new checkpoint
	currentBlock     *types.Block // Current head of the block chain
	currentFastBlock *types.Block // Current head of the fast-sync chain (may be above the block chain!)
O
obscuren 已提交
97

98 99 100
	bodyCache    *lru.Cache // Cache for the most recent block bodies
	bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format
	blockCache   *lru.Cache // Cache for the most recent entire blocks
101
	futureBlocks *lru.Cache // future blocks are blocks added for later processing
102

103
	quit    chan struct{} // blockchain quit channel
L
Leif Jurvetson 已提交
104
	running int32         // running must be called atomically
O
obscuren 已提交
105
	// procInterrupt must be atomically called
106 107
	procInterrupt int32          // interrupt signaler for block processing
	wg            sync.WaitGroup // chain processing wait group for shutting down
108

109
	pow       pow.PoW
110 111
	processor Processor // block processor interface
	validator Validator // block and state validator interface
O
obscuren 已提交
112
}
O
obscuren 已提交
113

114 115 116
// NewBlockChain returns a fully initialised block chain using information
// available in the database. It initialiser the default Ethereum Validator and
// Processor.
117
func NewBlockChain(chainDb ethdb.Database, config *ChainConfig, pow pow.PoW, mux *event.TypeMux) (*BlockChain, error) {
118 119 120 121 122
	bodyCache, _ := lru.New(bodyCacheLimit)
	bodyRLPCache, _ := lru.New(bodyCacheLimit)
	blockCache, _ := lru.New(blockCacheLimit)
	futureBlocks, _ := lru.New(maxFutureBlocks)

123
	bc := &BlockChain{
124
		config:       config,
125 126 127 128 129 130 131 132
		chainDb:      chainDb,
		eventMux:     mux,
		quit:         make(chan struct{}),
		bodyCache:    bodyCache,
		bodyRLPCache: bodyRLPCache,
		blockCache:   blockCache,
		futureBlocks: futureBlocks,
		pow:          pow,
O
obscuren 已提交
133
	}
134 135
	bc.SetValidator(NewBlockValidator(config, bc, pow))
	bc.SetProcessor(NewStateProcessor(config, bc))
136 137 138

	gv := func() HeaderValidator { return bc.Validator() }
	var err error
139
	bc.hc, err = NewHeaderChain(chainDb, config, gv, bc.getProcInterrupt)
140 141 142
	if err != nil {
		return nil, err
	}
143 144 145

	bc.genesisBlock = bc.GetBlockByNumber(0)
	if bc.genesisBlock == nil {
146
		return nil, ErrNoGenesis
147
	}
148

149
	if err := bc.loadLastState(); err != nil {
150
		return nil, err
O
obscuren 已提交
151
	}
152
	// Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain
153
	for hash, _ := range BadHashes {
154 155 156 157
		if header := bc.GetHeader(hash); header != nil {
			glog.V(logger.Error).Infof("Found bad hash, rewinding chain to block #%d [%x…]", header.Number, header.ParentHash[:4])
			bc.SetHead(header.Number.Uint64() - 1)
			glog.V(logger.Error).Infoln("Chain rewind was successful, resuming normal operation")
158 159
		}
	}
160
	// Take ownership of this particular state
161
	go bc.update()
O
obscuren 已提交
162
	return bc, nil
163 164
}

165 166 167 168
func (self *BlockChain) getProcInterrupt() bool {
	return atomic.LoadInt32(&self.procInterrupt) == 1
}

169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
// loadLastState loads the last known chain state from the database. This method
// assumes that the chain manager mutex is held.
func (self *BlockChain) loadLastState() error {
	// Restore the last known head block
	head := GetHeadBlockHash(self.chainDb)
	if head == (common.Hash{}) {
		// Corrupt or empty database, init from scratch
		self.Reset()
	} else {
		if block := self.GetBlock(head); block != nil {
			// Block found, set as the current head
			self.currentBlock = block
		} else {
			// Corrupt or empty database, init from scratch
			self.Reset()
		}
	}
	// Restore the last known head header
187
	currentHeader := self.currentBlock.Header()
188 189
	if head := GetHeadHeaderHash(self.chainDb); head != (common.Hash{}) {
		if header := self.GetHeader(head); header != nil {
190
			currentHeader = header
191 192
		}
	}
193
	self.hc.SetCurrentHeader(currentHeader)
194 195 196 197 198 199 200
	// Restore the last known head fast block
	self.currentFastBlock = self.currentBlock
	if head := GetHeadFastBlockHash(self.chainDb); head != (common.Hash{}) {
		if block := self.GetBlock(head); block != nil {
			self.currentFastBlock = block
		}
	}
201
	// Issue a status log and return
202
	headerTd := self.GetTd(self.hc.CurrentHeader().Hash())
203
	blockTd := self.GetTd(self.currentBlock.Hash())
204
	fastTd := self.GetTd(self.currentFastBlock.Hash())
205

206
	glog.V(logger.Info).Infof("Last header: #%d [%x…] TD=%v", self.hc.CurrentHeader().Number, self.hc.CurrentHeader().Hash().Bytes()[:4], headerTd)
207
	glog.V(logger.Info).Infof("Last block: #%d [%x…] TD=%v", self.currentBlock.Number(), self.currentBlock.Hash().Bytes()[:4], blockTd)
208
	glog.V(logger.Info).Infof("Fast block: #%d [%x…] TD=%v", self.currentFastBlock.Number(), self.currentFastBlock.Hash().Bytes()[:4], fastTd)
209 210 211 212

	return nil
}

213 214 215 216
// SetHead rewinds the local chain to a new head. In the case of headers, everything
// above the new head will be deleted and the new one set. In the case of blocks
// though, the head may be further rewound if block bodies are missing (non-archive
// nodes after a fast sync).
217
func (bc *BlockChain) SetHead(head uint64) {
218 219 220
	bc.mu.Lock()
	defer bc.mu.Unlock()

221
	delFn := func(hash common.Hash) {
222 223
		DeleteBody(bc.chainDb, hash)
	}
224 225
	bc.hc.SetHead(head, delFn)

226
	// Clear out any stale content from the caches
227 228 229 230
	bc.bodyCache.Purge()
	bc.bodyRLPCache.Purge()
	bc.blockCache.Purge()
	bc.futureBlocks.Purge()
231

232
	// Update all computed fields to the new head
233 234 235 236 237 238 239
	if bc.currentBlock != nil && bc.hc.CurrentHeader().Number.Uint64() < bc.currentBlock.NumberU64() {
		bc.currentBlock = bc.GetBlock(bc.hc.CurrentHeader().Hash())
	}
	if bc.currentFastBlock != nil && bc.hc.CurrentHeader().Number.Uint64() < bc.currentFastBlock.NumberU64() {
		bc.currentFastBlock = bc.GetBlock(bc.hc.CurrentHeader().Hash())
	}

240 241 242
	if bc.currentBlock == nil {
		bc.currentBlock = bc.genesisBlock
	}
243 244 245
	if bc.currentFastBlock == nil {
		bc.currentFastBlock = bc.genesisBlock
	}
246

247 248 249 250 251 252
	if err := WriteHeadBlockHash(bc.chainDb, bc.currentBlock.Hash()); err != nil {
		glog.Fatalf("failed to reset head block hash: %v", err)
	}
	if err := WriteHeadFastBlockHash(bc.chainDb, bc.currentFastBlock.Hash()); err != nil {
		glog.Fatalf("failed to reset head fast block hash: %v", err)
	}
253
	bc.loadLastState()
254 255
}

256 257 258
// FastSyncCommitHead sets the current head block to the one defined by the hash
// irrelevant what the chain contents were prior.
func (self *BlockChain) FastSyncCommitHead(hash common.Hash) error {
259
	// Make sure that both the block as well at its state trie exists
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
	block := self.GetBlock(hash)
	if block == nil {
		return fmt.Errorf("non existent block [%x…]", hash[:4])
	}
	if _, err := trie.NewSecure(block.Root(), self.chainDb); err != nil {
		return err
	}
	// If all checks out, manually set the head block
	self.mu.Lock()
	self.currentBlock = block
	self.mu.Unlock()

	glog.V(logger.Info).Infof("committed block #%d [%x…] as new head", block.Number(), hash[:4])
	return nil
}

276
// GasLimit returns the gas limit of the current HEAD block.
277
func (self *BlockChain) GasLimit() *big.Int {
O
obscuren 已提交
278 279
	self.mu.RLock()
	defer self.mu.RUnlock()
O
obscuren 已提交
280

281
	return self.currentBlock.GasLimit()
O
obscuren 已提交
282 283
}

284
// LastBlockHash return the hash of the HEAD block.
285
func (self *BlockChain) LastBlockHash() common.Hash {
286 287 288
	self.mu.RLock()
	defer self.mu.RUnlock()

289
	return self.currentBlock.Hash()
290 291
}

292
// CurrentBlock retrieves the current head block of the canonical chain. The
293
// block is retrieved from the blockchain's internal cache.
294
func (self *BlockChain) CurrentBlock() *types.Block {
O
obscuren 已提交
295 296 297 298
	self.mu.RLock()
	defer self.mu.RUnlock()

	return self.currentBlock
O
obscuren 已提交
299 300
}

301
// CurrentFastBlock retrieves the current fast-sync head block of the canonical
302
// chain. The block is retrieved from the blockchain's internal cache.
303 304 305 306 307 308 309
func (self *BlockChain) CurrentFastBlock() *types.Block {
	self.mu.RLock()
	defer self.mu.RUnlock()

	return self.currentFastBlock
}

310 311
// Status returns status information about the current chain such as the HEAD Td,
// the HEAD hash and the hash of the genesis block.
312
func (self *BlockChain) Status() (td *big.Int, currentBlock common.Hash, genesisBlock common.Hash) {
O
obscuren 已提交
313 314 315
	self.mu.RLock()
	defer self.mu.RUnlock()

316
	return self.GetTd(self.currentBlock.Hash()), self.currentBlock.Hash(), self.genesisBlock.Hash()
317 318
}

319 320 321 322 323 324 325 326 327 328 329 330
// SetProcessor sets the processor required for making state modifications.
func (self *BlockChain) SetProcessor(processor Processor) {
	self.procmu.Lock()
	defer self.procmu.Unlock()
	self.processor = processor
}

// SetValidator sets the validator which is used to validate incoming blocks.
func (self *BlockChain) SetValidator(validator Validator) {
	self.procmu.Lock()
	defer self.procmu.Unlock()
	self.validator = validator
331 332
}

333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
// Validator returns the current validator.
func (self *BlockChain) Validator() Validator {
	self.procmu.RLock()
	defer self.procmu.RUnlock()
	return self.validator
}

// Processor returns the current processor.
func (self *BlockChain) Processor() Processor {
	self.procmu.RLock()
	defer self.procmu.RUnlock()
	return self.processor
}

// AuxValidator returns the auxiliary validator (Proof of work atm)
func (self *BlockChain) AuxValidator() pow.PoW { return self.pow }

// State returns a new mutable state based on the current HEAD block.
351
func (self *BlockChain) State() (*state.StateDB, error) {
352
	return state.New(self.CurrentBlock().Root(), self.chainDb)
O
obscuren 已提交
353 354
}

355
// Reset purges the entire blockchain, restoring it to its genesis state.
356
func (bc *BlockChain) Reset() {
357
	bc.ResetWithGenesisBlock(bc.genesisBlock)
358 359
}

360 361
// ResetWithGenesisBlock purges the entire blockchain, restoring it to the
// specified genesis state.
362
func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) {
363 364 365
	// Dump the entire block chain and purge the caches
	bc.SetHead(0)

366 367 368
	bc.mu.Lock()
	defer bc.mu.Unlock()

369
	// Prepare the genesis block and reinitialise the chain
370
	if err := bc.hc.WriteTd(genesis.Hash(), genesis.Difficulty()); err != nil {
371 372 373
		glog.Fatalf("failed to write genesis block TD: %v", err)
	}
	if err := WriteBlock(bc.chainDb, genesis); err != nil {
374
		glog.Fatalf("failed to write genesis block: %v", err)
375
	}
376
	bc.genesisBlock = genesis
377 378
	bc.insert(bc.genesisBlock)
	bc.currentBlock = bc.genesisBlock
379 380
	bc.hc.SetGenesis(bc.genesisBlock.Header())
	bc.hc.SetCurrentHeader(bc.genesisBlock.Header())
381
	bc.currentFastBlock = bc.genesisBlock
382 383
}

384
// Export writes the active chain to the given writer.
385
func (self *BlockChain) Export(w io.Writer) error {
386
	if err := self.ExportN(w, uint64(0), self.currentBlock.NumberU64()); err != nil {
T
Taylor Gerring 已提交
387 388 389 390 391 392
		return err
	}
	return nil
}

// ExportN writes a subset of the active chain to the given writer.
393
func (self *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error {
O
obscuren 已提交
394 395
	self.mu.RLock()
	defer self.mu.RUnlock()
O
obscuren 已提交
396

T
Taylor Gerring 已提交
397 398 399 400
	if first > last {
		return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last)
	}

T
Cleanup  
Taylor Gerring 已提交
401
	glog.V(logger.Info).Infof("exporting %d blocks...\n", last-first+1)
402

T
Taylor Gerring 已提交
403
	for nr := first; nr <= last; nr++ {
404 405 406 407 408 409
		block := self.GetBlockByNumber(nr)
		if block == nil {
			return fmt.Errorf("export failed on #%d: not found", nr)
		}

		if err := block.EncodeRLP(w); err != nil {
410 411
			return err
		}
O
obscuren 已提交
412
	}
413

414
	return nil
O
obscuren 已提交
415 416
}

417 418
// insert injects a new head block into the current block chain. This method
// assumes that the block is indeed a true head. It will also reset the head
419 420
// header and the head fast sync block to this very same block if they are older
// or if they are on a different side chain.
421 422
//
// Note, this function assumes that the `mu` mutex is held!
423
func (bc *BlockChain) insert(block *types.Block) {
424 425 426
	// If the block is on a side chain or an unknown one, force other heads onto it too
	updateHeads := GetCanonicalHash(bc.chainDb, block.NumberU64()) != block.Hash()

427 428 429
	// Add the block to the canonical chain number scheme and mark as the head
	if err := WriteCanonicalHash(bc.chainDb, block.Hash(), block.NumberU64()); err != nil {
		glog.Fatalf("failed to insert block number: %v", err)
430
	}
431
	if err := WriteHeadBlockHash(bc.chainDb, block.Hash()); err != nil {
432
		glog.Fatalf("failed to insert head block hash: %v", err)
433
	}
434
	bc.currentBlock = block
435 436 437

	// If the block is better than out head or is on a different chain, force update heads
	if updateHeads {
438
		bc.hc.SetCurrentHeader(block.Header())
439 440 441 442 443 444

		if err := WriteHeadFastBlockHash(bc.chainDb, block.Hash()); err != nil {
			glog.Fatalf("failed to insert head fast block hash: %v", err)
		}
		bc.currentFastBlock = block
	}
445 446
}

O
obscuren 已提交
447
// Accessors
448
func (bc *BlockChain) Genesis() *types.Block {
O
obscuren 已提交
449 450 451
	return bc.genesisBlock
}

452 453
// GetBody retrieves a block body (transactions and uncles) from the database by
// hash, caching it if found.
454
func (self *BlockChain) GetBody(hash common.Hash) *types.Body {
455 456
	// Short circuit if the body's already in the cache, retrieve otherwise
	if cached, ok := self.bodyCache.Get(hash); ok {
457 458
		body := cached.(*types.Body)
		return body
O
obscuren 已提交
459
	}
460 461 462
	body := GetBody(self.chainDb, hash)
	if body == nil {
		return nil
463 464
	}
	// Cache the found body for next time and return
465 466
	self.bodyCache.Add(hash, body)
	return body
467
}
O
obscuren 已提交
468

469 470
// GetBodyRLP retrieves a block body in RLP encoding from the database by hash,
// caching it if found.
471
func (self *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
472 473
	// Short circuit if the body's already in the cache, retrieve otherwise
	if cached, ok := self.bodyRLPCache.Get(hash); ok {
474
		return cached.(rlp.RawValue)
475
	}
476 477
	body := GetBodyRLP(self.chainDb, hash)
	if len(body) == 0 {
478
		return nil
O
obscuren 已提交
479
	}
480 481 482 483
	// Cache the found body for next time and return
	self.bodyRLPCache.Add(hash, body)
	return body
}
O
obscuren 已提交
484

485 486
// HasBlock checks if a block is fully present in the database or not, caching
// it if present.
487
func (bc *BlockChain) HasBlock(hash common.Hash) bool {
488
	return bc.GetBlock(hash) != nil
O
obscuren 已提交
489 490
}

491 492 493 494 495 496 497 498 499 500 501 502 503
// HasBlockAndState checks if a block and associated state trie is fully present
// in the database or not, caching it if present.
func (bc *BlockChain) HasBlockAndState(hash common.Hash) bool {
	// Check first that the block itself is known
	block := bc.GetBlock(hash)
	if block == nil {
		return false
	}
	// Ensure the associated state is also present
	_, err := state.New(block.Root(), bc.chainDb)
	return err == nil
}

504
// GetBlock retrieves a block from the database by hash, caching it if found.
505
func (self *BlockChain) GetBlock(hash common.Hash) *types.Block {
506 507
	// Short circuit if the block's already in the cache, retrieve otherwise
	if block, ok := self.blockCache.Get(hash); ok {
508 509
		return block.(*types.Block)
	}
510
	block := GetBlock(self.chainDb, hash)
511
	if block == nil {
O
obscuren 已提交
512 513
		return nil
	}
514 515 516
	// Cache the found block for next time and return
	self.blockCache.Add(block.Hash(), block)
	return block
O
obscuren 已提交
517 518
}

519 520
// GetBlockByNumber retrieves a block from the database by number, caching it
// (associated with its hash) if found.
521
func (self *BlockChain) GetBlockByNumber(number uint64) *types.Block {
522
	hash := GetCanonicalHash(self.chainDb, number)
523 524 525 526 527
	if hash == (common.Hash{}) {
		return nil
	}
	return self.GetBlock(hash)
}
528

529
// [deprecated by eth/62]
F
Felix Lange 已提交
530
// GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
531
func (self *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
F
Felix Lange 已提交
532 533 534 535 536 537 538 539 540 541 542
	for i := 0; i < n; i++ {
		block := self.GetBlock(hash)
		if block == nil {
			break
		}
		blocks = append(blocks, block)
		hash = block.ParentHash()
	}
	return
}

543 544 545 546
// GetUnclesInChain retrieves all the uncles from a given block backwards until
// a specific distance is reached.
func (self *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header {
	uncles := []*types.Header{}
547 548 549 550
	for i := 0; block != nil && i < length; i++ {
		uncles = append(uncles, block.Uncles()...)
		block = self.GetBlock(block.ParentHash())
	}
551
	return uncles
O
obscuren 已提交
552
}
O
obscuren 已提交
553

554 555
// Stop stops the blockchain service. If any imports are currently in progress
// it will abort them using the procInterrupt.
556
func (bc *BlockChain) Stop() {
557 558 559
	if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) {
		return
	}
560
	close(bc.quit)
O
obscuren 已提交
561
	atomic.StoreInt32(&bc.procInterrupt, 1)
562 563 564 565

	bc.wg.Wait()

	glog.V(logger.Info).Infoln("Chain manager stopped")
566 567
}

568
func (self *BlockChain) procFutureBlocks() {
569 570 571 572 573
	blocks := make([]*types.Block, 0, self.futureBlocks.Len())
	for _, hash := range self.futureBlocks.Keys() {
		if block, exist := self.futureBlocks.Get(hash); exist {
			blocks = append(blocks, block.(*types.Block))
		}
574
	}
575 576 577 578
	if len(blocks) > 0 {
		types.BlockBy(types.Number).Sort(blocks)
		self.InsertChain(blocks)
	}
579 580
}

581
type WriteStatus byte
582 583

const (
584
	NonStatTy WriteStatus = iota
585 586 587
	CanonStatTy
	SplitStatTy
	SideStatTy
588 589
)

590 591 592
// Rollback is designed to remove a chain of links from the database that aren't
// certain enough to be valid.
func (self *BlockChain) Rollback(chain []common.Hash) {
593 594 595
	self.mu.Lock()
	defer self.mu.Unlock()

596 597 598
	for i := len(chain) - 1; i >= 0; i-- {
		hash := chain[i]

599 600
		if self.hc.CurrentHeader().Hash() == hash {
			self.hc.SetCurrentHeader(self.GetHeader(self.hc.CurrentHeader().ParentHash))
601 602 603 604 605 606 607 608 609 610 611 612
		}
		if self.currentFastBlock.Hash() == hash {
			self.currentFastBlock = self.GetBlock(self.currentFastBlock.ParentHash())
			WriteHeadFastBlockHash(self.chainDb, self.currentFastBlock.Hash())
		}
		if self.currentBlock.Hash() == hash {
			self.currentBlock = self.GetBlock(self.currentBlock.ParentHash())
			WriteHeadBlockHash(self.chainDb, self.currentBlock.Hash())
		}
	}
}

613 614 615 616 617 618 619
// InsertReceiptChain attempts to complete an already existing header chain with
// transaction and receipt data.
func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) {
	self.wg.Add(1)
	defer self.wg.Done()

	// Collect some import statistics to report on
620
	stats := struct{ processed, ignored int32 }{}
621 622
	start := time.Now()

623 624
	// Create the block importing task queue and worker functions
	tasks := make(chan int, len(blockChain))
625
	for i := 0; i < len(blockChain) && i < len(receiptChain); i++ {
626 627 628
		tasks <- i
	}
	close(tasks)
629

630 631 632 633 634 635 636 637
	errs, failed := make([]error, len(tasks)), int32(0)
	process := func(worker int) {
		for index := range tasks {
			block, receipts := blockChain[index], receiptChain[index]

			// Short circuit insertion if shutting down or processing failed
			if atomic.LoadInt32(&self.procInterrupt) == 1 {
				return
638
			}
639 640
			if atomic.LoadInt32(&failed) > 0 {
				return
641
			}
642 643 644 645 646
			// Short circuit if the owner header is unknown
			if !self.HasHeader(block.Hash()) {
				errs[index] = fmt.Errorf("containing header #%d [%x…] unknown", block.Number(), block.Hash().Bytes()[:4])
				atomic.AddInt32(&failed, 1)
				return
647
			}
648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
			// Skip if the entire data is already known
			if self.HasBlock(block.Hash()) {
				atomic.AddInt32(&stats.ignored, 1)
				continue
			}
			// Compute all the non-consensus fields of the receipts
			transactions, logIndex := block.Transactions(), uint(0)
			for j := 0; j < len(receipts); j++ {
				// The transaction hash can be retrieved from the transaction itself
				receipts[j].TxHash = transactions[j].Hash()

				// The contract address can be derived from the transaction itself
				if MessageCreatesContract(transactions[j]) {
					from, _ := transactions[j].From()
					receipts[j].ContractAddress = crypto.CreateAddress(from, transactions[j].Nonce())
				}
				// The used gas can be calculated based on previous receipts
				if j == 0 {
					receipts[j].GasUsed = new(big.Int).Set(receipts[j].CumulativeGasUsed)
				} else {
					receipts[j].GasUsed = new(big.Int).Sub(receipts[j].CumulativeGasUsed, receipts[j-1].CumulativeGasUsed)
				}
				// The derived log fields can simply be set from the block and transaction
				for k := 0; k < len(receipts[j].Logs); k++ {
					receipts[j].Logs[k].BlockNumber = block.NumberU64()
					receipts[j].Logs[k].BlockHash = block.Hash()
					receipts[j].Logs[k].TxHash = receipts[j].TxHash
					receipts[j].Logs[k].TxIndex = uint(j)
					receipts[j].Logs[k].Index = logIndex
					logIndex++
				}
			}
			// Write all the data out into the database
681
			if err := WriteBody(self.chainDb, block.Hash(), block.Body()); err != nil {
682 683 684 685 686
				errs[index] = fmt.Errorf("failed to write block body: %v", err)
				atomic.AddInt32(&failed, 1)
				glog.Fatal(errs[index])
				return
			}
687
			if err := WriteBlockReceipts(self.chainDb, block.Hash(), receipts); err != nil {
688 689 690 691 692
				errs[index] = fmt.Errorf("failed to write block receipts: %v", err)
				atomic.AddInt32(&failed, 1)
				glog.Fatal(errs[index])
				return
			}
693 694 695 696 697 698
			if err := WriteMipmapBloom(self.chainDb, block.NumberU64(), receipts); err != nil {
				errs[index] = fmt.Errorf("failed to write log blooms: %v", err)
				atomic.AddInt32(&failed, 1)
				glog.Fatal(errs[index])
				return
			}
699 700 701 702 703 704 705 706 707 708 709 710
			if err := WriteTransactions(self.chainDb, block); err != nil {
				errs[index] = fmt.Errorf("failed to write individual transactions: %v", err)
				atomic.AddInt32(&failed, 1)
				glog.Fatal(errs[index])
				return
			}
			if err := WriteReceipts(self.chainDb, receipts); err != nil {
				errs[index] = fmt.Errorf("failed to write individual receipts: %v", err)
				atomic.AddInt32(&failed, 1)
				glog.Fatal(errs[index])
				return
			}
711
			atomic.AddInt32(&stats.processed, 1)
712
		}
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729
	}
	// Start as many worker threads as goroutines allowed
	pending := new(sync.WaitGroup)
	for i := 0; i < runtime.GOMAXPROCS(0); i++ {
		pending.Add(1)
		go func(id int) {
			defer pending.Done()
			process(id)
		}(i)
	}
	pending.Wait()

	// If anything failed, report
	if failed > 0 {
		for i, err := range errs {
			if err != nil {
				return i, err
730 731 732
			}
		}
	}
733 734 735 736
	if atomic.LoadInt32(&self.procInterrupt) == 1 {
		glog.V(logger.Debug).Infoln("premature abort during receipt chain processing")
		return 0, nil
	}
737 738 739 740 741 742 743 744 745 746 747
	// Update the head fast sync block if better
	self.mu.Lock()
	head := blockChain[len(errs)-1]
	if self.GetTd(self.currentFastBlock.Hash()).Cmp(self.GetTd(head.Hash())) < 0 {
		if err := WriteHeadFastBlockHash(self.chainDb, head.Hash()); err != nil {
			glog.Fatalf("failed to update head fast block hash: %v", err)
		}
		self.currentFastBlock = head
	}
	self.mu.Unlock()

748 749 750 751 752 753 754 755
	// Report some public statistics so the user has a clue what's going on
	first, last := blockChain[0], blockChain[len(blockChain)-1]
	glog.V(logger.Info).Infof("imported %d receipt(s) (%d ignored) in %v. #%d [%x… / %x…]", stats.processed, stats.ignored,
		time.Since(start), last.Number(), first.Hash().Bytes()[:4], last.Hash().Bytes()[:4])

	return 0, nil
}

756
// WriteBlock writes the block to the chain.
757
func (self *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err error) {
758 759 760
	self.wg.Add(1)
	defer self.wg.Done()

761 762 763 764 765
	// Calculate the total difficulty of the block
	ptd := self.GetTd(block.ParentHash())
	if ptd == nil {
		return NonStatTy, ParentError(block.ParentHash())
	}
766 767 768

	localTd := self.GetTd(self.currentBlock.Hash())
	externTd := new(big.Int).Add(block.Difficulty(), ptd)
769

770 771 772
	// Make sure no inconsistent state is leaked during insertion
	self.mu.Lock()
	defer self.mu.Unlock()
773

774
	// If the total difficulty is higher than our known, add it to the canonical chain
775 776 777
	// Second clause in the if statement reduces the vulnerability to selfish mining.
	// Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf
	if externTd.Cmp(localTd) > 0 || (externTd.Cmp(localTd) == 0 && mrand.Float64() < 0.5) {
778
		// Reorganise the chain if the parent is not the head block
779 780
		if block.ParentHash() != self.currentBlock.Hash() {
			if err := self.reorg(self.currentBlock, block); err != nil {
781
				return NonStatTy, err
782 783
			}
		}
784
		// Insert the block as the new head of the chain
785
		self.insert(block)
786
		status = CanonStatTy
787
	} else {
788
		status = SideStatTy
789
	}
790
	// Irrelevant of the canonical status, write the block itself to the database
791
	if err := self.hc.WriteTd(block.Hash(), externTd); err != nil {
792 793 794
		glog.Fatalf("failed to write block total difficulty: %v", err)
	}
	if err := WriteBlock(self.chainDb, block); err != nil {
L
Leif Jurvetson 已提交
795
		glog.Fatalf("failed to write block contents: %v", err)
796
	}
797

798
	self.futureBlocks.Remove(block.Hash())
799 800 801 802

	return
}

803 804
// InsertChain will attempt to insert the given chain in to the canonical chain or, otherwise, create a fork. It an error is returned
// it will return the index number of the failing block as well an error describing what went wrong (for possible errors see core/errors.go).
805
func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
806 807 808
	self.wg.Add(1)
	defer self.wg.Done()

O
obscuren 已提交
809 810 811
	self.chainmu.Lock()
	defer self.chainmu.Unlock()

F
Felix Lange 已提交
812 813 814
	// A queued approach to delivering events. This is generally
	// faster than direct delivery and requires much less mutex
	// acquiring.
O
obscuren 已提交
815
	var (
816 817 818 819
		stats         struct{ queued, processed, ignored int }
		events        = make([]interface{}, 0, len(chain))
		coalescedLogs vm.Logs
		tstart        = time.Now()
F
Felix Lange 已提交
820 821

		nonceChecked = make([]bool, len(chain))
822
		statedb      *state.StateDB
O
obscuren 已提交
823
	)
824

F
Felix Lange 已提交
825
	// Start the parallel nonce verifier.
826 827
	nonceAbort, nonceResults := verifyNoncesFromBlocks(self.pow, chain)
	defer close(nonceAbort)
828

829
	txcount := 0
830
	for i, block := range chain {
O
obscuren 已提交
831
		if atomic.LoadInt32(&self.procInterrupt) == 1 {
832
			glog.V(logger.Debug).Infoln("Premature abort during block chain processing")
O
obscuren 已提交
833 834
			break
		}
835

O
obscuren 已提交
836 837 838 839
		bstart := time.Now()
		// Wait for block i's nonce to be verified before processing
		// its state transition.
		for !nonceChecked[i] {
840 841
			r := <-nonceResults
			nonceChecked[r.index] = true
O
obscuren 已提交
842
			if !r.valid {
843 844
				block := chain[r.index]
				return r.index, &BlockNonceErr{Hash: block.Hash(), Number: block.Number(), Nonce: block.Nonce()}
O
obscuren 已提交
845
			}
O
obscuren 已提交
846
		}
O
obscuren 已提交
847

O
obscuren 已提交
848
		if BadHashes[block.Hash()] {
849
			err := BadHashError(block.Hash())
850
			reportBlock(block, err)
O
obscuren 已提交
851 852
			return i, err
		}
853 854 855
		// Stage 1 validation of the block using the chain's validator
		// interface.
		err := self.Validator().ValidateBlock(block)
O
obscuren 已提交
856 857 858 859 860
		if err != nil {
			if IsKnownBlockErr(err) {
				stats.ignored++
				continue
			}
861

O
obscuren 已提交
862 863 864 865
			if err == BlockFutureErr {
				// Allow up to MaxFuture second in the future blocks. If this limit
				// is exceeded the chain is discarded and processed at a later time
				// if given.
866 867
				max := big.NewInt(time.Now().Unix() + maxTimeFutureBlocks)
				if block.Time().Cmp(max) == 1 {
O
obscuren 已提交
868
					return i, fmt.Errorf("%v: BlockFutureErr, %v > %v", BlockFutureErr, block.Time(), max)
869
				}
O
obscuren 已提交
870

871
				self.futureBlocks.Add(block.Hash(), block)
O
obscuren 已提交
872 873 874
				stats.queued++
				continue
			}
O
obscuren 已提交
875

876 877
			if IsParentErr(err) && self.futureBlocks.Contains(block.ParentHash()) {
				self.futureBlocks.Add(block.Hash(), block)
O
obscuren 已提交
878 879
				stats.queued++
				continue
880
			}
881

882
			reportBlock(block, err)
O
obscuren 已提交
883

884 885
			return i, err
		}
886

887 888
		// Create a new statedb using the parent block and report an
		// error if it fails.
889 890 891 892 893
		if statedb == nil {
			statedb, err = state.New(self.GetBlock(block.ParentHash()).Root(), self.chainDb)
		} else {
			err = statedb.Reset(chain[i-1].Root())
		}
894 895
		if err != nil {
			reportBlock(block, err)
O
obscuren 已提交
896 897
			return i, err
		}
898
		// Process block using the parent state as reference point.
899
		receipts, logs, usedGas, err := self.processor.Process(block, statedb, self.config.VmConfig)
900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918
		if err != nil {
			reportBlock(block, err)
			return i, err
		}
		// Validate the state using the default validator
		err = self.Validator().ValidateState(block, self.GetBlock(block.ParentHash()), statedb, receipts, usedGas)
		if err != nil {
			reportBlock(block, err)
			return i, err
		}
		// Write state changes to database
		_, err = statedb.Commit()
		if err != nil {
			return i, err
		}

		// coalesce logs for later processing
		coalescedLogs = append(coalescedLogs, logs...)

919
		if err := WriteBlockReceipts(self.chainDb, block.Hash(), receipts); err != nil {
920
			return i, err
921
		}
O
obscuren 已提交
922 923

		txcount += len(block.Transactions())
924
		// write the block to the chain and get the status
925
		status, err := self.WriteBlock(block)
926 927 928
		if err != nil {
			return i, err
		}
929

930
		switch status {
931
		case CanonStatTy:
O
obscuren 已提交
932
			if glog.V(logger.Debug) {
933
				glog.Infof("[%v] inserted block #%d (%d TXs %v G %d UNCs) (%x...). Took %v\n", time.Now().UnixNano(), block.Number(), len(block.Transactions()), block.GasUsed(), len(block.Uncles()), block.Hash().Bytes()[0:4], time.Since(bstart))
O
obscuren 已提交
934
			}
935
			events = append(events, ChainEvent{block, block.Hash(), logs})
936 937

			// This puts transactions in a extra db for rpc
938
			if err := WriteTransactions(self.chainDb, block); err != nil {
939 940
				return i, err
			}
941
			// store the receipts
942
			if err := WriteReceipts(self.chainDb, receipts); err != nil {
943 944 945 946 947 948
				return i, err
			}
			// Write map map bloom filters
			if err := WriteMipmapBloom(self.chainDb, block.NumberU64(), receipts); err != nil {
				return i, err
			}
949
		case SideStatTy:
O
obscuren 已提交
950 951
			if glog.V(logger.Detail) {
				glog.Infof("inserted forked block #%d (TD=%v) (%d TXs %d UNCs) (%x...). Took %v\n", block.Number(), block.Difficulty(), len(block.Transactions()), len(block.Uncles()), block.Hash().Bytes()[0:4], time.Since(bstart))
O
obscuren 已提交
952
			}
953 954
			events = append(events, ChainSideEvent{block, logs})

955
		case SplitStatTy:
956
			events = append(events, ChainSplitEvent{block, logs})
957
		}
O
obscuren 已提交
958
		stats.processed++
O
obscuren 已提交
959 960
	}

O
obscuren 已提交
961
	if (stats.queued > 0 || stats.processed > 0 || stats.ignored > 0) && bool(glog.V(logger.Info)) {
O
obscuren 已提交
962
		tend := time.Since(tstart)
O
obscuren 已提交
963
		start, end := chain[0], chain[len(chain)-1]
964
		glog.Infof("imported %d block(s) (%d queued %d ignored) including %d txs in %v. #%v [%x / %x]\n", stats.processed, stats.queued, stats.ignored, txcount, tend, end.Number(), start.Hash().Bytes()[:4], end.Hash().Bytes()[:4])
O
obscuren 已提交
965
	}
966
	go self.postChainEvents(events, coalescedLogs)
967

968
	return 0, nil
O
obscuren 已提交
969
}
970

971 972 973
// reorgs takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them
// to be part of the new canonical chain and accumulates potential missing transactions and post an
// event about them
974
func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
975
	var (
976 977 978 979 980 981 982 983
		newChain          types.Blocks
		oldChain          types.Blocks
		commonBlock       *types.Block
		oldStart          = oldBlock
		newStart          = newBlock
		deletedTxs        types.Transactions
		deletedLogs       vm.Logs
		deletedLogsByHash = make(map[common.Hash]vm.Logs)
J
Jeffrey Wilcke 已提交
984 985 986 987 988 989 990 991
		// collectLogs collects the logs that were generated during the
		// processing of the block that corresponds with the given hash.
		// These logs are later announced as deleted.
		collectLogs = func(h common.Hash) {
			// Coalesce logs
			receipts := GetBlockReceipts(self.chainDb, h)
			for _, receipt := range receipts {
				deletedLogs = append(deletedLogs, receipt.Logs...)
992 993

				deletedLogsByHash[h] = receipt.Logs
J
Jeffrey Wilcke 已提交
994 995
			}
		}
996
	)
997 998 999 1000

	// first reduce whoever is higher bound
	if oldBlock.NumberU64() > newBlock.NumberU64() {
		// reduce old chain
F
Felix Lange 已提交
1001
		for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = self.GetBlock(oldBlock.ParentHash()) {
1002
			oldChain = append(oldChain, oldBlock)
1003
			deletedTxs = append(deletedTxs, oldBlock.Transactions()...)
J
Jeffrey Wilcke 已提交
1004 1005

			collectLogs(oldBlock.Hash())
1006 1007 1008
		}
	} else {
		// reduce new chain and append new chain blocks for inserting later on
F
Felix Lange 已提交
1009
		for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = self.GetBlock(newBlock.ParentHash()) {
1010 1011
			newChain = append(newChain, newBlock)
		}
O
obscuren 已提交
1012
	}
O
obscuren 已提交
1013
	if oldBlock == nil {
1014
		return fmt.Errorf("Invalid old chain")
O
obscuren 已提交
1015 1016
	}
	if newBlock == nil {
1017
		return fmt.Errorf("Invalid new chain")
O
obscuren 已提交
1018
	}
O
obscuren 已提交
1019

1020
	numSplit := newBlock.Number()
1021 1022
	for {
		if oldBlock.Hash() == newBlock.Hash() {
1023
			commonBlock = oldBlock
1024 1025
			break
		}
1026 1027

		oldChain = append(oldChain, oldBlock)
1028
		newChain = append(newChain, newBlock)
1029
		deletedTxs = append(deletedTxs, oldBlock.Transactions()...)
J
Jeffrey Wilcke 已提交
1030
		collectLogs(oldBlock.Hash())
O
obscuren 已提交
1031 1032

		oldBlock, newBlock = self.GetBlock(oldBlock.ParentHash()), self.GetBlock(newBlock.ParentHash())
1033
		if oldBlock == nil {
1034
			return fmt.Errorf("Invalid old chain")
1035 1036
		}
		if newBlock == nil {
1037
			return fmt.Errorf("Invalid new chain")
1038
		}
1039 1040
	}

1041
	if glog.V(logger.Debug) {
1042
		commonHash := commonBlock.Hash()
1043
		glog.Infof("Chain split detected @ %x. Reorganising chain from #%v %x to %x", commonHash[:4], numSplit, oldStart.Hash().Bytes()[:4], newStart.Hash().Bytes()[:4])
1044 1045
	}

1046
	var addedTxs types.Transactions
1047
	// insert blocks. Order does not matter. Last block will be written in ImportChain itself which creates the new head properly
1048
	for _, block := range newChain {
1049
		// insert the block in the canonical way, re-writing history
1050
		self.insert(block)
1051
		// write canonical receipts and transactions
1052
		if err := WriteTransactions(self.chainDb, block); err != nil {
1053 1054 1055 1056
			return err
		}
		receipts := GetBlockReceipts(self.chainDb, block.Hash())
		// write receipts
1057
		if err := WriteReceipts(self.chainDb, receipts); err != nil {
1058 1059 1060 1061 1062 1063
			return err
		}
		// Write map map bloom filters
		if err := WriteMipmapBloom(self.chainDb, block.NumberU64(), receipts); err != nil {
			return err
		}
1064 1065 1066 1067 1068 1069 1070 1071 1072 1073
		addedTxs = append(addedTxs, block.Transactions()...)
	}

	// calculate the difference between deleted and added transactions
	diff := types.TxDifference(deletedTxs, addedTxs)
	// When transactions get deleted from the database that means the
	// receipts that were created in the fork must also be deleted
	for _, tx := range diff {
		DeleteReceipt(self.chainDb, tx.Hash())
		DeleteTransaction(self.chainDb, tx.Hash())
1074
	}
1075 1076
	// Must be posted in a goroutine because of the transaction pool trying
	// to acquire the chain manager lock
J
Jeffrey Wilcke 已提交
1077 1078 1079 1080
	if len(diff) > 0 {
		go self.eventMux.Post(RemovedTransactionEvent{diff})
	}
	if len(deletedLogs) > 0 {
1081
		go self.eventMux.Post(RemovedLogsEvent{deletedLogs})
J
Jeffrey Wilcke 已提交
1082
	}
1083

1084 1085 1086 1087 1088 1089 1090 1091
	if len(oldChain) > 0 {
		go func() {
			for _, block := range oldChain {
				self.eventMux.Post(ChainSideEvent{Block: block, Logs: deletedLogsByHash[block.Hash()]})
			}
		}()
	}

1092
	return nil
1093 1094
}

1095 1096
// postChainEvents iterates over the events generated by a chain insertion and
// posts them into the event mux.
1097 1098 1099
func (self *BlockChain) postChainEvents(events []interface{}, logs vm.Logs) {
	// post event logs for further processing
	self.eventMux.Post(logs)
1100 1101 1102 1103
	for _, event := range events {
		if event, ok := event.(ChainEvent); ok {
			// We need some control over the mining operation. Acquiring locks and waiting for the miner to create new block takes too long
			// and in most cases isn't even necessary.
1104
			if self.LastBlockHash() == event.Hash {
1105 1106 1107 1108 1109 1110 1111 1112
				self.eventMux.Post(ChainHeadEvent{event.Block})
			}
		}
		// Fire the insertion events individually too
		self.eventMux.Post(event)
	}
}

1113
func (self *BlockChain) update() {
O
obscuren 已提交
1114
	futureTimer := time.Tick(5 * time.Second)
1115 1116
	for {
		select {
O
obscuren 已提交
1117
		case <-futureTimer:
1118
			self.procFutureBlocks()
1119
		case <-self.quit:
1120
			return
1121 1122 1123
		}
	}
}
1124

F
Felix Lange 已提交
1125
// reportBlock logs a bad block error.
1126
func reportBlock(block *types.Block, err error) {
1127 1128 1129 1130
	if glog.V(logger.Error) {
		glog.Errorf("Bad block #%v (%s)\n", block.Number(), block.Hash().Hex())
		glog.Errorf("    %v", err)
	}
F
Felix Lange 已提交
1131
}
1132 1133 1134 1135 1136 1137 1138

// InsertHeaderChain attempts to insert the given header chain in to the local
// chain, possibly creating a reorg. If an error is returned, it will return the
// index number of the failing header as well an error describing what went wrong.
//
// The verify parameter can be used to fine tune whether nonce verification
// should be done or not. The reason behind the optional check is because some
L
Leif Jurvetson 已提交
1139
// of the header retrieval mechanisms already need to verify nonces, as well as
1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217
// because nonces can be verified sparsely, not needing to check each.
func (self *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) {
	// Make sure only one thread manipulates the chain at once
	self.chainmu.Lock()
	defer self.chainmu.Unlock()

	self.wg.Add(1)
	defer self.wg.Done()

	whFunc := func(header *types.Header) error {
		self.mu.Lock()
		defer self.mu.Unlock()

		_, err := self.hc.WriteHeader(header)
		return err
	}

	return self.hc.InsertHeaderChain(chain, checkFreq, whFunc)
}

// writeHeader writes a header into the local chain, given that its parent is
// already known. If the total difficulty of the newly inserted header becomes
// greater than the current known TD, the canonical chain is re-routed.
//
// Note: This method is not concurrent-safe with inserting blocks simultaneously
// into the chain, as side effects caused by reorganisations cannot be emulated
// without the real blocks. Hence, writing headers directly should only be done
// in two scenarios: pure-header mode of operation (light clients), or properly
// separated header/block phases (non-archive clients).
func (self *BlockChain) writeHeader(header *types.Header) error {
	self.wg.Add(1)
	defer self.wg.Done()

	self.mu.Lock()
	defer self.mu.Unlock()

	_, err := self.hc.WriteHeader(header)
	return err
}

// CurrentHeader retrieves the current head header of the canonical chain. The
// header is retrieved from the HeaderChain's internal cache.
func (self *BlockChain) CurrentHeader() *types.Header {
	self.mu.RLock()
	defer self.mu.RUnlock()

	return self.hc.CurrentHeader()
}

// GetTd retrieves a block's total difficulty in the canonical chain from the
// database by hash, caching it if found.
func (self *BlockChain) GetTd(hash common.Hash) *big.Int {
	return self.hc.GetTd(hash)
}

// GetHeader retrieves a block header from the database by hash, caching it if
// found.
func (self *BlockChain) GetHeader(hash common.Hash) *types.Header {
	return self.hc.GetHeader(hash)
}

// HasHeader checks if a block header is present in the database or not, caching
// it if present.
func (bc *BlockChain) HasHeader(hash common.Hash) bool {
	return bc.hc.HasHeader(hash)
}

// GetBlockHashesFromHash retrieves a number of block hashes starting at a given
// hash, fetching towards the genesis block.
func (self *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash {
	return self.hc.GetBlockHashesFromHash(hash, max)
}

// GetHeaderByNumber retrieves a block header from the database by number,
// caching it (associated with its hash) if found.
func (self *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
	return self.hc.GetHeaderByNumber(number)
}
1218 1219 1220

// Config retrieves the blockchain's chain configuration.
func (self *BlockChain) Config() *ChainConfig { return self.config }