blockchain.go 40.6 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 101 102
	stateCache   *state.StateDB // State database to reuse between imports (contains state cache)
	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
	futureBlocks *lru.Cache     // future blocks are blocks added for later processing
103

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

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

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

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

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

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

150
	if err := bc.loadLastState(); err != nil {
151
		return nil, err
O
obscuren 已提交
152
	}
153
	// Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain
154
	for hash, _ := range BadHashes {
155 156 157 158
		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")
159 160
		}
	}
161
	// Take ownership of this particular state
162
	go bc.update()
O
obscuren 已提交
163
	return bc, nil
164 165
}

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

170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
// 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
188
	currentHeader := self.currentBlock.Header()
189 190
	if head := GetHeadHeaderHash(self.chainDb); head != (common.Hash{}) {
		if header := self.GetHeader(head); header != nil {
191
			currentHeader = header
192 193
		}
	}
194
	self.hc.SetCurrentHeader(currentHeader)
195 196 197 198 199 200 201
	// 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
		}
	}
202 203 204 205 206 207 208 209
	// Initialize a statedb cache to ensure singleton account bloom filter generation
	statedb, err := state.New(self.currentBlock.Root(), self.chainDb)
	if err != nil {
		return err
	}
	self.stateCache = statedb
	self.stateCache.GetAccount(common.Address{})

210
	// Issue a status log and return
211
	headerTd := self.GetTd(self.hc.CurrentHeader().Hash())
212
	blockTd := self.GetTd(self.currentBlock.Hash())
213
	fastTd := self.GetTd(self.currentFastBlock.Hash())
214
	glog.V(logger.Info).Infof("Last header: #%d [%x…] TD=%v", self.hc.CurrentHeader().Number, self.hc.CurrentHeader().Hash().Bytes()[:4], headerTd)
215
	glog.V(logger.Info).Infof("Last block: #%d [%x…] TD=%v", self.currentBlock.Number(), self.currentBlock.Hash().Bytes()[:4], blockTd)
216
	glog.V(logger.Info).Infof("Fast block: #%d [%x…] TD=%v", self.currentFastBlock.Number(), self.currentFastBlock.Hash().Bytes()[:4], fastTd)
217 218 219 220

	return nil
}

221 222 223 224
// 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).
225
func (bc *BlockChain) SetHead(head uint64) {
226 227 228
	bc.mu.Lock()
	defer bc.mu.Unlock()

229
	delFn := func(hash common.Hash) {
230 231
		DeleteBody(bc.chainDb, hash)
	}
232 233
	bc.hc.SetHead(head, delFn)

234
	// Clear out any stale content from the caches
235 236 237 238
	bc.bodyCache.Purge()
	bc.bodyRLPCache.Purge()
	bc.blockCache.Purge()
	bc.futureBlocks.Purge()
239

240
	// Update all computed fields to the new head
241 242 243 244 245 246 247
	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())
	}

248 249 250
	if bc.currentBlock == nil {
		bc.currentBlock = bc.genesisBlock
	}
251 252 253
	if bc.currentFastBlock == nil {
		bc.currentFastBlock = bc.genesisBlock
	}
254

255 256 257 258 259 260
	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)
	}
261
	bc.loadLastState()
262 263
}

264 265 266
// 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 {
267
	// Make sure that both the block as well at its state trie exists
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
	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
}

284
// GasLimit returns the gas limit of the current HEAD block.
285
func (self *BlockChain) GasLimit() *big.Int {
O
obscuren 已提交
286 287
	self.mu.RLock()
	defer self.mu.RUnlock()
O
obscuren 已提交
288

289
	return self.currentBlock.GasLimit()
O
obscuren 已提交
290 291
}

292
// LastBlockHash return the hash of the HEAD block.
293
func (self *BlockChain) LastBlockHash() common.Hash {
294 295 296
	self.mu.RLock()
	defer self.mu.RUnlock()

297
	return self.currentBlock.Hash()
298 299
}

