blockchain.go 61.5 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"
O
obscuren 已提交
26
	"sync"
O
obscuren 已提交
27
	"sync/atomic"
28
	"time"
29

O
obscuren 已提交
30
	"github.com/ethereum/go-ethereum/common"
F
Felix Lange 已提交
31
	"github.com/ethereum/go-ethereum/common/mclock"
32
	"github.com/ethereum/go-ethereum/common/prque"
33
	"github.com/ethereum/go-ethereum/consensus"
34
	"github.com/ethereum/go-ethereum/core/rawdb"
O
obscuren 已提交
35
	"github.com/ethereum/go-ethereum/core/state"
O
obscuren 已提交
36
	"github.com/ethereum/go-ethereum/core/types"
37
	"github.com/ethereum/go-ethereum/core/vm"
38
	"github.com/ethereum/go-ethereum/crypto"
39
	"github.com/ethereum/go-ethereum/ethdb"
O
obscuren 已提交
40
	"github.com/ethereum/go-ethereum/event"
41
	"github.com/ethereum/go-ethereum/log"
42
	"github.com/ethereum/go-ethereum/metrics"
43
	"github.com/ethereum/go-ethereum/params"
44
	"github.com/ethereum/go-ethereum/rlp"
45
	"github.com/ethereum/go-ethereum/trie"
O
obscuren 已提交
46
	"github.com/hashicorp/golang-lru"
O
obscuren 已提交
47 48
)

49
var (
50 51 52 53
	blockInsertTimer     = metrics.NewRegisteredTimer("chain/inserts", nil)
	blockValidationTimer = metrics.NewRegisteredTimer("chain/validation", nil)
	blockExecutionTimer  = metrics.NewRegisteredTimer("chain/execution", nil)
	blockWriteTimer      = metrics.NewRegisteredTimer("chain/write", nil)
54 55

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

O
obscuren 已提交
58
const (
59
	bodyCacheLimit      = 256
O
obscuren 已提交
60
	blockCacheLimit     = 256
61
	receiptsCacheLimit  = 32
O
wip  
obscuren 已提交
62 63
	maxFutureBlocks     = 256
	maxTimeFutureBlocks = 30
64
	badBlockLimit       = 10
65
	triesInMemory       = 128
66 67

	// BlockChainVersion ensures that an incompatible database forces a resync from scratch.
68
	BlockChainVersion uint64 = 3
O
obscuren 已提交
69
)
70

71 72 73
// CacheConfig contains the configuration values for the trie caching/pruning
// that's resident in a blockchain.
type CacheConfig struct {
74 75 76 77
	Disabled       bool          // Whether to disable trie write caching (archive node)
	TrieCleanLimit int           // Memory allowance (MB) to use for caching trie nodes in memory
	TrieDirtyLimit int           // Memory limit (MB) at which to start flushing dirty trie nodes to disk
	TrieTimeLimit  time.Duration // Time limit after which to flush the current in-memory trie to disk
78 79
}

80 81 82 83 84 85 86 87 88 89 90 91 92 93
// 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.
94
type BlockChain struct {
95 96 97 98 99 100
	chainConfig *params.ChainConfig // Chain & network configuration
	cacheConfig *CacheConfig        // Cache configuration for pruning

	db     ethdb.Database // Low level persistent database to store final content in
	triegc *prque.Prque   // Priority queue mapping block numbers to tries to gc
	gcproc time.Duration  // Accumulates canonical block processing for trie dumping
101

102 103 104 105 106 107 108 109
	hc            *HeaderChain
	rmLogsFeed    event.Feed
	chainFeed     event.Feed
	chainSideFeed event.Feed
	chainHeadFeed event.Feed
	logsFeed      event.Feed
	scope         event.SubscriptionScope
	genesisBlock  *types.Block
110

111 112
	chainmu sync.RWMutex // blockchain insertion lock
	procmu  sync.RWMutex // block processor lock
113

114
	checkpoint       int          // checkpoint counts towards the new checkpoint
115 116
	currentBlock     atomic.Value // Current head of the block chain
	currentFastBlock atomic.Value // Current head of the fast-sync chain (may be above the block chain!)
O
obscuren 已提交
117

118 119 120 121 122 123
	stateCache    state.Database // 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
	receiptsCache *lru.Cache     // Cache for the most recent receipts per block
	blockCache    *lru.Cache     // Cache for the most recent entire blocks
	futureBlocks  *lru.Cache     // future blocks are blocks added for later processing
124

125
	quit    chan struct{} // blockchain quit channel
L
Leif Jurvetson 已提交
126
	running int32         // running must be called atomically
O
obscuren 已提交
127
	// procInterrupt must be atomically called
128 129
	procInterrupt int32          // interrupt signaler for block processing
	wg            sync.WaitGroup // chain processing wait group for shutting down
130

131
	engine    consensus.Engine
132 133
	processor Processor // block processor interface
	validator Validator // block and state validator interface
134
	vmConfig  vm.Config
135

136 137
	badBlocks      *lru.Cache              // Bad block cache
	shouldPreserve func(*types.Block) bool // Function used to determine whether should preserve the given block.
O
obscuren 已提交
138
}
O
obscuren 已提交
139

140
// NewBlockChain returns a fully initialised block chain using information
J
Justin 已提交
141
// available in the database. It initialises the default Ethereum Validator and
142
// Processor.
143
func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config, shouldPreserve func(block *types.Block) bool) (*BlockChain, error) {
144 145
	if cacheConfig == nil {
		cacheConfig = &CacheConfig{
146 147 148
			TrieCleanLimit: 256,
			TrieDirtyLimit: 256,
			TrieTimeLimit:  5 * time.Minute,
149 150
		}
	}
151 152
	bodyCache, _ := lru.New(bodyCacheLimit)
	bodyRLPCache, _ := lru.New(bodyCacheLimit)
153
	receiptsCache, _ := lru.New(receiptsCacheLimit)
154 155
	blockCache, _ := lru.New(blockCacheLimit)
	futureBlocks, _ := lru.New(maxFutureBlocks)
156
	badBlocks, _ := lru.New(badBlockLimit)
157

158
	bc := &BlockChain{
159 160 161 162
		chainConfig:    chainConfig,
		cacheConfig:    cacheConfig,
		db:             db,
		triegc:         prque.New(nil),
163
		stateCache:     state.NewDatabaseWithCache(db, cacheConfig.TrieCleanLimit),
164 165 166 167
		quit:           make(chan struct{}),
		shouldPreserve: shouldPreserve,
		bodyCache:      bodyCache,
		bodyRLPCache:   bodyRLPCache,
168
		receiptsCache:  receiptsCache,
169 170 171 172 173
		blockCache:     blockCache,
		futureBlocks:   futureBlocks,
		engine:         engine,
		vmConfig:       vmConfig,
		badBlocks:      badBlocks,
O
obscuren 已提交
174
	}
175 176
	bc.SetValidator(NewBlockValidator(chainConfig, bc, engine))
	bc.SetProcessor(NewStateProcessor(chainConfig, bc, engine))
177 178

	var err error
179
	bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.getProcInterrupt)
180 181 182
	if err != nil {
		return nil, err
	}
183 184
	bc.genesisBlock = bc.GetBlockByNumber(0)
	if bc.genesisBlock == nil {
185
		return nil, ErrNoGenesis
186
	}
187
	if err := bc.loadLastState(); err != nil {
188
		return nil, err
O
obscuren 已提交
189
	}
190
	// Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain
F
Felix Lange 已提交
191
	for hash := range BadHashes {
192
		if header := bc.GetHeaderByHash(hash); header != nil {
193 194 195 196
			// get the canonical block corresponding to the offending header's number
			headerByNumber := bc.GetHeaderByNumber(header.Number.Uint64())
			// make sure the headerByNumber (if present) is in our current canonical chain
			if headerByNumber != nil && headerByNumber.Hash() == header.Hash() {
197
				log.Error("Found bad hash, rewinding chain", "number", header.Number, "hash", header.ParentHash)
198
				bc.SetHead(header.Number.Uint64() - 1)
199
				log.Error("Chain rewind was successful, resuming normal operation")
200
			}
201 202
		}
	}
203
	// Take ownership of this particular state
204
	go bc.update()
O
obscuren 已提交
205
	return bc, nil
206 207
}

C
changhong 已提交
208 209
func (bc *BlockChain) getProcInterrupt() bool {
	return atomic.LoadInt32(&bc.procInterrupt) == 1
210 211
}

212 213 214 215 216
// GetVMConfig returns the block chain VM config.
func (bc *BlockChain) GetVMConfig() *vm.Config {
	return &bc.vmConfig
}

