1// Copyright 2021 The go-ethereum Authors
2// This file is part of the go-ethereum library.
3//
4// The go-ethereum library is free software: you can redistribute it and/or modify
5// it under the terms of the GNU Lesser General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// The go-ethereum library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU Lesser General Public License for more details.
13//
14// 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/>.
16
17package core
18
19import (
20	"math/big"
21
22	"github.com/ethereum/go-ethereum/common"
23	"github.com/ethereum/go-ethereum/consensus"
24	"github.com/ethereum/go-ethereum/core/rawdb"
25	"github.com/ethereum/go-ethereum/core/state"
26	"github.com/ethereum/go-ethereum/core/state/snapshot"
27	"github.com/ethereum/go-ethereum/core/types"
28	"github.com/ethereum/go-ethereum/core/vm"
29	"github.com/ethereum/go-ethereum/event"
30	"github.com/ethereum/go-ethereum/params"
31	"github.com/ethereum/go-ethereum/rlp"
32)
33
34// CurrentHeader retrieves the current head header of the canonical chain. The
35// header is retrieved from the HeaderChain's internal cache.
36func (bc *BlockChain) CurrentHeader() *types.Header {
37	return bc.hc.CurrentHeader()
38}
39
40// CurrentBlock retrieves the current head block of the canonical chain. The
41// block is retrieved from the blockchain's internal cache.
42func (bc *BlockChain) CurrentBlock() *types.Block {
43	return bc.currentBlock.Load().(*types.Block)
44}
45
46// CurrentFastBlock retrieves the current fast-sync head block of the canonical
47// chain. The block is retrieved from the blockchain's internal cache.
48func (bc *BlockChain) CurrentFastBlock() *types.Block {
49	return bc.currentFastBlock.Load().(*types.Block)
50}
51
52// HasHeader checks if a block header is present in the database or not, caching
53// it if present.
54func (bc *BlockChain) HasHeader(hash common.Hash, number uint64) bool {
55	return bc.hc.HasHeader(hash, number)
56}
57
58// GetHeader retrieves a block header from the database by hash and number,
59// caching it if found.
60func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header {
61	return bc.hc.GetHeader(hash, number)
62}
63
64// GetHeaderByHash retrieves a block header from the database by hash, caching it if
65// found.
66func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header {
67	return bc.hc.GetHeaderByHash(hash)
68}
69
70// GetHeaderByNumber retrieves a block header from the database by number,
71// caching it (associated with its hash) if found.
72func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
73	return bc.hc.GetHeaderByNumber(number)
74}
75
76// GetHeadersFrom returns a contiguous segment of headers, in rlp-form, going
77// backwards from the given number.
78func (bc *BlockChain) GetHeadersFrom(number, count uint64) []rlp.RawValue {
79	return bc.hc.GetHeadersFrom(number, count)
80}
81
82// GetBody retrieves a block body (transactions and uncles) from the database by
83// hash, caching it if found.
84func (bc *BlockChain) GetBody(hash common.Hash) *types.Body {
85	// Short circuit if the body's already in the cache, retrieve otherwise
86	if cached, ok := bc.bodyCache.Get(hash); ok {
87		body := cached.(*types.Body)
88		return body
89	}
90	number := bc.hc.GetBlockNumber(hash)
91	if number == nil {
92		return nil
93	}
94	body := rawdb.ReadBody(bc.db, hash, *number)
95	if body == nil {
96		return nil
97	}
98	// Cache the found body for next time and return
99	bc.bodyCache.Add(hash, body)
100	return body
101}
102
103// GetBodyRLP retrieves a block body in RLP encoding from the database by hash,
104// caching it if found.
105func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
106	// Short circuit if the body's already in the cache, retrieve otherwise
107	if cached, ok := bc.bodyRLPCache.Get(hash); ok {
108		return cached.(rlp.RawValue)
109	}
110	number := bc.hc.GetBlockNumber(hash)
111	if number == nil {
112		return nil
113	}
114	body := rawdb.ReadBodyRLP(bc.db, hash, *number)
115	if len(body) == 0 {
116		return nil
117	}
118	// Cache the found body for next time and return
119	bc.bodyRLPCache.Add(hash, body)
120	return body
121}
122
123// HasBlock checks if a block is fully present in the database or not.
124func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool {
125	if bc.blockCache.Contains(hash) {
126		return true
127	}
128	return rawdb.HasBody(bc.db, hash, number)
129}
130
131// HasFastBlock checks if a fast block is fully present in the database or not.
132func (bc *BlockChain) HasFastBlock(hash common.Hash, number uint64) bool {
133	if !bc.HasBlock(hash, number) {
134		return false
135	}
136	if bc.receiptsCache.Contains(hash) {
137		return true
138	}
139	return rawdb.HasReceipts(bc.db, hash, number)
140}
141
142// GetBlock retrieves a block from the database by hash and number,
143// caching it if found.
144func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
145	// Short circuit if the block's already in the cache, retrieve otherwise
146	if block, ok := bc.blockCache.Get(hash); ok {
147		return block.(*types.Block)
148	}
149	block := rawdb.ReadBlock(bc.db, hash, number)
150	if block == nil {
151		return nil
152	}
153	// Cache the found block for next time and return
154	bc.blockCache.Add(block.Hash(), block)
155	return block
156}
157
158// GetBlockByHash retrieves a block from the database by hash, caching it if found.
159func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
160	number := bc.hc.GetBlockNumber(hash)
161	if number == nil {
162		return nil
163	}
164	return bc.GetBlock(hash, *number)
165}
166
167// GetBlockByNumber retrieves a block from the database by number, caching it
168// (associated with its hash) if found.
169func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block {
170	hash := rawdb.ReadCanonicalHash(bc.db, number)
171	if hash == (common.Hash{}) {
172		return nil
173	}
174	return bc.GetBlock(hash, number)
175}
176
177// GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
178// [deprecated by eth/62]
179func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
180	number := bc.hc.GetBlockNumber(hash)
181	if number == nil {
182		return nil
183	}
184	for i := 0; i < n; i++ {
185		block := bc.GetBlock(hash, *number)
186		if block == nil {
187			break
188		}
189		blocks = append(blocks, block)
190		hash = block.ParentHash()
191		*number--
192	}
193	return
194}
195
196// GetReceiptsByHash retrieves the receipts for all transactions in a given block.
197func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
198	if receipts, ok := bc.receiptsCache.Get(hash); ok {
199		return receipts.(types.Receipts)
200	}
201	number := rawdb.ReadHeaderNumber(bc.db, hash)
202	if number == nil {
203		return nil
204	}
205	receipts := rawdb.ReadReceipts(bc.db, hash, *number, bc.chainConfig)
206	if receipts == nil {
207		return nil
208	}
209	bc.receiptsCache.Add(hash, receipts)
210	return receipts
211}
212
213// GetUnclesInChain retrieves all the uncles from a given block backwards until
214// a specific distance is reached.
215func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header {
216	uncles := []*types.Header{}
217	for i := 0; block != nil && i < length; i++ {
218		uncles = append(uncles, block.Uncles()...)
219		block = bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
220	}
221	return uncles
222}
223
224// GetCanonicalHash returns the canonical hash for a given block number
225func (bc *BlockChain) GetCanonicalHash(number uint64) common.Hash {
226	return bc.hc.GetCanonicalHash(number)
227}
228
229// GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or
230// a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the
231// number of blocks to be individually checked before we reach the canonical chain.
232//
233// Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
234func (bc *BlockChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) {
235	return bc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical)
236}
237
238// GetTransactionLookup retrieves the lookup associate with the given transaction
239// hash from the cache or database.
240func (bc *BlockChain) GetTransactionLookup(hash common.Hash) *rawdb.LegacyTxLookupEntry {
241	// Short circuit if the txlookup already in the cache, retrieve otherwise
242	if lookup, exist := bc.txLookupCache.Get(hash); exist {
243		return lookup.(*rawdb.LegacyTxLookupEntry)
244	}
245	tx, blockHash, blockNumber, txIndex := rawdb.ReadTransaction(bc.db, hash)
246	if tx == nil {
247		return nil
248	}
249	lookup := &rawdb.LegacyTxLookupEntry{BlockHash: blockHash, BlockIndex: blockNumber, Index: txIndex}
250	bc.txLookupCache.Add(hash, lookup)
251	return lookup
252}
253
254// GetTd retrieves a block's total difficulty in the canonical chain from the
255// database by hash and number, caching it if found.
256func (bc *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int {
257	return bc.hc.GetTd(hash, number)
258}
259
260// HasState checks if state trie is fully present in the database or not.
261func (bc *BlockChain) HasState(hash common.Hash) bool {
262	_, err := bc.stateCache.OpenTrie(hash)
263	return err == nil
264}
265
266// HasBlockAndState checks if a block and associated state trie is fully present
267// in the database or not, caching it if present.
268func (bc *BlockChain) HasBlockAndState(hash common.Hash, number uint64) bool {
269	// Check first that the block itself is known
270	block := bc.GetBlock(hash, number)
271	if block == nil {
272		return false
273	}
274	return bc.HasState(block.Root())
275}
276
277// TrieNode retrieves a blob of data associated with a trie node
278// either from ephemeral in-memory cache, or from persistent storage.
279func (bc *BlockChain) TrieNode(hash common.Hash) ([]byte, error) {
280	return bc.stateCache.TrieDB().Node(hash)
281}
282
283// ContractCode retrieves a blob of data associated with a contract hash
284// either from ephemeral in-memory cache, or from persistent storage.
285func (bc *BlockChain) ContractCode(hash common.Hash) ([]byte, error) {
286	return bc.stateCache.ContractCode(common.Hash{}, hash)
287}
288
289// ContractCodeWithPrefix retrieves a blob of data associated with a contract
290// hash either from ephemeral in-memory cache, or from persistent storage.
291//
292// If the code doesn't exist in the in-memory cache, check the storage with
293// new code scheme.
294func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) ([]byte, error) {
295	type codeReader interface {
296		ContractCodeWithPrefix(addrHash, codeHash common.Hash) ([]byte, error)
297	}
298	return bc.stateCache.(codeReader).ContractCodeWithPrefix(common.Hash{}, hash)
299}
300
301// State returns a new mutable state based on the current HEAD block.
302func (bc *BlockChain) State() (*state.StateDB, error) {
303	return bc.StateAt(bc.CurrentBlock().Root())
304}
305
306// StateAt returns a new mutable state based on a particular point in time.
307func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
308	return state.New(root, bc.stateCache, bc.snaps)
309}
310
311// Config retrieves the chain's fork configuration.
312func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig }
313
314// Engine retrieves the blockchain's consensus engine.
315func (bc *BlockChain) Engine() consensus.Engine { return bc.engine }
316
317// Snapshots returns the blockchain snapshot tree.
318func (bc *BlockChain) Snapshots() *snapshot.Tree {
319	return bc.snaps
320}
321
322// Validator returns the current validator.
323func (bc *BlockChain) Validator() Validator {
324	return bc.validator
325}
326
327// Processor returns the current processor.
328func (bc *BlockChain) Processor() Processor {
329	return bc.processor
330}
331
332// StateCache returns the caching database underpinning the blockchain instance.
333func (bc *BlockChain) StateCache() state.Database {
334	return bc.stateCache
335}
336
337// GasLimit returns the gas limit of the current HEAD block.
338func (bc *BlockChain) GasLimit() uint64 {
339	return bc.CurrentBlock().GasLimit()
340}
341
342// Genesis retrieves the chain's genesis block.
343func (bc *BlockChain) Genesis() *types.Block {
344	return bc.genesisBlock
345}
346
347// GetVMConfig returns the block chain VM config.
348func (bc *BlockChain) GetVMConfig() *vm.Config {
349	return &bc.vmConfig
350}
351
352// SetTxLookupLimit is responsible for updating the txlookup limit to the
353// original one stored in db if the new mismatches with the old one.
354func (bc *BlockChain) SetTxLookupLimit(limit uint64) {
355	bc.txLookupLimit = limit
356}
357
358// TxLookupLimit retrieves the txlookup limit used by blockchain to prune
359// stale transaction indices.
360func (bc *BlockChain) TxLookupLimit() uint64 {
361	return bc.txLookupLimit
362}
363
364// SubscribeRemovedLogsEvent registers a subscription of RemovedLogsEvent.
365func (bc *BlockChain) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription {
366	return bc.scope.Track(bc.rmLogsFeed.Subscribe(ch))
367}
368
369// SubscribeChainEvent registers a subscription of ChainEvent.
370func (bc *BlockChain) SubscribeChainEvent(ch chan<- ChainEvent) event.Subscription {
371	return bc.scope.Track(bc.chainFeed.Subscribe(ch))
372}
373
374// SubscribeChainHeadEvent registers a subscription of ChainHeadEvent.
375func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription {
376	return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch))
377}
378
379// SubscribeChainSideEvent registers a subscription of ChainSideEvent.
380func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription {
381	return bc.scope.Track(bc.chainSideFeed.Subscribe(ch))
382}
383
384// SubscribeLogsEvent registers a subscription of []*types.Log.
385func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
386	return bc.scope.Track(bc.logsFeed.Subscribe(ch))
387}
388
389// SubscribeBlockProcessingEvent registers a subscription of bool where true means
390// block processing has started while false means it has stopped.
391func (bc *BlockChain) SubscribeBlockProcessingEvent(ch chan<- bool) event.Subscription {
392	return bc.scope.Track(bc.blockProcFeed.Subscribe(ch))
393}
394