300
// CurrentBlock retrieves the current head block of the canonical chain. The
301
// block is retrieved from the blockchain's internal cache.
302
func (self *BlockChain) CurrentBlock() *types.Block {
O
obscuren 已提交
303 304 305 306
	self.mu.RLock()
	defer self.mu.RUnlock()

	return self.currentBlock
O
obscuren 已提交
307 308
}

309
// CurrentFastBlock retrieves the current fast-sync head block of the canonical
310
// chain. The block is retrieved from the blockchain's internal cache.
311 312 313 314 315 316 317
func (self *BlockChain) CurrentFastBlock() *types.Block {
	self.mu.RLock()
	defer self.mu.RUnlock()

	return self.currentFastBlock
}

318 319
// Status returns status information about the current chain such as the HEAD Td,
// the HEAD hash and the hash of the genesis block.
320
func (self *BlockChain) Status() (td *big.Int, currentBlock common.Hash, genesisBlock common.Hash) {
O
obscuren 已提交
321 322 323
	self.mu.RLock()
	defer self.mu.RUnlock()

324
	return self.GetTd(self.currentBlock.Hash()), self.currentBlock.Hash(), self.genesisBlock.Hash()
325 326
}

327 328 329 330 331 332 333 334 335 336 337 338
// 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
339 340
}

341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
// 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.
359
func (self *BlockChain) State() (*state.StateDB, error) {
360 361 362 363 364 365
	return self.StateAt(self.CurrentBlock().Root())
}

// StateAt returns a new mutable state based on a particular point in time.
func (self *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
	return self.stateCache.New(root)
O
obscuren 已提交
366 367
}

368
// Reset purges the entire blockchain, restoring it to its genesis state.
369
func (bc *BlockChain) Reset() {
370
	bc.ResetWithGenesisBlock(bc.genesisBlock)
371 372
}

373 374
// ResetWithGenesisBlock purges the entire blockchain, restoring it to the
// specified genesis state.
375
func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) {
376 377 378
	// Dump the entire block chain and purge the caches
	bc.SetHead(0)

379 380 381
	bc.mu.Lock()
	defer bc.mu.Unlock()

382
	// Prepare the genesis block and reinitialise the chain
383
	if err := bc.hc.WriteTd(genesis.Hash(), genesis.Difficulty()); err != nil {
384 385 386
		glog.Fatalf("failed to write genesis block TD: %v", err)
	}
	if err := WriteBlock(bc.chainDb, genesis); err != nil {
387
		glog.Fatalf("failed to write genesis block: %v", err)
388
	}
389
	bc.genesisBlock = genesis
390 391
	bc.insert(bc.genesisBlock)
	bc.currentBlock = bc.genesisBlock
392 393
	bc.hc.SetGenesis(bc.genesisBlock.Header())
	bc.hc.SetCurrentHeader(bc.genesisBlock.Header())
394
	bc.currentFastBlock = bc.genesisBlock
395 396
}

397
// Export writes the active chain to the given writer.
398
func (self *BlockChain) Export(w io.Writer) error {
399
	if err := self.ExportN(w, uint64(0), self.currentBlock.NumberU64()); err != nil {
T
Taylor Gerring 已提交
400 401 402 403 404 405
		return err
	}
	return nil
}

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

T
Taylor Gerring 已提交
410 411 412 413
	if first > last {
		return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last)
	}

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

T
Taylor Gerring 已提交
416
	for nr := first; nr <= last; nr++ {
417 418 419 420 421 422
		block := self.GetBlockByNumber(nr)
		if block == nil {
			return fmt.Errorf("export failed on #%d: not found", nr)
		}

		if err := block.EncodeRLP(w); err != nil {
423 424
			return err
		}
O
obscuren 已提交
425
	}
426

427
	return nil
O
obscuren 已提交
428 429
}

430 431
// 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
432 433
// 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.
434 435
//
// Note, this function assumes that the `mu` mutex is held!
436
func (bc *BlockChain) insert(block *types.Block) {
437 438 439
	// 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()

440 441 442
	// 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)
443
	}
444
	if err := WriteHeadBlockHash(bc.chainDb, block.Hash()); err != nil {
445
		glog.Fatalf("failed to insert head block hash: %v", err)
446
	}