217 218
// loadLastState loads the last known chain state from the database. This method
// assumes that the chain manager mutex is held.
C
changhong 已提交
219
func (bc *BlockChain) loadLastState() error {
220
	// Restore the last known head block
221
	head := rawdb.ReadHeadBlockHash(bc.db)
222 223
	if head == (common.Hash{}) {
		// Corrupt or empty database, init from scratch
224
		log.Warn("Empty database, resetting chain")
C
changhong 已提交
225
		return bc.Reset()
226 227
	}
	// Make sure the entire head block is available
C
changhong 已提交
228
	currentBlock := bc.GetBlockByHash(head)
229 230 231
	if currentBlock == nil {
		// Corrupt or empty database, init from scratch
		log.Warn("Head block missing, resetting chain", "hash", head)
C
changhong 已提交
232
		return bc.Reset()
233 234
	}
	// Make sure the state associated with the block is available
235
	if _, err := state.New(currentBlock.Root(), bc.stateCache); err != nil {
236
		// Dangling block without a state associated, init from scratch
237 238 239 240
		log.Warn("Head state missing, repairing chain", "number", currentBlock.Number(), "hash", currentBlock.Hash())
		if err := bc.repair(&currentBlock); err != nil {
			return err
		}
241
	}
242
	// Everything seems to be fine, set as the head block
243
	bc.currentBlock.Store(currentBlock)
244

245
	// Restore the last known head header
246
	currentHeader := currentBlock.Header()
247
	if head := rawdb.ReadHeadHeaderHash(bc.db); head != (common.Hash{}) {
C
changhong 已提交
248
		if header := bc.GetHeaderByHash(head); header != nil {
249
			currentHeader = header
250 251
		}
	}
C
changhong 已提交
252
	bc.hc.SetCurrentHeader(currentHeader)
253

254
	// Restore the last known head fast block
255
	bc.currentFastBlock.Store(currentBlock)
256
	if head := rawdb.ReadHeadFastBlockHash(bc.db); head != (common.Hash{}) {
C
changhong 已提交
257
		if block := bc.GetBlockByHash(head); block != nil {
258
			bc.currentFastBlock.Store(block)
259 260
		}
	}
261 262

	// Issue a status log for the user
263 264
	currentFastBlock := bc.CurrentFastBlock()

C
changhong 已提交
265
	headerTd := bc.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64())
266 267
	blockTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
	fastTd := bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64())
268

269 270 271
	log.Info("Loaded most recent local header", "number", currentHeader.Number, "hash", currentHeader.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(currentHeader.Time.Int64(), 0)))
	log.Info("Loaded most recent local full block", "number", currentBlock.Number(), "hash", currentBlock.Hash(), "td", blockTd, "age", common.PrettyAge(time.Unix(currentBlock.Time().Int64(), 0)))
	log.Info("Loaded most recent local fast block", "number", currentFastBlock.Number(), "hash", currentFastBlock.Hash(), "td", fastTd, "age", common.PrettyAge(time.Unix(currentFastBlock.Time().Int64(), 0)))
272 273 274 275

	return nil
}

276 277 278 279
// 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).
280 281 282
func (bc *BlockChain) SetHead(head uint64) error {
	log.Warn("Rewinding blockchain", "target", head)

283 284
	bc.chainmu.Lock()
	defer bc.chainmu.Unlock()
285

286
	// Rewind the header chain, deleting all block bodies until then
287 288
	delFn := func(db rawdb.DatabaseDeleter, hash common.Hash, num uint64) {
		rawdb.DeleteBody(db, hash, num)
289
	}
290
	bc.hc.SetHead(head, delFn)
291
	currentHeader := bc.hc.CurrentHeader()
292

293
	// Clear out any stale content from the caches
294 295
	bc.bodyCache.Purge()
	bc.bodyRLPCache.Purge()
296
	bc.receiptsCache.Purge()
297 298
	bc.blockCache.Purge()
	bc.futureBlocks.Purge()
299

300
	// Rewind the block chain, ensuring we don't end up with a stateless head block
301 302
	if currentBlock := bc.CurrentBlock(); currentBlock != nil && currentHeader.Number.Uint64() < currentBlock.NumberU64() {
		bc.currentBlock.Store(bc.GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64()))
303
	}
304 305
	if currentBlock := bc.CurrentBlock(); currentBlock != nil {
		if _, err := state.New(currentBlock.Root(), bc.stateCache); err != nil {
306
			// Rewound state missing, rolled back to before pivot, reset to genesis
307
			bc.currentBlock.Store(bc.genesisBlock)
308 309 310
		}
	}
	// Rewind the fast block in a simpleton way to the target head
311 312
	if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && currentHeader.Number.Uint64() < currentFastBlock.NumberU64() {
		bc.currentFastBlock.Store(bc.GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64()))
313
	}
314
	// If either blocks reached nil, reset to the genesis state
315 316
	if currentBlock := bc.CurrentBlock(); currentBlock == nil {
		bc.currentBlock.Store(bc.genesisBlock)
317
	}
318 319
	if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock == nil {
		bc.currentFastBlock.Store(bc.genesisBlock)
320
	}
321 322
	currentBlock := bc.CurrentBlock()
	currentFastBlock := bc.CurrentFastBlock()
323 324 325 326

	rawdb.WriteHeadBlockHash(bc.db, currentBlock.Hash())
	rawdb.WriteHeadFastBlockHash(bc.db, currentFastBlock.Hash())

327
	return bc.loadLastState()
328 329
}

330 331
// FastSyncCommitHead sets the current head block to the one defined by the hash
// irrelevant what the chain contents were prior.
C
changhong 已提交
332
func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error {
333
	// Make sure that both the block as well at its state trie exists
C
changhong 已提交
334
	block := bc.GetBlockByHash(hash)
335 336 337
	if block == nil {
		return fmt.Errorf("non existent block [%x…]", hash[:4])
	}
338
	if _, err := trie.NewSecure(block.Root(), bc.stateCache.TrieDB(), 0); err != nil {
339 340 341
		return err
	}
	// If all checks out, manually set the head block
342
	bc.chainmu.Lock()
343
	bc.currentBlock.Store(block)
344
	bc.chainmu.Unlock()
345

346
	log.Info("Committed new head block", "number", block.Number(), "hash", hash)
347 348 349
	return nil
}

350
// GasLimit returns the gas limit of the current HEAD block.
351
func (bc *BlockChain) GasLimit() uint64 {
352
	return bc.CurrentBlock().GasLimit()
O
obscuren 已提交
353 354
}

355
// CurrentBlock retrieves the current head block of the canonical chain. The
356
// block is retrieved from the blockchain's internal cache.
C
changhong 已提交
357
func (bc *BlockChain) CurrentBlock() *types.Block {
358
	return bc.currentBlock.Load().(*types.Block)
O
obscuren 已提交
359 360
}

361
// CurrentFastBlock retrieves the current fast-sync head block of the canonical
362
// chain. The block is retrieved from the blockchain's internal cache.
C
changhong 已提交
363
func (bc *BlockChain) CurrentFastBlock() *types.Block {
364
	return bc.currentFastBlock.Load().(*types.Block)
365 366
}

367
// SetProcessor sets the processor required for making state modifications.
C
changhong 已提交
368 369 370 371
func (bc *BlockChain) SetProcessor(processor Processor) {
	bc.procmu.Lock()
	defer bc.procmu.Unlock()
	bc.processor = processor
372 373 374
}

// SetValidator sets the validator which is used to validate incoming blocks.
C
changhong 已提交
375 376 377 378
func (bc *BlockChain) SetValidator(validator Validator) {
	bc.procmu.Lock()
	defer bc.procmu.Unlock()
	bc.validator = validator
379 380
}

381
// Validator returns the current validator.
C
changhong 已提交
382 383 384 385
func (bc *BlockChain) Validator() Validator {
	bc.procmu.RLock()
	defer bc.procmu.RUnlock()
	return bc.validator
386 387 388
}

// Processor returns the current processor.
C
changhong 已提交
389 390 391 392
func (bc *BlockChain) Processor() Processor {
	bc.procmu.RLock()
	defer bc.procmu.RUnlock()
	return bc.processor
393 394 395
}

// State returns a new mutable state based on the current HEAD block.
C
changhong 已提交
396 397
func (bc *BlockChain) State() (*state.StateDB, error) {
	return bc.StateAt(bc.CurrentBlock().Root())
398 399 400
}

// StateAt returns a new mutable state based on a particular point in time.
C
changhong 已提交
401
func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
402
	return state.New(root, bc.stateCache)
O
obscuren 已提交
403 404
}

405 406 407 408 409
// StateCache returns the caching database underpinning the blockchain instance.
func (bc *BlockChain) StateCache() state.Database {
	return bc.stateCache
}

410
// Reset purges the entire blockchain, restoring it to its genesis state.
411 412
func (bc *BlockChain) Reset() error {
	return bc.ResetWithGenesisBlock(bc.genesisBlock)
413 414
}

415 416
// ResetWithGenesisBlock purges the entire blockchain, restoring it to the
// specified genesis state.
417
func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error {
418
	// Dump the entire block chain and purge the caches
419 420 421
	if err := bc.SetHead(0); err != nil {
		return err
	}
422 423
	bc.chainmu.Lock()
	defer bc.chainmu.Unlock()
424

425
	// Prepare the genesis block and reinitialise the chain
426
	if err := bc.hc.WriteTd(genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()); err != nil {
427
		log.Crit("Failed to write genesis block TD", "err", err)
428
	}
429 430
	rawdb.WriteBlock(bc.db, genesis)

431
	bc.genesisBlock = genesis
432
	bc.insert(bc.genesisBlock)
433
	bc.currentBlock.Store(bc.genesisBlock)
434 435
	bc.hc.SetGenesis(bc.genesisBlock.Header())
	bc.hc.SetCurrentHeader(bc.genesisBlock.Header())
436
	bc.currentFastBlock.Store(bc.genesisBlock)
437 438

	return nil
439 440
}