447
	bc.currentBlock = block
448 449 450

	// If the block is better than out head or is on a different chain, force update heads
	if updateHeads {
451
		bc.hc.SetCurrentHeader(block.Header())
452 453 454 455 456 457

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

O
obscuren 已提交
460
// Accessors
461
func (bc *BlockChain) Genesis() *types.Block {
O
obscuren 已提交
462 463 464
	return bc.genesisBlock
}

465 466
// GetBody retrieves a block body (transactions and uncles) from the database by
// hash, caching it if found.
467
func (self *BlockChain) GetBody(hash common.Hash) *types.Body {
468 469
	// Short circuit if the body's already in the cache, retrieve otherwise
	if cached, ok := self.bodyCache.Get(hash); ok {
470 471
		body := cached.(*types.Body)
		return body
O
obscuren 已提交
472
	}
473 474 475
	body := GetBody(self.chainDb, hash)
	if body == nil {
		return nil
476 477
	}
	// Cache the found body for next time and return
478 479
	self.bodyCache.Add(hash, body)
	return body
480
}
O
obscuren 已提交
481

482 483
// GetBodyRLP retrieves a block body in RLP encoding from the database by hash,
// caching it if found.
484
func (self *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
485 486
	// Short circuit if the body's already in the cache, retrieve otherwise
	if cached, ok := self.bodyRLPCache.Get(hash); ok {
487
		return cached.(rlp.RawValue)
488
	}
489 490
	body := GetBodyRLP(self.chainDb, hash)
	if len(body) == 0 {
491
		return nil
O
obscuren 已提交
492
	}
493 494 495 496
	// Cache the found body for next time and return
	self.bodyRLPCache.Add(hash, body)
	return body
}
O
obscuren 已提交
497

498 499
// HasBlock checks if a block is fully present in the database or not, caching
// it if present.
500
func (bc *BlockChain) HasBlock(hash common.Hash) bool {
501
	return bc.GetBlock(hash) != nil
O
obscuren 已提交
502 503
}

504 505 506 507 508 509 510 511 512 513 514 515 516
// 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
}

517
// GetBlock retrieves a block from the database by hash, caching it if found.
518
func (self *BlockChain) GetBlock(hash common.Hash) *types.Block {
519 520
	// Short circuit if the block's already in the cache, retrieve otherwise
	if block, ok := self.blockCache.Get(hash); ok {
521 522
		return block.(*types.Block)
	}
523
	block := GetBlock(self.chainDb, hash)
524
	if block == nil {
O
obscuren 已提交
525 526
		return nil
	}
527 528 529
	// Cache the found block for next time and return
	self.blockCache.Add(block.Hash(), block)
	return block
O
obscuren 已提交
530 531
}

532 533
// GetBlockByNumber retrieves a block from the database by number, caching it
// (associated with its hash) if found.
534
func (self *BlockChain) GetBlockByNumber(number uint64) *types.Block {
535
	hash := GetCanonicalHash(self.chainDb, number)
536 537 538 539 540
	if hash == (common.Hash{}) {
		return nil
	}
	return self.GetBlock(hash)
}
541

542
// [deprecated by eth/62]
F
Felix Lange 已提交
543
// GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
544
func (self *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
F
Felix Lange 已提交
545 546 547 548 549 550 551 552 553 554 555
	for i := 0; i < n; i++ {
		block := self.GetBlock(hash)
		if block == nil {
			break
		}
		blocks = append(blocks, block)
		hash = block.ParentHash()
	}
	return
}

556 557 558 559
// 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{}
560 561 562 563
	for i := 0; block != nil && i < length; i++ {
		uncles = append(uncles, block.Uncles()...)
		block = self.GetBlock(block.ParentHash())
	}
564
	return uncles
O
obscuren 已提交
565
}
O
obscuren 已提交
566

567 568
// Stop stops the blockchain service. If any imports are currently in progress
// it will abort them using the procInterrupt.
569
func (bc *BlockChain) Stop() {
570 571 572
	if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) {
		return
	}
573
	close(bc.quit)
O
obscuren 已提交
574
	atomic.StoreInt32(&bc.procInterrupt, 1)
575 576 577 578

	bc.wg.Wait()

	glog.V(logger.Info).Infoln("Chain manager stopped")
579 580
}

581
func (self *BlockChain) procFutureBlocks() {
582 583 584 585 586
	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))
		}
587
	}
588 589 590 591
	if len(blocks) > 0 {
		types.BlockBy(types.Number).Sort(blocks)
		self.InsertChain(blocks)
	}
592 593
}

594
type WriteStatus byte
595 596

const (
597
	NonStatTy WriteStatus = iota
598 599 600
	CanonStatTy
	SplitStatTy
	SideStatTy
601 602
)

603 604 605
// 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) {
606 607 608
	self.mu.Lock()
	defer self.mu.Unlock()

609 610 611
	for i := len(chain) - 1; i >= 0; i-- {
		hash := chain[i]

612 613
		if self.hc.CurrentHeader().Hash() == hash {
			self.hc.SetCurrentHeader(self.GetHeader(self.hc.CurrentHeader().ParentHash))
614 615 616 617 618 619 620 621 622 623 624 625
		}
		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())
		}
	}
}

626 627 628 629 630 631 632
// 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
633
	stats := struct{ processed, ignored int32 }{}
634 635
	start := time.Now()

636 637
	// Create the block importing task queue and worker functions
	tasks := make(chan int, len(blockChain))
638
	for i := 0; i < len(blockChain) && i < len(receiptChain); i++ {
639 640 641
		tasks <- i
	}
	close(tasks)
642

643 644 645 646 647 648 649 650
	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
651
			}
652 653
			if atomic.LoadInt32(&failed) > 0 {
				return
654
			}
655 656 657 658 659
			// 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
660
			}
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693
			// 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
694
			if err := WriteBody(self.chainDb, block.Hash(), block.Body()); err != nil {
695 696 697 698 699
				errs[index] = fmt.Errorf("failed to write block body: %v", err)
				atomic.AddInt32(&failed, 1)
				glog.Fatal(errs[index])
				return
			}
700
			if err := WriteBlockReceipts(self.chainDb, block.Hash(), receipts); err != nil {
701 702 703 704 705
				errs[index] = fmt.Errorf("failed to write block receipts: %v", err)
				atomic.AddInt32(&failed, 1)
				glog.Fatal(errs[index])
				return
			}
706 707 708 709 710 711
			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
			}
712 713 714 715 716 717 718 719 720 721 722 723
			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
			}
724
			atomic.AddInt32(&stats.processed, 1)
725
		}
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742
	}
	// 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
743 744 745
			}
		}
	}
746 747 748 749
	if atomic.LoadInt32(&self.procInterrupt) == 1 {
		glog.V(logger.Debug).Infoln("premature abort during receipt chain processing")
		return 0, nil
	}
750 751 752 753 754 755 756 757 758 759 760
	// 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()

761 762 763 764 765 766 767 768
	// 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
}

769
// WriteBlock writes the block to the chain.
770
func (self *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err error) {
771 772 773
	self.wg.Add(1)
	defer self.wg.Done()

774 775 776 777 778
	// Calculate the total difficulty of the block
	ptd := self.GetTd(block.ParentHash())
	if ptd == nil {
		return NonStatTy, ParentError(block.ParentHash())
	}
779 780 781
	// Make sure no inconsistent state is leaked during insertion
	self.mu.Lock()
	defer self.mu.Unlock()
782

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

786 787 788 789 790 791 792 793
	// Irrelevant of the canonical status, write the block itself to the database
	if err := self.hc.WriteTd(block.Hash(), externTd); err != nil {
		glog.Fatalf("failed to write block total difficulty: %v", err)
	}
	if err := WriteBlock(self.chainDb, block); err != nil {
		glog.Fatalf("failed to write block contents: %v", err)
	}

794
	// If the total difficulty is higher than our known, add it to the canonical chain
795 796 797
	// 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) {
798
		// Reorganise the chain if the parent is not the head block
799 800
		if block.ParentHash() != self.currentBlock.Hash() {
			if err := self.reorg(self.currentBlock, block); err != nil {
801
				return NonStatTy, err
802 803
			}
		}
804
		self.insert(block) // Insert the block as the new head of the chain
805
		status = CanonStatTy
806
	} else {
807
		status = SideStatTy
808
	}