441 442 443 444 445 446 447 448 449 450 451 452 453 454
// repair tries to repair the current blockchain by rolling back the current block
// until one with associated state is found. This is needed to fix incomplete db
// writes caused either by crashes/power outages, or simply non-committed tries.
//
// This method only rolls back the current block. The current header and current
// fast block are left intact.
func (bc *BlockChain) repair(head **types.Block) error {
	for {
		// Abort if we've rewound to a head block that does have associated state
		if _, err := state.New((*head).Root(), bc.stateCache); err == nil {
			log.Info("Rewound blockchain to past state", "number", (*head).Number(), "hash", (*head).Hash())
			return nil
		}
		// Otherwise rewind one block and recheck state availability there
455 456 457 458 459
		block := bc.GetBlock((*head).ParentHash(), (*head).NumberU64()-1)
		if block == nil {
			return fmt.Errorf("missing block %d [%x]", (*head).NumberU64()-1, (*head).ParentHash())
		}
		(*head) = block
460 461 462
	}
}

463
// Export writes the active chain to the given writer.
C
changhong 已提交
464
func (bc *BlockChain) Export(w io.Writer) error {
465
	return bc.ExportN(w, uint64(0), bc.CurrentBlock().NumberU64())
T
Taylor Gerring 已提交
466 467 468
}

// ExportN writes a subset of the active chain to the given writer.
C
changhong 已提交
469
func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error {
470 471
	bc.chainmu.RLock()
	defer bc.chainmu.RUnlock()
O
obscuren 已提交
472

T
Taylor Gerring 已提交
473 474 475
	if first > last {
		return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last)
	}
476
	log.Info("Exporting batch of blocks", "count", last-first+1)
477

478
	start, reported := time.Now(), time.Now()
T
Taylor Gerring 已提交
479
	for nr := first; nr <= last; nr++ {
C
changhong 已提交
480
		block := bc.GetBlockByNumber(nr)
481 482 483 484
		if block == nil {
			return fmt.Errorf("export failed on #%d: not found", nr)
		}
		if err := block.EncodeRLP(w); err != nil {
485 486
			return err
		}
487 488 489 490
		if time.Since(reported) >= statsReportLimit {
			log.Info("Exporting blocks", "exported", block.NumberU64()-first, "elapsed", common.PrettyDuration(time.Since(start)))
			reported = time.Now()
		}
O
obscuren 已提交
491
	}
492
	return nil
O
obscuren 已提交
493 494
}

495 496
// 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
497 498
// 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.
499 500
//
// Note, this function assumes that the `mu` mutex is held!
501
func (bc *BlockChain) insert(block *types.Block) {
502
	// If the block is on a side chain or an unknown one, force other heads onto it too
503
	updateHeads := rawdb.ReadCanonicalHash(bc.db, block.NumberU64()) != block.Hash()
504

505
	// Add the block to the canonical chain number scheme and mark as the head
506 507 508
	rawdb.WriteCanonicalHash(bc.db, block.Hash(), block.NumberU64())
	rawdb.WriteHeadBlockHash(bc.db, block.Hash())

509
	bc.currentBlock.Store(block)
510

511
	// If the block is better than our head or is on a different chain, force update heads
512
	if updateHeads {
513
		bc.hc.SetCurrentHeader(block.Header())
514
		rawdb.WriteHeadFastBlockHash(bc.db, block.Hash())
515

516
		bc.currentFastBlock.Store(block)
517
	}
518 519
}

520
// Genesis retrieves the chain's genesis block.
521
func (bc *BlockChain) Genesis() *types.Block {
O
obscuren 已提交
522 523 524
	return bc.genesisBlock
}

525 526
// GetBody retrieves a block body (transactions and uncles) from the database by
// hash, caching it if found.
C
changhong 已提交
527
func (bc *BlockChain) GetBody(hash common.Hash) *types.Body {
528
	// Short circuit if the body's already in the cache, retrieve otherwise
C
changhong 已提交
529
	if cached, ok := bc.bodyCache.Get(hash); ok {
530 531
		body := cached.(*types.Body)
		return body
O
obscuren 已提交
532
	}
533 534 535 536 537
	number := bc.hc.GetBlockNumber(hash)
	if number == nil {
		return nil
	}
	body := rawdb.ReadBody(bc.db, hash, *number)
538 539
	if body == nil {
		return nil
540 541
	}
	// Cache the found body for next time and return
C
changhong 已提交
542
	bc.bodyCache.Add(hash, body)
543
	return body
544
}
O
obscuren 已提交
545

546 547
// GetBodyRLP retrieves a block body in RLP encoding from the database by hash,
// caching it if found.
C
changhong 已提交
548
func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
549
	// Short circuit if the body's already in the cache, retrieve otherwise
C
changhong 已提交
550
	if cached, ok := bc.bodyRLPCache.Get(hash); ok {
551
		return cached.(rlp.RawValue)
552
	}
553 554 555 556 557
	number := bc.hc.GetBlockNumber(hash)
	if number == nil {
		return nil
	}
	body := rawdb.ReadBodyRLP(bc.db, hash, *number)
558
	if len(body) == 0 {
559
		return nil
O
obscuren 已提交
560
	}
561
	// Cache the found body for next time and return
C
changhong 已提交
562
	bc.bodyRLPCache.Add(hash, body)
563 564
	return body
}
O
obscuren 已提交
565

566 567 568 569 570
// HasBlock checks if a block is fully present in the database or not.
func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool {
	if bc.blockCache.Contains(hash) {
		return true
	}
571
	return rawdb.HasBody(bc.db, hash, number)
O
obscuren 已提交
572 573
}

574 575 576 577 578 579 580 581 582 583 584
// HasFastBlock checks if a fast block is fully present in the database or not.
func (bc *BlockChain) HasFastBlock(hash common.Hash, number uint64) bool {
	if !bc.HasBlock(hash, number) {
		return false
	}
	if bc.receiptsCache.Contains(hash) {
		return true
	}
	return rawdb.HasReceipts(bc.db, hash, number)
}

585 586 587 588 589 590
// HasState checks if state trie is fully present in the database or not.
func (bc *BlockChain) HasState(hash common.Hash) bool {
	_, err := bc.stateCache.OpenTrie(hash)
	return err == nil
}

591 592
// HasBlockAndState checks if a block and associated state trie is fully present
// in the database or not, caching it if present.
593
func (bc *BlockChain) HasBlockAndState(hash common.Hash, number uint64) bool {
594
	// Check first that the block itself is known
595
	block := bc.GetBlock(hash, number)
596 597 598
	if block == nil {
		return false
	}
599
	return bc.HasState(block.Root())
600 601
}

602 603
// GetBlock retrieves a block from the database by hash and number,
// caching it if found.
C
changhong 已提交
604
func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
605
	// Short circuit if the block's already in the cache, retrieve otherwise
C
changhong 已提交
606
	if block, ok := bc.blockCache.Get(hash); ok {
607 608
		return block.(*types.Block)
	}
609
	block := rawdb.ReadBlock(bc.db, hash, number)
610
	if block == nil {
O
obscuren 已提交
611 612
		return nil
	}
613
	// Cache the found block for next time and return
C
changhong 已提交
614
	bc.blockCache.Add(block.Hash(), block)
615
	return block
O
obscuren 已提交
616 617
}

618
// GetBlockByHash retrieves a block from the database by hash, caching it if found.
C
changhong 已提交
619
func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
620 621 622 623 624
	number := bc.hc.GetBlockNumber(hash)
	if number == nil {
		return nil
	}
	return bc.GetBlock(hash, *number)
625 626
}

627 628
// GetBlockByNumber retrieves a block from the database by number, caching it
// (associated with its hash) if found.
C
changhong 已提交
629
func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block {
630
	hash := rawdb.ReadCanonicalHash(bc.db, number)
631 632 633
	if hash == (common.Hash{}) {
		return nil
	}
C
changhong 已提交
634
	return bc.GetBlock(hash, number)
635
}
636

637 638
// GetReceiptsByHash retrieves the receipts for all transactions in a given block.
func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
639 640 641
	if receipts, ok := bc.receiptsCache.Get(hash); ok {
		return receipts.(types.Receipts)
	}
642 643 644 645
	number := rawdb.ReadHeaderNumber(bc.db, hash)
	if number == nil {
		return nil
	}
646 647 648
	receipts := rawdb.ReadReceipts(bc.db, hash, *number)
	bc.receiptsCache.Add(hash, receipts)
	return receipts
649 650
}