809
	self.futureBlocks.Remove(block.Hash())
810 811 812 813

	return
}

814 815
// 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).
816
func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
817 818 819
	self.wg.Add(1)
	defer self.wg.Done()

O
obscuren 已提交
820 821 822
	self.chainmu.Lock()
	defer self.chainmu.Unlock()

F
Felix Lange 已提交
823 824 825
	// A queued approach to delivering events. This is generally
	// faster than direct delivery and requires much less mutex
	// acquiring.
O
obscuren 已提交
826
	var (
827 828 829 830
		stats         struct{ queued, processed, ignored int }
		events        = make([]interface{}, 0, len(chain))
		coalescedLogs vm.Logs
		tstart        = time.Now()
F
Felix Lange 已提交
831 832

		nonceChecked = make([]bool, len(chain))
O
obscuren 已提交
833
	)
834

F
Felix Lange 已提交
835
	// Start the parallel nonce verifier.
836 837
	nonceAbort, nonceResults := verifyNoncesFromBlocks(self.pow, chain)
	defer close(nonceAbort)
838

839
	txcount := 0
840
	for i, block := range chain {
O
obscuren 已提交
841
		if atomic.LoadInt32(&self.procInterrupt) == 1 {
842
			glog.V(logger.Debug).Infoln("Premature abort during block chain processing")
O
obscuren 已提交
843 844
			break
		}
845

O
obscuren 已提交
846 847 848 849
		bstart := time.Now()
		// Wait for block i's nonce to be verified before processing
		// its state transition.
		for !nonceChecked[i] {
850 851
			r := <-nonceResults
			nonceChecked[r.index] = true
O
obscuren 已提交
852
			if !r.valid {
853 854
				block := chain[r.index]
				return r.index, &BlockNonceErr{Hash: block.Hash(), Number: block.Number(), Nonce: block.Nonce()}
O
obscuren 已提交
855
			}
O
obscuren 已提交
856
		}
O
obscuren 已提交
857

O
obscuren 已提交
858
		if BadHashes[block.Hash()] {
859
			err := BadHashError(block.Hash())
860
			reportBlock(block, err)
O
obscuren 已提交
861 862
			return i, err
		}
863 864 865
		// Stage 1 validation of the block using the chain's validator
		// interface.
		err := self.Validator().ValidateBlock(block)
O
obscuren 已提交
866 867 868 869 870
		if err != nil {
			if IsKnownBlockErr(err) {
				stats.ignored++
				continue
			}
871

O
obscuren 已提交
872 873 874 875
			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.
876 877
				max := big.NewInt(time.Now().Unix() + maxTimeFutureBlocks)
				if block.Time().Cmp(max) == 1 {
O
obscuren 已提交
878
					return i, fmt.Errorf("%v: BlockFutureErr, %v > %v", BlockFutureErr, block.Time(), max)
879
				}
O
obscuren 已提交
880

881
				self.futureBlocks.Add(block.Hash(), block)
O
obscuren 已提交
882 883 884
				stats.queued++
				continue
			}
O
obscuren 已提交
885

886 887
			if IsParentErr(err) && self.futureBlocks.Contains(block.ParentHash()) {
				self.futureBlocks.Add(block.Hash(), block)
O
obscuren 已提交
888 889
				stats.queued++
				continue
890
			}
891

892
			reportBlock(block, err)
O
obscuren 已提交
893

894 895
			return i, err
		}
896

897 898
		// Create a new statedb using the parent block and report an
		// error if it fails.
899 900 901 902 903
		switch {
		case i == 0:
			err = self.stateCache.Reset(self.GetBlock(block.ParentHash()).Root())
		default:
			err = self.stateCache.Reset(chain[i-1].Root())
904
		}
905 906
		if err != nil {
			reportBlock(block, err)
O
obscuren 已提交
907 908
			return i, err
		}
909
		// Process block using the parent state as reference point.
910
		receipts, logs, usedGas, err := self.processor.Process(block, self.stateCache, self.config.VmConfig)
911 912 913 914 915
		if err != nil {
			reportBlock(block, err)
			return i, err
		}
		// Validate the state using the default validator
916
		err = self.Validator().ValidateState(block, self.GetBlock(block.ParentHash()), self.stateCache, receipts, usedGas)
917 918 919 920 921
		if err != nil {
			reportBlock(block, err)
			return i, err
		}
		// Write state changes to database
922
		_, err = self.stateCache.Commit()
923 924 925 926 927 928 929
		if err != nil {
			return i, err
		}

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

930
		if err := WriteBlockReceipts(self.chainDb, block.Hash(), receipts); err != nil {
931
			return i, err
932
		}
O
obscuren 已提交
933 934

		txcount += len(block.Transactions())
935
		// write the block to the chain and get the status
936
		status, err := self.WriteBlock(block)
937 938 939
		if err != nil {
			return i, err
		}
940

941
		switch status {
942
		case CanonStatTy:
O
obscuren 已提交
943
			if glog.V(logger.Debug) {
944
				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 已提交
945
			}
946
			events = append(events, ChainEvent{block, block.Hash(), logs})
947 948

			// This puts transactions in a extra db for rpc
949
			if err := WriteTransactions(self.chainDb, block); err != nil {
950 951
				return i, err
			}
952
			// store the receipts
953
			if err := WriteReceipts(self.chainDb, receipts); err != nil {
954 955 956 957 958 959
				return i, err
			}
			// Write map map bloom filters
			if err := WriteMipmapBloom(self.chainDb, block.NumberU64(), receipts); err != nil {
				return i, err
			}
960
		case SideStatTy:
O
obscuren 已提交
961 962
			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 已提交
963
			}
964 965
			events = append(events, ChainSideEvent{block, logs})

966
		case SplitStatTy:
967
			events = append(events, ChainSplitEvent{block, logs})
968
		}
O
obscuren 已提交
969
		stats.processed++
O
obscuren 已提交
970 971
	}

O
obscuren 已提交
972
	if (stats.queued > 0 || stats.processed > 0 || stats.ignored > 0) && bool(glog.V(logger.Info)) {
O
obscuren 已提交
973
		tend := time.Since(tstart)
O
obscuren 已提交
974
		start, end := chain[0], chain[len(chain)-1]
975
		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 已提交
976
	}
977
	go self.postChainEvents(events, coalescedLogs)
978

979
	return 0, nil
O
obscuren 已提交
980
}
981

982 983 984
// 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
985
func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
986
	var (
987 988 989 990 991 992 993 994
		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 已提交
995 996 997 998 999 1000 1001 1002
		// 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...)
1003 1004

				deletedLogsByHash[h] = receipt.Logs
J
Jeffrey Wilcke 已提交
1005 1006
			}
		}
1007
	)
1008 1009 1010 1011

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

			collectLogs(oldBlock.Hash())
1017 1018 1019
		}
	} else {
		// reduce new chain and append new chain blocks for inserting later on
F
Felix Lange 已提交
1020
		for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = self.GetBlock(newBlock.ParentHash()) {
1021 1022
			newChain = append(newChain, newBlock)
		}
O
obscuren 已提交
1023
	}
O
obscuren 已提交
1024
	if oldBlock == nil {
1025
		return fmt.Errorf("Invalid old chain")
O
obscuren 已提交
1026 1027
	}
	if newBlock == nil {
1028
		return fmt.Errorf("Invalid new chain")
O
obscuren 已提交
1029
	}
O
obscuren 已提交
1030

1031
	numSplit := newBlock.Number()