F
Felix Lange 已提交
651
// GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
C
changhong 已提交
652 653 654
// [deprecated by eth/62]
func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
	number := bc.hc.GetBlockNumber(hash)
655 656 657
	if number == nil {
		return nil
	}
F
Felix Lange 已提交
658
	for i := 0; i < n; i++ {
659
		block := bc.GetBlock(hash, *number)
F
Felix Lange 已提交
660 661 662 663 664
		if block == nil {
			break
		}
		blocks = append(blocks, block)
		hash = block.ParentHash()
665
		*number--
F
Felix Lange 已提交
666 667 668 669
	}
	return
}

670 671
// GetUnclesInChain retrieves all the uncles from a given block backwards until
// a specific distance is reached.
C
changhong 已提交
672
func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header {
673
	uncles := []*types.Header{}
674 675
	for i := 0; block != nil && i < length; i++ {
		uncles = append(uncles, block.Uncles()...)
C
changhong 已提交
676
		block = bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
677
	}
678
	return uncles
O
obscuren 已提交
679
}
O
obscuren 已提交
680

681 682 683 684 685 686
// TrieNode retrieves a blob of data associated with a trie node (or code hash)
// either from ephemeral in-memory cache, or from persistent storage.
func (bc *BlockChain) TrieNode(hash common.Hash) ([]byte, error) {
	return bc.stateCache.TrieDB().Node(hash)
}

687 688
// Stop stops the blockchain service. If any imports are currently in progress
// it will abort them using the procInterrupt.
689
func (bc *BlockChain) Stop() {
690 691 692
	if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) {
		return
	}
693 694
	// Unsubscribe all subscriptions registered from blockchain
	bc.scope.Close()
695
	close(bc.quit)
O
obscuren 已提交
696
	atomic.StoreInt32(&bc.procInterrupt, 1)
697 698

	bc.wg.Wait()
699 700

	// Ensure the state of a recent block is also stored to disk before exiting.
701 702 703 704
	// We're writing three different states to catch different restart scenarios:
	//  - HEAD:     So we don't need to reprocess any blocks in the general case
	//  - HEAD-1:   So we don't do large reorgs if our HEAD becomes an uncle
	//  - HEAD-127: So we have a hard limit on the number of blocks reexecuted
705 706 707
	if !bc.cacheConfig.Disabled {
		triedb := bc.stateCache.TrieDB()

708 709 710 711 712 713 714 715
		for _, offset := range []uint64{0, 1, triesInMemory - 1} {
			if number := bc.CurrentBlock().NumberU64(); number > offset {
				recent := bc.GetBlockByNumber(number - offset)

				log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root())
				if err := triedb.Commit(recent.Root(), true); err != nil {
					log.Error("Failed to commit recent state trie", "err", err)
				}
716 717 718
			}
		}
		for !bc.triegc.Empty() {
719
			triedb.Dereference(bc.triegc.PopItem().(common.Hash))
720
		}
721
		if size, _ := triedb.Size(); size != 0 {
722 723 724
			log.Error("Dangling trie nodes after full cleanup")
		}
	}
725
	log.Info("Blockchain manager stopped")
726 727
}

C
changhong 已提交
728 729 730 731
func (bc *BlockChain) procFutureBlocks() {
	blocks := make([]*types.Block, 0, bc.futureBlocks.Len())
	for _, hash := range bc.futureBlocks.Keys() {
		if block, exist := bc.futureBlocks.Peek(hash); exist {
732 733
			blocks = append(blocks, block.(*types.Block))
		}
734
	}
735 736
	if len(blocks) > 0 {
		types.BlockBy(types.Number).Sort(blocks)
737 738 739

		// Insert one by one as chain insertion needs contiguous ancestry between blocks
		for i := range blocks {
C
changhong 已提交
740
			bc.InsertChain(blocks[i : i+1])
741
		}
742
	}
743 744
}

C
changhong 已提交
745
// WriteStatus status of write
746
type WriteStatus byte
747 748

const (
749
	NonStatTy WriteStatus = iota
750 751
	CanonStatTy
	SideStatTy
752 753
)

754 755
// Rollback is designed to remove a chain of links from the database that aren't
// certain enough to be valid.
C
changhong 已提交
756
func (bc *BlockChain) Rollback(chain []common.Hash) {
757 758
	bc.chainmu.Lock()
	defer bc.chainmu.Unlock()
759

760 761 762
	for i := len(chain) - 1; i >= 0; i-- {
		hash := chain[i]

C
changhong 已提交
763
		currentHeader := bc.hc.CurrentHeader()
764
		if currentHeader.Hash() == hash {
C
changhong 已提交
765
			bc.hc.SetCurrentHeader(bc.GetHeader(currentHeader.ParentHash, currentHeader.Number.Uint64()-1))
766
		}
767 768 769
		if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock.Hash() == hash {
			newFastBlock := bc.GetBlock(currentFastBlock.ParentHash(), currentFastBlock.NumberU64()-1)
			bc.currentFastBlock.Store(newFastBlock)
770
			rawdb.WriteHeadFastBlockHash(bc.db, newFastBlock.Hash())
771
		}
772 773 774
		if currentBlock := bc.CurrentBlock(); currentBlock.Hash() == hash {
			newBlock := bc.GetBlock(currentBlock.ParentHash(), currentBlock.NumberU64()-1)
			bc.currentBlock.Store(newBlock)
775
			rawdb.WriteHeadBlockHash(bc.db, newBlock.Hash())
776 777 778 779
		}
	}
}

780
// SetReceiptsData computes all the non-consensus fields of the receipts
781
func SetReceiptsData(config *params.ChainConfig, block *types.Block, receipts types.Receipts) error {
J
Jeffrey Wilcke 已提交
782 783
	signer := types.MakeSigner(config, block.Number())

784
	transactions, logIndex := block.Transactions(), uint(0)
785 786 787
	if len(transactions) != len(receipts) {
		return errors.New("transaction and receipt count mismatch")
	}
788 789 790 791 792 793

	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
794 795 796 797
		if transactions[j].To() == nil {
			// Deriving the signer is expensive, only do if it's actually needed
			from, _ := types.Sender(signer, transactions[j])
			receipts[j].ContractAddress = crypto.CreateAddress(from, transactions[j].Nonce())
798 799 800
		}
		// The used gas can be calculated based on previous receipts
		if j == 0 {
801
			receipts[j].GasUsed = receipts[j].CumulativeGasUsed
802
		} else {
803
			receipts[j].GasUsed = receipts[j].CumulativeGasUsed - receipts[j-1].CumulativeGasUsed
804 805 806 807 808 809 810 811 812 813 814
		}
		// 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++
		}
	}
815
	return nil
816 817
}

818 819
// InsertReceiptChain attempts to complete an already existing header chain with
// transaction and receipt data.
C
changhong 已提交
820
func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) {
821 822 823
	bc.wg.Add(1)
	defer bc.wg.Done()

824 825 826
	// Do a sanity check that the provided chain is actually ordered and linked
	for i := 1; i < len(blockChain); i++ {
		if blockChain[i].NumberU64() != blockChain[i-1].NumberU64()+1 || blockChain[i].ParentHash() != blockChain[i-1].Hash() {
827 828 829 830
			log.Error("Non contiguous receipt insert", "number", blockChain[i].Number(), "hash", blockChain[i].Hash(), "parent", blockChain[i].ParentHash(),
				"prevnumber", blockChain[i-1].Number(), "prevhash", blockChain[i-1].Hash())
			return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, blockChain[i-1].NumberU64(),
				blockChain[i-1].Hash().Bytes()[:4], i, blockChain[i].NumberU64(), blockChain[i].Hash().Bytes()[:4], blockChain[i].ParentHash().Bytes()[:4])
831 832
		}
	}
833

834 835 836 837
	var (
		stats = struct{ processed, ignored int32 }{}
		start = time.Now()
		bytes = 0
838
		batch = bc.db.NewBatch()
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855
	)
	for i, block := range blockChain {
		receipts := receiptChain[i]
		// Short circuit insertion if shutting down or processing failed
		if atomic.LoadInt32(&bc.procInterrupt) == 1 {
			return 0, nil
		}
		// Short circuit if the owner header is unknown
		if !bc.HasHeader(block.Hash(), block.NumberU64()) {
			return i, fmt.Errorf("containing header #%d [%x…] unknown", block.Number(), block.Hash().Bytes()[:4])
		}
		// Skip if the entire data is already known
		if bc.HasBlock(block.Hash(), block.NumberU64()) {
			stats.ignored++
			continue
		}
		// Compute all the non-consensus fields of the receipts
856 857 858
		if err := SetReceiptsData(bc.chainConfig, block, receipts); err != nil {
			return i, fmt.Errorf("failed to set receipts data: %v", err)
		}
859
		// Write all the data out into the database
860 861 862 863
		rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body())
		rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receipts)
		rawdb.WriteTxLookupEntries(batch, block)

864
		stats.processed++
865

866 867 868
		if batch.ValueSize() >= ethdb.IdealBatchSize {
			if err := batch.Write(); err != nil {
				return 0, err
869
			}
870
			bytes += batch.ValueSize()
871
			batch.Reset()
872
		}