1032 1033
	for {
		if oldBlock.Hash() == newBlock.Hash() {
1034
			commonBlock = oldBlock
1035 1036
			break
		}
1037 1038

		oldChain = append(oldChain, oldBlock)
1039
		newChain = append(newChain, newBlock)
1040
		deletedTxs = append(deletedTxs, oldBlock.Transactions()...)
J
Jeffrey Wilcke 已提交
1041
		collectLogs(oldBlock.Hash())
O
obscuren 已提交
1042 1043

		oldBlock, newBlock = self.GetBlock(oldBlock.ParentHash()), self.GetBlock(newBlock.ParentHash())
1044
		if oldBlock == nil {
1045
			return fmt.Errorf("Invalid old chain")
1046 1047
		}
		if newBlock == nil {
1048
			return fmt.Errorf("Invalid new chain")
1049
		}
1050 1051
	}

1052
	if glog.V(logger.Debug) {
1053
		commonHash := commonBlock.Hash()
1054
		glog.Infof("Chain split detected @ %x. Reorganising chain from #%v %x to %x", commonHash[:4], numSplit, oldStart.Hash().Bytes()[:4], newStart.Hash().Bytes()[:4])
1055 1056
	}

1057
	var addedTxs types.Transactions
1058
	// insert blocks. Order does not matter. Last block will be written in ImportChain itself which creates the new head properly
1059
	for _, block := range newChain {
1060
		// insert the block in the canonical way, re-writing history
1061
		self.insert(block)
1062
		// write canonical receipts and transactions
1063
		if err := WriteTransactions(self.chainDb, block); err != nil {
1064 1065 1066 1067
			return err
		}
		receipts := GetBlockReceipts(self.chainDb, block.Hash())
		// write receipts
1068
		if err := WriteReceipts(self.chainDb, receipts); err != nil {
1069 1070 1071 1072 1073 1074
			return err
		}
		// Write map map bloom filters
		if err := WriteMipmapBloom(self.chainDb, block.NumberU64(), receipts); err != nil {
			return err
		}
1075 1076 1077 1078 1079 1080 1081 1082 1083 1084
		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())
1085
	}
1086 1087
	// Must be posted in a goroutine because of the transaction pool trying
	// to acquire the chain manager lock
J
Jeffrey Wilcke 已提交
1088 1089 1090 1091
	if len(diff) > 0 {
		go self.eventMux.Post(RemovedTransactionEvent{diff})
	}
	if len(deletedLogs) > 0 {
1092
		go self.eventMux.Post(RemovedLogsEvent{deletedLogs})
J
Jeffrey Wilcke 已提交
1093
	}
1094

1095 1096 1097 1098 1099 1100 1101 1102
	if len(oldChain) > 0 {
		go func() {
			for _, block := range oldChain {
				self.eventMux.Post(ChainSideEvent{Block: block, Logs: deletedLogsByHash[block.Hash()]})
			}
		}()
	}

1103
	return nil
1104 1105
}

1106 1107
// postChainEvents iterates over the events generated by a chain insertion and
// posts them into the event mux.
1108 1109 1110
func (self *BlockChain) postChainEvents(events []interface{}, logs vm.Logs) {
	// post event logs for further processing
	self.eventMux.Post(logs)
1111 1112 1113 1114
	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.
1115
			if self.LastBlockHash() == event.Hash {
1116 1117 1118 1119 1120 1121 1122 1123
				self.eventMux.Post(ChainHeadEvent{event.Block})
			}
		}
		// Fire the insertion events individually too
		self.eventMux.Post(event)
	}
}

1124
func (self *BlockChain) update() {
O
obscuren 已提交
1125
	futureTimer := time.Tick(5 * time.Second)
1126 1127
	for {
		select {
O
obscuren 已提交
1128
		case <-futureTimer:
1129
			self.procFutureBlocks()
1130
		case <-self.quit:
1131
			return
1132 1133 1134
		}
	}
}
1135

1136
// reportBlock logs a bad block error.
1137
func reportBlock(block *types.Block, err error) {
1138 1139 1140 1141
	if glog.V(logger.Error) {
		glog.Errorf("Bad block #%v (%s)\n", block.Number(), block.Hash().Hex())
		glog.Errorf("    %v", err)
	}
F
Felix Lange 已提交
1142
}
1143 1144 1145 1146 1147 1148 1149

// 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 已提交
1150
// of the header retrieval mechanisms already need to verify nonces, as well as
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 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228
// 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)
}
1229 1230 1231

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