873
	}
874 875 876 877
	if batch.ValueSize() > 0 {
		bytes += batch.ValueSize()
		if err := batch.Write(); err != nil {
			return 0, err
878 879
		}
	}
880

881
	// Update the head fast sync block if better
882
	bc.chainmu.Lock()
883
	head := blockChain[len(blockChain)-1]
C
changhong 已提交
884
	if td := bc.GetTd(head.Hash(), head.NumberU64()); td != nil { // Rewind may have occurred, skip in that case
885 886
		currentFastBlock := bc.CurrentFastBlock()
		if bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()).Cmp(td) < 0 {
887
			rawdb.WriteHeadFastBlockHash(bc.db, head.Hash())
888
			bc.currentFastBlock.Store(head)
889 890
		}
	}
891
	bc.chainmu.Unlock()
892

893 894 895
	context := []interface{}{
		"count", stats.processed, "elapsed", common.PrettyDuration(time.Since(start)),
		"number", head.Number(), "hash", head.Hash(), "age", common.PrettyAge(time.Unix(head.Time().Int64(), 0)),
896
		"size", common.StorageSize(bytes),
897 898 899 900 901 902
	}
	if stats.ignored > 0 {
		context = append(context, []interface{}{"ignored", stats.ignored}...)
	}
	log.Info("Imported new block receipts", context...)

903 904 905
	return 0, nil
}

906 907 908 909 910 911 912 913 914 915 916 917
var lastWrite uint64

// WriteBlockWithoutState writes only the block and its metadata to the database,
// but does not write any state. This is used to construct competing side forks
// up to the point where they exceed the canonical total difficulty.
func (bc *BlockChain) WriteBlockWithoutState(block *types.Block, td *big.Int) (err error) {
	bc.wg.Add(1)
	defer bc.wg.Done()

	if err := bc.hc.WriteTd(block.Hash(), block.NumberU64(), td); err != nil {
		return err
	}
918 919
	rawdb.WriteBlock(bc.db, block)

920 921 922 923 924
	return nil
}

// WriteBlockWithState writes the block and all associated state to the database.
func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB) (status WriteStatus, err error) {
925 926 927 928 929 930 931 932 933
	bc.chainmu.Lock()
	defer bc.chainmu.Unlock()

	return bc.writeBlockWithState(block, receipts, state)
}

// writeBlockWithState writes the block and all associated state to the database,
// but is expects the chain mutex to be held.
func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB) (status WriteStatus, err error) {
C
changhong 已提交
934 935
	bc.wg.Add(1)
	defer bc.wg.Done()
936

937
	// Calculate the total difficulty of the block
C
changhong 已提交
938
	ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1)
939
	if ptd == nil {
940
		return NonStatTy, consensus.ErrUnknownAncestor
941
	}
942
	// Make sure no inconsistent state is leaked during insertion
943 944
	currentBlock := bc.CurrentBlock()
	localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
945 946
	externTd := new(big.Int).Add(block.Difficulty(), ptd)

947
	// Irrelevant of the canonical status, write the block itself to the database
C
changhong 已提交
948
	if err := bc.hc.WriteTd(block.Hash(), block.NumberU64(), externTd); err != nil {
949
		return NonStatTy, err
950
	}
951
	rawdb.WriteBlock(bc.db, block)
952

953 954
	root, err := state.Commit(bc.chainConfig.IsEIP158(block.Number()))
	if err != nil {
955 956
		return NonStatTy, err
	}
957 958 959 960 961 962 963 964 965 966
	triedb := bc.stateCache.TrieDB()

	// If we're running an archive node, always flush
	if bc.cacheConfig.Disabled {
		if err := triedb.Commit(root, false); err != nil {
			return NonStatTy, err
		}
	} else {
		// Full but not archive node, do proper garbage collection
		triedb.Reference(root, common.Hash{}) // metadata reference to keep trie alive
967
		bc.triegc.Push(root, -int64(block.NumberU64()))
968 969

		if current := block.NumberU64(); current > triesInMemory {
970 971 972
			// If we exceeded our memory allowance, flush matured singleton nodes to disk
			var (
				nodes, imgs = triedb.Size()
973
				limit       = common.StorageSize(bc.cacheConfig.TrieDirtyLimit) * 1024 * 1024
974 975 976 977
			)
			if nodes > limit || imgs > 4*1024*1024 {
				triedb.Cap(limit - ethdb.IdealBatchSize)
			}
978 979 980 981
			// Find the next state trie we need to commit
			header := bc.GetHeaderByNumber(current - triesInMemory)
			chosen := header.Number.Uint64()

982 983
			// If we exceeded out time allowance, flush an entire trie to disk
			if bc.gcproc > bc.cacheConfig.TrieTimeLimit {
984 985
				// If we're exceeding limits but haven't reached a large enough memory gap,
				// warn the user that the system is becoming unstable.
986 987
				if chosen < lastWrite+triesInMemory && bc.gcproc >= 2*bc.cacheConfig.TrieTimeLimit {
					log.Info("State in memory for too long, committing", "time", bc.gcproc, "allowance", bc.cacheConfig.TrieTimeLimit, "optimum", float64(chosen-lastWrite)/triesInMemory)
988
				}
989 990 991 992
				// Flush an entire trie and restart the counters
				triedb.Commit(header.Root, true)
				lastWrite = chosen
				bc.gcproc = 0
993 994 995 996 997 998 999 1000
			}
			// Garbage collect anything below our required write retention
			for !bc.triegc.Empty() {
				root, number := bc.triegc.Pop()
				if uint64(-number) > chosen {
					bc.triegc.Push(root, number)
					break
				}
1001
				triedb.Dereference(root.(common.Hash))
1002 1003 1004
			}
		}
	}
1005 1006 1007

	// Write other block data using a batch.
	batch := bc.db.NewBatch()
1008 1009
	rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receipts)

1010
	// If the total difficulty is higher than our known, add it to the canonical chain
1011 1012
	// Second clause in the if statement reduces the vulnerability to selfish mining.
	// Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf
1013
	reorg := externTd.Cmp(localTd) > 0
1014
	currentBlock = bc.CurrentBlock()
1015
	if !reorg && externTd.Cmp(localTd) == 0 {
1016 1017 1018 1019 1020
		// Split same-difficulty blocks by number, then preferentially select
		// the block generated by the local miner as the canonical block.
		if block.NumberU64() < currentBlock.NumberU64() {
			reorg = true
		} else if block.NumberU64() == currentBlock.NumberU64() {
1021 1022 1023
			var currentPreserve, blockPreserve bool
			if bc.shouldPreserve != nil {
				currentPreserve, blockPreserve = bc.shouldPreserve(currentBlock), bc.shouldPreserve(block)
1024
			}
1025
			reorg = !currentPreserve && (blockPreserve || mrand.Float64() < 0.5)
1026
		}
1027 1028
	}
	if reorg {
1029
		// Reorganise the chain if the parent is not the head block
1030 1031
		if block.ParentHash() != currentBlock.Hash() {
			if err := bc.reorg(currentBlock, block); err != nil {
1032
				return NonStatTy, err
1033 1034
			}
		}
1035 1036
		// Write the positional metadata for transaction/receipt lookups and preimages
		rawdb.WriteTxLookupEntries(batch, block)
1037
		rawdb.WritePreimages(batch, state.Preimages())
1038

1039
		status = CanonStatTy
1040
	} else {
1041
		status = SideStatTy
1042
	}
1043 1044 1045
	if err := batch.Write(); err != nil {
		return NonStatTy, err
	}
1046

1047 1048 1049 1050
	// Set new head.
	if status == CanonStatTy {
		bc.insert(block)
	}
C
changhong 已提交
1051
	bc.futureBlocks.Remove(block.Hash())
1052
	return status, nil
1053 1054
}

1055 1056 1057
// addFutureBlock checks if the block is within the max allowed window to get
// accepted for future processing, and returns an error if the block is too far
// ahead and was not added.
1058 1059 1060
func (bc *BlockChain) addFutureBlock(block *types.Block) error {
	max := big.NewInt(time.Now().Unix() + maxTimeFutureBlocks)
	if block.Time().Cmp(max) > 0 {
1061
		return fmt.Errorf("future block timestamp %v > allowed %v", block.Time(), max)
1062 1063 1064 1065 1066
	}
	bc.futureBlocks.Add(block.Hash(), block)
	return nil
}

1067 1068 1069 1070 1071 1072
// InsertChain attempts to insert the given batch of blocks in to the canonical
// chain or, otherwise, create a fork. If an error is returned it will return
// the index number of the failing block as well an error describing what went
// wrong.
//
// After insertion is done, all accumulated events will be fired.
C
changhong 已提交
1073
func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) {
1074 1075
	// Sanity check that we have something meaningful to import
	if len(chain) == 0 {
1076
		return 0, nil
1077
	}
1078 1079 1080
	// Do a sanity check that the provided chain is actually ordered and linked
	for i := 1; i < len(chain); i++ {
		if chain[i].NumberU64() != chain[i-1].NumberU64()+1 || chain[i].ParentHash() != chain[i-1].Hash() {
1081
			// Chain broke ancestry, log a message (programming error) and skip insertion
1082 1083
			log.Error("Non contiguous block insert", "number", chain[i].Number(), "hash", chain[i].Hash(),
				"parent", chain[i].ParentHash(), "prevnumber", chain[i-1].Number(), "prevhash", chain[i-1].Hash())
1084

1085
			return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, chain[i-1].NumberU64(),
1086
				chain[i-1].Hash().Bytes()[:4], i, chain[i].NumberU64(), chain[i].Hash().Bytes()[:4], chain[i].ParentHash().Bytes()[:4])
1087 1088 1089
		}
	}
	// Pre-checks passed, start the full block imports
C
changhong 已提交
1090 1091
	bc.wg.Add(1)
	bc.chainmu.Lock()
1092 1093 1094
	n, events, logs, err := bc.insertChain(chain, true)
	bc.chainmu.Unlock()
	bc.wg.Done()
1095

1096 1097 1098
	bc.PostChainEvents(events, logs)
	return n, err
}
1099

1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112
// insertChain is the internal implementation of insertChain, which assumes that
// 1) chains are contiguous, and 2) The chain mutex is held.
//
// This method is split out so that import batches that require re-injecting
// historical blocks can do so without releasing the lock, which could lead to
// racey behaviour. If a sidechain import is in progress, and the historic state
// is imported, but then new canon-head is added before the actual sidechain
// completes, then the historic state could be pruned again
func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, []interface{}, []*types.Log, error) {
	// If the chain is terminating, don't even bother starting u
	if atomic.LoadInt32(&bc.procInterrupt) == 1 {
		return 0, nil, nil, nil
	}
1113 1114
	// Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss)
	senderCacher.recoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number()), chain)
O
obscuren 已提交
1115

F
Felix Lange 已提交
1116 1117 1118
	// A queued approach to delivering events. This is generally
	// faster than direct delivery and requires much less mutex
	// acquiring.
O
obscuren 已提交
1119
	var (
F
Felix Lange 已提交
1120
		stats         = insertStats{startTime: mclock.Now()}
1121
		events        = make([]interface{}, 0, len(chain))
1122
		lastCanon     *types.Block
F
Felix Lange 已提交
1123
		coalescedLogs []*types.Log
O
obscuren 已提交
1124
	)
1125 1126 1127
	// Start the parallel header verifier
	headers := make([]*types.Header, len(chain))
	seals := make([]bool, len(chain))
1128

1129 1130
	for i, block := range chain {
		headers[i] = block.Header()
1131
		seals[i] = verifySeals
1132
	}
C
changhong 已提交
1133
	abort, results := bc.engine.VerifyHeaders(bc, headers, seals)
1134
	defer close(abort)
1135

1136 1137
	// Peek the error for the first block to decide the directing import logic
	it := newInsertIterator(chain, results, bc.Validator())
1138

1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149
	block, err := it.next()
	switch {
	// First block is pruned, insert as sidechain and reorg only if TD grows enough
	case err == consensus.ErrPrunedAncestor:
		return bc.insertSidechain(it)

	// First block is future, shove it (and all children) to the future queue (unknown ancestor)
	case err == consensus.ErrFutureBlock || (err == consensus.ErrUnknownAncestor && bc.futureBlocks.Contains(it.first().ParentHash())):
		for block != nil && (it.index == 0 || err == consensus.ErrUnknownAncestor) {
			if err := bc.addFutureBlock(block); err != nil {
				return it.index, events, coalescedLogs, err
1150
			}
1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169
			block, err = it.next()
		}
		stats.queued += it.processed()
		stats.ignored += it.remaining()

		// If there are any still remaining, mark as ignored
		return it.index, events, coalescedLogs, err

	// First block (and state) is known
	//   1. We did a roll-back, and should now do a re-import
	//   2. The block is stored as a sidechain, and is lying about it's stateroot, and passes a stateroot
	// 	    from the canonical chain, which has not been verified.
	case err == ErrKnownBlock:
		// Skip all known blocks that behind us
		current := bc.CurrentBlock().NumberU64()

		for block != nil && err == ErrKnownBlock && current >= block.NumberU64() {
			stats.ignored++
			block, err = it.next()
1170
		}
1171 1172 1173 1174 1175 1176 1177
		// Falls through to the block import

	// Some other error occurred, abort
	case err != nil:
		stats.ignored += len(it.chain)
		bc.reportBlock(block, nil, err)
		return it.index, events, coalescedLogs, err
1178
	}
1179 1180
	// No validation errors for the first block (or chain prefix skipped)
	for ; block != nil && err == nil; block, err = it.next() {
1181
		// If the chain is terminating, stop processing blocks
C
changhong 已提交
1182
		if atomic.LoadInt32(&bc.procInterrupt) == 1 {
1183
			log.Debug("Premature abort during blocks processing")
O
obscuren 已提交
1184 1185
			break
		}
1186
		// If the header is a banned one, straight out abort
O
obscuren 已提交
1187
		if BadHashes[block.Hash()] {
C
changhong 已提交
1188
			bc.reportBlock(block, nil, ErrBlacklistedHash)
1189
			return it.index, events, coalescedLogs, ErrBlacklistedHash
O
obscuren 已提交
1190
		}
1191 1192
		// Retrieve the parent block and it's state to execute on top
		start := time.Now()
O
obscuren 已提交
1193

1194
		parent := it.previous()
1195
		if parent == nil {
1196
			parent = bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
1197
		}
1198
		state, err := state.New(parent.Root(), bc.stateCache)
1199
		if err != nil {
1200
			return it.index, events, coalescedLogs, err
O
obscuren 已提交
1201
		}
1202
		// Process block using the parent state as reference point.
1203
		t0 := time.Now()
1204
		receipts, logs, usedGas, err := bc.processor.Process(block, state, bc.vmConfig)
1205
		t1 := time.Now()
1206
		if err != nil {
C
changhong 已提交
1207
			bc.reportBlock(block, receipts, err)
1208
			return it.index, events, coalescedLogs, err
1209 1210
		}
		// Validate the state using the default validator
1211
		if err := bc.Validator().ValidateState(block, parent, state, receipts, usedGas); err != nil {
C
changhong 已提交
1212
			bc.reportBlock(block, receipts, err)
1213
			return it.index, events, coalescedLogs, err
1214
		}
1215
		t2 := time.Now()
1216
		proctime := time.Since(start)
1217

1218
		// Write the block to the chain and get the status.
1219
		status, err := bc.writeBlockWithState(block, receipts, state)
1220
		t3 := time.Now()
1221
		if err != nil {
1222
			return it.index, events, coalescedLogs, err
1223
		}
1224 1225 1226 1227
		blockInsertTimer.UpdateSince(start)
		blockExecutionTimer.Update(t1.Sub(t0))
		blockValidationTimer.Update(t2.Sub(t1))
		blockWriteTimer.Update(t3.Sub(t2))
1228
		switch status {
1229
		case CanonStatTy:
1230 1231
			log.Debug("Inserted new block", "number", block.Number(), "hash", block.Hash(),
				"uncles", len(block.Uncles()), "txs", len(block.Transactions()), "gas", block.GasUsed(),
1232 1233
				"elapsed", common.PrettyDuration(time.Since(start)),
				"root", block.Root())
1234

1235
			coalescedLogs = append(coalescedLogs, logs...)
1236
			events = append(events, ChainEvent{block, block.Hash(), logs})
1237 1238
			lastCanon = block

1239 1240 1241
			// Only count canonical blocks for GC processing time
			bc.gcproc += proctime

1242
		case SideStatTy:
1243
			log.Debug("Inserted forked block", "number", block.Number(), "hash", block.Hash(),
1244
				"diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)),
1245
				"txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()),
1246
				"root", block.Root())
1247
			events = append(events, ChainSideEvent{block})
1248
		}
1249
		blockInsertTimer.UpdateSince(start)
O
obscuren 已提交
1250
		stats.processed++
1251
		stats.usedGas += usedGas
1252 1253

		cache, _ := bc.stateCache.TrieDB().Size()
1254
		stats.report(chain, it.index, cache)
O
obscuren 已提交
1255
	}
1256
	// Any blocks remaining here? The only ones we care about are the future ones
1257
	if block != nil && err == consensus.ErrFutureBlock {
1258 1259
		if err := bc.addFutureBlock(block); err != nil {
			return it.index, events, coalescedLogs, err
1260
		}
1261 1262 1263 1264 1265
		block, err = it.next()

		for ; block != nil && err == consensus.ErrUnknownAncestor; block, err = it.next() {
			if err := bc.addFutureBlock(block); err != nil {
				return it.index, events, coalescedLogs, err
1266 1267 1268
			}
			stats.queued++
		}
O
obscuren 已提交
1269
	}
1270 1271
	stats.ignored += it.remaining()

1272
	// Append a single chain head event if we've progressed the chain
1273
	if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() {
1274 1275
		events = append(events, ChainHeadEvent{lastCanon})
	}
1276
	return it.index, events, coalescedLogs, err
O
obscuren 已提交
1277
}
1278

1279 1280 1281 1282 1283 1284 1285
// insertSidechain is called when an import batch hits upon a pruned ancestor
// error, which happens when a sidechain with a sufficiently old fork-block is
// found.
//
// The method writes all (header-and-body-valid) blocks to disk, then tries to
// switch over to the new chain if the TD exceeded the current chain.
func (bc *BlockChain) insertSidechain(it *insertIterator) (int, []interface{}, []*types.Log, error) {
1286
	var (
1287
		externTd *big.Int
1288
		current  = bc.CurrentBlock()
1289
	)
1290 1291 1292 1293 1294 1295 1296
	// The first sidechain block error is already verified to be ErrPrunedAncestor.
	// Since we don't import them here, we expect ErrUnknownAncestor for the remaining
	// ones. Any other errors means that the block is invalid, and should not be written
	// to disk.
	block, err := it.current(), consensus.ErrPrunedAncestor
	for ; block != nil && (err == consensus.ErrPrunedAncestor); block, err = it.next() {
		// Check the canonical state root for that number
1297
		if number := block.NumberU64(); current.NumberU64() >= number {
1298 1299 1300 1301
			if canonical := bc.GetBlockByNumber(number); canonical != nil && canonical.Root() == block.Root() {
				// This is most likely a shadow-state attack. When a fork is imported into the
				// database, and it eventually reaches a block height which is not pruned, we
				// just found that the state already exist! This means that the sidechain block
1302
				// refers to a state which already exists in our canon chain.
1303 1304 1305 1306 1307
				//
				// If left unchecked, we would now proceed importing the blocks, without actually
				// having verified the state of the previous blocks.
				log.Warn("Sidechain ghost-state attack detected", "number", block.NumberU64(), "sideroot", block.Root(), "canonroot", canonical.Root())

1308 1309 1310
				// If someone legitimately side-mines blocks, they would still be imported as usual. However,
				// we cannot risk writing unverified blocks to disk when they obviously target the pruning
				// mechanism.
1311
				return it.index, nil, nil, errors.New("sidechain ghost-state attack")
1312
			}
1313
		}
1314 1315
		if externTd == nil {
			externTd = bc.GetTd(block.ParentHash(), block.NumberU64()-1)
1316
		}
1317
		externTd = new(big.Int).Add(externTd, block.Difficulty())
1318

1319
		if !bc.HasBlock(block.Hash(), block.NumberU64()) {
1320
			start := time.Now()
1321
			if err := bc.WriteBlockWithoutState(block, externTd); err != nil {
1322
				return it.index, nil, nil, err
1323
			}
1324 1325 1326 1327
			log.Debug("Inserted sidechain block", "number", block.Number(), "hash", block.Hash(),
				"diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)),
				"txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()),
				"root", block.Root())
1328
		}
1329
	}
1330 1331 1332
	// At this point, we've written all sidechain blocks to database. Loop ended
	// either on some other error or all were processed. If there was some other
	// error, we can ignore the rest of those blocks.
1333 1334 1335
	//
	// If the externTd was larger than our local TD, we now need to reimport the previous
	// blocks to regenerate the required state
1336
	localTd := bc.GetTd(current.Hash(), current.NumberU64())
1337
	if localTd.Cmp(externTd) > 0 {
1338 1339
		log.Info("Sidechain written to disk", "start", it.first().NumberU64(), "end", it.previous().NumberU64(), "sidetd", externTd, "localtd", localTd)
		return it.index, nil, nil, err
1340
	}
1341 1342 1343 1344 1345 1346 1347 1348 1349
	// Gather all the sidechain hashes (full blocks may be memory heavy)
	var (
		hashes  []common.Hash
		numbers []uint64
	)
	parent := bc.GetHeader(it.previous().Hash(), it.previous().NumberU64())
	for parent != nil && !bc.HasState(parent.Root) {
		hashes = append(hashes, parent.Hash())
		numbers = append(numbers, parent.Number.Uint64())
1350

1351
		parent = bc.GetHeader(parent.ParentHash, parent.Number.Uint64()-1)
F
Felix Lange 已提交
1352
	}
1353 1354
	if parent == nil {
		return it.index, nil, nil, errors.New("missing parent")
1355 1356
	}
	// Import all the pruned blocks to make the state available
1357
	var (
1358 1359
		blocks []*types.Block
		memory common.StorageSize
1360
	)
1361 1362 1363
	for i := len(hashes) - 1; i >= 0; i-- {
		// Append the next block to our batch
		block := bc.GetBlock(hashes[i], numbers[i])
1364

1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376
		blocks = append(blocks, block)
		memory += block.Size()

		// If memory use grew too large, import and continue. Sadly we need to discard
		// all raised events and logs from notifications since we're too heavy on the
		// memory here.
		if len(blocks) >= 2048 || memory > 64*1024*1024 {
			log.Info("Importing heavy sidechain segment", "blocks", len(blocks), "start", blocks[0].NumberU64(), "end", block.NumberU64())
			if _, _, _, err := bc.insertChain(blocks, false); err != nil {
				return 0, nil, nil, err
			}
			blocks, memory = blocks[:0], 0
F
Felix Lange 已提交
1377

1378 1379 1380 1381 1382 1383
			// If the chain is terminating, stop processing blocks
			if atomic.LoadInt32(&bc.procInterrupt) == 1 {
				log.Debug("Premature abort during blocks processing")
				return 0, nil, nil, nil
			}
		}
F
Felix Lange 已提交
1384
	}
1385 1386 1387
	if len(blocks) > 0 {
		log.Info("Importing sidechain segment", "start", blocks[0].NumberU64(), "end", blocks[len(blocks)-1].NumberU64())
		return bc.insertChain(blocks, false)
F
Felix Lange 已提交
1388
	}
1389
	return 0, nil, nil, nil
F
Felix Lange 已提交
1390 1391
}

1392 1393 1394
// 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
C
changhong 已提交
1395
func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
1396
	var (
1397 1398 1399 1400
		newChain    types.Blocks
		oldChain    types.Blocks
		commonBlock *types.Block
		deletedTxs  types.Transactions
F
Felix Lange 已提交
1401
		deletedLogs []*types.Log
J
Jeffrey Wilcke 已提交
1402 1403 1404
		// 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.
1405
		collectLogs = func(hash common.Hash) {
1406
			// Coalesce logs and set 'Removed'.
1407 1408 1409 1410 1411
			number := bc.hc.GetBlockNumber(hash)
			if number == nil {
				return
			}
			receipts := rawdb.ReadReceipts(bc.db, hash, *number)
J
Jeffrey Wilcke 已提交
1412
			for _, receipt := range receipts {
1413 1414 1415 1416 1417
				for _, log := range receipt.Logs {
					del := *log
					del.Removed = true
					deletedLogs = append(deletedLogs, &del)
				}
J
Jeffrey Wilcke 已提交
1418 1419
			}
		}
1420
	)
1421 1422 1423 1424

	// first reduce whoever is higher bound
	if oldBlock.NumberU64() > newBlock.NumberU64() {
		// reduce old chain
C
changhong 已提交
1425
		for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) {
1426
			oldChain = append(oldChain, oldBlock)
1427
			deletedTxs = append(deletedTxs, oldBlock.Transactions()...)
J
Jeffrey Wilcke 已提交
1428 1429

			collectLogs(oldBlock.Hash())
1430 1431 1432
		}
	} else {
		// reduce new chain and append new chain blocks for inserting later on
C
changhong 已提交
1433
		for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) {
1434 1435
			newChain = append(newChain, newBlock)
		}
O
obscuren 已提交
1436
	}
O
obscuren 已提交
1437
	if oldBlock == nil {
1438
		return fmt.Errorf("Invalid old chain")
O
obscuren 已提交
1439 1440
	}
	if newBlock == nil {
1441
		return fmt.Errorf("Invalid new chain")
O
obscuren 已提交
1442
	}
O
obscuren 已提交
1443

1444 1445
	for {
		if oldBlock.Hash() == newBlock.Hash() {
1446
			commonBlock = oldBlock
1447 1448
			break
		}
1449 1450

		oldChain = append(oldChain, oldBlock)
1451
		newChain = append(newChain, newBlock)
1452
		deletedTxs = append(deletedTxs, oldBlock.Transactions()...)
J
Jeffrey Wilcke 已提交
1453
		collectLogs(oldBlock.Hash())
O
obscuren 已提交
1454

C
changhong 已提交
1455
		oldBlock, newBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1), bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1)
1456
		if oldBlock == nil {
1457
			return fmt.Errorf("Invalid old chain")
1458 1459
		}
		if newBlock == nil {
1460
			return fmt.Errorf("Invalid new chain")
1461
		}
1462
	}
1463
	// Ensure the user sees large reorgs
1464 1465 1466 1467 1468 1469 1470 1471 1472
	if len(oldChain) > 0 && len(newChain) > 0 {
		logFn := log.Debug
		if len(oldChain) > 63 {
			logFn = log.Warn
		}
		logFn("Chain split detected", "number", commonBlock.Number(), "hash", commonBlock.Hash(),
			"drop", len(oldChain), "dropfrom", oldChain[0].Hash(), "add", len(newChain), "addfrom", newChain[0].Hash())
	} else {
		log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "newnum", newBlock.Number(), "newhash", newBlock.Hash())
1473
	}
1474
	// Insert the new chain, taking care of the proper incremental order
1475
	var addedTxs types.Transactions
1476
	for i := len(newChain) - 1; i >= 0; i-- {
1477
		// insert the block in the canonical way, re-writing history
1478
		bc.insert(newChain[i])
1479
		// write lookup entries for hash based transaction/receipt searches
1480
		rawdb.WriteTxLookupEntries(bc.db, newChain[i])
1481
		addedTxs = append(addedTxs, newChain[i].Transactions()...)
1482 1483 1484 1485 1486
	}
	// 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
1487
	batch := bc.db.NewBatch()
1488
	for _, tx := range diff {
1489
		rawdb.DeleteTxLookupEntry(batch, tx.Hash())
1490
	}
1491 1492
	batch.Write()

J
Jeffrey Wilcke 已提交
1493
	if len(deletedLogs) > 0 {
1494
		go bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs})
J
Jeffrey Wilcke 已提交
1495
	}
1496 1497 1498
	if len(oldChain) > 0 {
		go func() {
			for _, block := range oldChain {
1499
				bc.chainSideFeed.Send(ChainSideEvent{Block: block})
1500 1501 1502 1503
			}
		}()
	}

1504
	return nil
1505 1506
}

1507 1508 1509 1510
// PostChainEvents iterates over the events generated by a chain insertion and
// posts them into the event feed.
// TODO: Should not expose PostChainEvents. The chain events should be posted in WriteBlock.
func (bc *BlockChain) PostChainEvents(events []interface{}, logs []*types.Log) {
1511
	// post event logs for further processing
1512 1513 1514
	if logs != nil {
		bc.logsFeed.Send(logs)
	}
1515
	for _, event := range events {
1516 1517 1518 1519 1520 1521 1522 1523 1524
		switch ev := event.(type) {
		case ChainEvent:
			bc.chainFeed.Send(ev)

		case ChainHeadEvent:
			bc.chainHeadFeed.Send(ev)

		case ChainSideEvent:
			bc.chainSideFeed.Send(ev)
1525 1526 1527 1528
		}
	}
}

C
changhong 已提交
1529
func (bc *BlockChain) update() {
1530 1531
	futureTimer := time.NewTicker(5 * time.Second)
	defer futureTimer.Stop()
1532 1533
	for {
		select {
1534
		case <-futureTimer.C:
C
changhong 已提交
1535 1536
			bc.procFutureBlocks()
		case <-bc.quit:
1537
			return
1538 1539 1540
		}
	}
}
1541

1542
// BadBlocks returns a list of the last 'bad blocks' that the client has seen on the network
1543 1544
func (bc *BlockChain) BadBlocks() []*types.Block {
	blocks := make([]*types.Block, 0, bc.badBlocks.Len())
1545
	for _, hash := range bc.badBlocks.Keys() {
1546 1547 1548
		if blk, exist := bc.badBlocks.Peek(hash); exist {
			block := blk.(*types.Block)
			blocks = append(blocks, block)
1549 1550
		}
	}
1551
	return blocks
1552 1553 1554 1555
}

// addBadBlock adds a bad block to the bad-block LRU cache
func (bc *BlockChain) addBadBlock(block *types.Block) {
1556
	bc.badBlocks.Add(block.Hash(), block)
1557 1558
}

F
Felix Lange 已提交
1559
// reportBlock logs a bad block error.
1560
func (bc *BlockChain) reportBlock(block *types.Block, receipts types.Receipts, err error) {
1561
	bc.addBadBlock(block)
1562 1563

	var receiptString string
1564 1565 1566 1567
	for i, receipt := range receipts {
		receiptString += fmt.Sprintf("\t %d: cumulative: %v gas: %v contract: %v status: %v tx: %v logs: %v bloom: %x state: %x\n",
			i, receipt.CumulativeGasUsed, receipt.GasUsed, receipt.ContractAddress.Hex(),
			receipt.Status, receipt.TxHash.Hex(), receipt.Logs, receipt.Bloom, receipt.PostState)
1568 1569
	}
	log.Error(fmt.Sprintf(`
1570 1571 1572 1573 1574 1575 1576 1577 1578
########## BAD BLOCK #########
Chain config: %v

Number: %v
Hash: 0x%x
%v

Error: %v
##############################
1579
`, bc.chainConfig, block.Number(), block.Hash(), receiptString, err))
F
Felix Lange 已提交
1580
}
1581 1582 1583 1584 1585 1586 1587

// 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 已提交
1588
// of the header retrieval mechanisms already need to verify nonces, as well as
1589
// because nonces can be verified sparsely, not needing to check each.
C
changhong 已提交
1590
func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) {
1591
	start := time.Now()
C
changhong 已提交
1592
	if i, err := bc.hc.ValidateHeaderChain(chain, checkFreq); err != nil {
1593 1594 1595
		return i, err
	}

1596
	// Make sure only one thread manipulates the chain at once
C
changhong 已提交
1597 1598
	bc.chainmu.Lock()
	defer bc.chainmu.Unlock()
1599

C
changhong 已提交
1600 1601
	bc.wg.Add(1)
	defer bc.wg.Done()
1602 1603

	whFunc := func(header *types.Header) error {
C
changhong 已提交
1604
		_, err := bc.hc.WriteHeader(header)
1605 1606
		return err
	}
C
changhong 已提交
1607
	return bc.hc.InsertHeaderChain(chain, whFunc, start)
1608 1609 1610 1611
}

// CurrentHeader retrieves the current head header of the canonical chain. The
// header is retrieved from the HeaderChain's internal cache.
C
changhong 已提交
1612 1613
func (bc *BlockChain) CurrentHeader() *types.Header {
	return bc.hc.CurrentHeader()
1614 1615 1616
}

// GetTd retrieves a block's total difficulty in the canonical chain from the
1617
// database by hash and number, caching it if found.
C
changhong 已提交
1618 1619
func (bc *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int {
	return bc.hc.GetTd(hash, number)
1620 1621 1622
}

// GetTdByHash retrieves a block's total difficulty in the canonical chain from the
1623
// database by hash, caching it if found.
C
changhong 已提交
1624 1625
func (bc *BlockChain) GetTdByHash(hash common.Hash) *big.Int {
	return bc.hc.GetTdByHash(hash)
1626 1627 1628 1629
}

// GetHeader retrieves a block header from the database by hash and number,
// caching it if found.
C
changhong 已提交
1630 1631
func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header {
	return bc.hc.GetHeader(hash, number)
1632 1633
}

1634
// GetHeaderByHash retrieves a block header from the database by hash, caching it if
1635
// found.
C
changhong 已提交
1636 1637
func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header {
	return bc.hc.GetHeaderByHash(hash)
1638 1639 1640 1641
}

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

// GetBlockHashesFromHash retrieves a number of block hashes starting at a given
// hash, fetching towards the genesis block.
C
changhong 已提交
1648 1649
func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash {
	return bc.hc.GetBlockHashesFromHash(hash, max)
1650 1651
}

1652 1653 1654 1655 1656 1657
// GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or
// a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the
// number of blocks to be individually checked before we reach the canonical chain.
//
// Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
func (bc *BlockChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) {
1658 1659
	bc.chainmu.RLock()
	defer bc.chainmu.RUnlock()
1660 1661 1662 1663

	return bc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical)
}

1664 1665
// GetHeaderByNumber retrieves a block header from the database by number,
// caching it (associated with its hash) if found.
C
changhong 已提交
1666 1667
func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
	return bc.hc.GetHeaderByNumber(number)
1668
}
1669 1670

// Config retrieves the blockchain's chain configuration.
1671
func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig }
1672 1673

// Engine retrieves the blockchain's consensus engine.
C
changhong 已提交
1674
func (bc *BlockChain) Engine() consensus.Engine { return bc.engine }
1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699

// SubscribeRemovedLogsEvent registers a subscription of RemovedLogsEvent.
func (bc *BlockChain) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription {
	return bc.scope.Track(bc.rmLogsFeed.Subscribe(ch))
}

// SubscribeChainEvent registers a subscription of ChainEvent.
func (bc *BlockChain) SubscribeChainEvent(ch chan<- ChainEvent) event.Subscription {
	return bc.scope.Track(bc.chainFeed.Subscribe(ch))
}

// SubscribeChainHeadEvent registers a subscription of ChainHeadEvent.
func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription {
	return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch))
}

// SubscribeChainSideEvent registers a subscription of ChainSideEvent.
func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription {
	return bc.scope.Track(bc.chainSideFeed.Subscribe(ch))
}

// SubscribeLogsEvent registers a subscription of []*types.Log.
func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
	return bc.scope.Track(bc.logsFeed.Subscribe(ch))
}