Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
c641cff5
Unverified
Commit
c641cff5
authored
Oct 18, 2021
by
Marius van der Wijden
Committed by
GitHub
Oct 18, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: refactored blockchain.go (#23735)
parent
464885fa
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
387 additions
and
366 deletions
+387
-366
blockchain.go
core/blockchain.go
+0
-366
blockchain_reader.go
core/blockchain_reader.go
+387
-0
No files found.
core/blockchain.go
View file @
c641cff5
...
...
@@ -43,7 +43,6 @@ import (
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
lru
"github.com/hashicorp/golang-lru"
)
...
...
@@ -409,11 +408,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
return
bc
,
nil
}
// GetVMConfig returns the block chain VM config.
func
(
bc
*
BlockChain
)
GetVMConfig
()
*
vm
.
Config
{
return
&
bc
.
vmConfig
}
// empty returns an indicator whether the blockchain is empty.
// Note, it's a special case that we connect a non-empty ancient
// database with an empty node, so that we can plugin the ancient
...
...
@@ -666,53 +660,6 @@ func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error {
return
nil
}
// GasLimit returns the gas limit of the current HEAD block.
func
(
bc
*
BlockChain
)
GasLimit
()
uint64
{
return
bc
.
CurrentBlock
()
.
GasLimit
()
}
// CurrentBlock retrieves the current head block of the canonical chain. The
// block is retrieved from the blockchain's internal cache.
func
(
bc
*
BlockChain
)
CurrentBlock
()
*
types
.
Block
{
return
bc
.
currentBlock
.
Load
()
.
(
*
types
.
Block
)
}
// Snapshots returns the blockchain snapshot tree.
func
(
bc
*
BlockChain
)
Snapshots
()
*
snapshot
.
Tree
{
return
bc
.
snaps
}
// CurrentFastBlock retrieves the current fast-sync head block of the canonical
// chain. The block is retrieved from the blockchain's internal cache.
func
(
bc
*
BlockChain
)
CurrentFastBlock
()
*
types
.
Block
{
return
bc
.
currentFastBlock
.
Load
()
.
(
*
types
.
Block
)
}
// Validator returns the current validator.
func
(
bc
*
BlockChain
)
Validator
()
Validator
{
return
bc
.
validator
}
// Processor returns the current processor.
func
(
bc
*
BlockChain
)
Processor
()
Processor
{
return
bc
.
processor
}
// State returns a new mutable state based on the current HEAD block.
func
(
bc
*
BlockChain
)
State
()
(
*
state
.
StateDB
,
error
)
{
return
bc
.
StateAt
(
bc
.
CurrentBlock
()
.
Root
())
}
// StateAt returns a new mutable state based on a particular point in time.
func
(
bc
*
BlockChain
)
StateAt
(
root
common
.
Hash
)
(
*
state
.
StateDB
,
error
)
{
return
state
.
New
(
root
,
bc
.
stateCache
,
bc
.
snaps
)
}
// StateCache returns the caching database underpinning the blockchain instance.
func
(
bc
*
BlockChain
)
StateCache
()
state
.
Database
{
return
bc
.
stateCache
}
// Reset purges the entire blockchain, restoring it to its genesis state.
func
(
bc
*
BlockChain
)
Reset
()
error
{
return
bc
.
ResetWithGenesisBlock
(
bc
.
genesisBlock
)
...
...
@@ -819,194 +766,6 @@ func (bc *BlockChain) writeHeadBlock(block *types.Block) {
headBlockGauge
.
Update
(
int64
(
block
.
NumberU64
()))
}
// Genesis retrieves the chain's genesis block.
func
(
bc
*
BlockChain
)
Genesis
()
*
types
.
Block
{
return
bc
.
genesisBlock
}
// GetBody retrieves a block body (transactions and uncles) from the database by
// hash, caching it if found.
func
(
bc
*
BlockChain
)
GetBody
(
hash
common
.
Hash
)
*
types
.
Body
{
// Short circuit if the body's already in the cache, retrieve otherwise
if
cached
,
ok
:=
bc
.
bodyCache
.
Get
(
hash
);
ok
{
body
:=
cached
.
(
*
types
.
Body
)
return
body
}
number
:=
bc
.
hc
.
GetBlockNumber
(
hash
)
if
number
==
nil
{
return
nil
}
body
:=
rawdb
.
ReadBody
(
bc
.
db
,
hash
,
*
number
)
if
body
==
nil
{
return
nil
}
// Cache the found body for next time and return
bc
.
bodyCache
.
Add
(
hash
,
body
)
return
body
}
// GetBodyRLP retrieves a block body in RLP encoding from the database by hash,
// caching it if found.
func
(
bc
*
BlockChain
)
GetBodyRLP
(
hash
common
.
Hash
)
rlp
.
RawValue
{
// Short circuit if the body's already in the cache, retrieve otherwise
if
cached
,
ok
:=
bc
.
bodyRLPCache
.
Get
(
hash
);
ok
{
return
cached
.
(
rlp
.
RawValue
)
}
number
:=
bc
.
hc
.
GetBlockNumber
(
hash
)
if
number
==
nil
{
return
nil
}
body
:=
rawdb
.
ReadBodyRLP
(
bc
.
db
,
hash
,
*
number
)
if
len
(
body
)
==
0
{
return
nil
}
// Cache the found body for next time and return
bc
.
bodyRLPCache
.
Add
(
hash
,
body
)
return
body
}
// 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
}
return
rawdb
.
HasBody
(
bc
.
db
,
hash
,
number
)
}
// 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
)
}
// 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
}
// 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
,
number
uint64
)
bool
{
// Check first that the block itself is known
block
:=
bc
.
GetBlock
(
hash
,
number
)
if
block
==
nil
{
return
false
}
return
bc
.
HasState
(
block
.
Root
())
}
// GetBlock retrieves a block from the database by hash and number,
// caching it if found.
func
(
bc
*
BlockChain
)
GetBlock
(
hash
common
.
Hash
,
number
uint64
)
*
types
.
Block
{
// Short circuit if the block's already in the cache, retrieve otherwise
if
block
,
ok
:=
bc
.
blockCache
.
Get
(
hash
);
ok
{
return
block
.
(
*
types
.
Block
)
}
block
:=
rawdb
.
ReadBlock
(
bc
.
db
,
hash
,
number
)
if
block
==
nil
{
return
nil
}
// Cache the found block for next time and return
bc
.
blockCache
.
Add
(
block
.
Hash
(),
block
)
return
block
}
// GetBlockByHash retrieves a block from the database by hash, caching it if found.
func
(
bc
*
BlockChain
)
GetBlockByHash
(
hash
common
.
Hash
)
*
types
.
Block
{
number
:=
bc
.
hc
.
GetBlockNumber
(
hash
)
if
number
==
nil
{
return
nil
}
return
bc
.
GetBlock
(
hash
,
*
number
)
}
// GetBlockByNumber retrieves a block from the database by number, caching it
// (associated with its hash) if found.
func
(
bc
*
BlockChain
)
GetBlockByNumber
(
number
uint64
)
*
types
.
Block
{
hash
:=
rawdb
.
ReadCanonicalHash
(
bc
.
db
,
number
)
if
hash
==
(
common
.
Hash
{})
{
return
nil
}
return
bc
.
GetBlock
(
hash
,
number
)
}
// GetReceiptsByHash retrieves the receipts for all transactions in a given block.
func
(
bc
*
BlockChain
)
GetReceiptsByHash
(
hash
common
.
Hash
)
types
.
Receipts
{
if
receipts
,
ok
:=
bc
.
receiptsCache
.
Get
(
hash
);
ok
{
return
receipts
.
(
types
.
Receipts
)
}
number
:=
rawdb
.
ReadHeaderNumber
(
bc
.
db
,
hash
)
if
number
==
nil
{
return
nil
}
receipts
:=
rawdb
.
ReadReceipts
(
bc
.
db
,
hash
,
*
number
,
bc
.
chainConfig
)
if
receipts
==
nil
{
return
nil
}
bc
.
receiptsCache
.
Add
(
hash
,
receipts
)
return
receipts
}
// GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
// [deprecated by eth/62]
func
(
bc
*
BlockChain
)
GetBlocksFromHash
(
hash
common
.
Hash
,
n
int
)
(
blocks
[]
*
types
.
Block
)
{
number
:=
bc
.
hc
.
GetBlockNumber
(
hash
)
if
number
==
nil
{
return
nil
}
for
i
:=
0
;
i
<
n
;
i
++
{
block
:=
bc
.
GetBlock
(
hash
,
*
number
)
if
block
==
nil
{
break
}
blocks
=
append
(
blocks
,
block
)
hash
=
block
.
ParentHash
()
*
number
--
}
return
}
// GetUnclesInChain retrieves all the uncles from a given block backwards until
// a specific distance is reached.
func
(
bc
*
BlockChain
)
GetUnclesInChain
(
block
*
types
.
Block
,
length
int
)
[]
*
types
.
Header
{
uncles
:=
[]
*
types
.
Header
{}
for
i
:=
0
;
block
!=
nil
&&
i
<
length
;
i
++
{
uncles
=
append
(
uncles
,
block
.
Uncles
()
...
)
block
=
bc
.
GetBlock
(
block
.
ParentHash
(),
block
.
NumberU64
()
-
1
)
}
return
uncles
}
// TrieNode retrieves a blob of data associated with a trie node
// 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
)
}
// ContractCode retrieves a blob of data associated with a contract hash
// either from ephemeral in-memory cache, or from persistent storage.
func
(
bc
*
BlockChain
)
ContractCode
(
hash
common
.
Hash
)
([]
byte
,
error
)
{
return
bc
.
stateCache
.
ContractCode
(
common
.
Hash
{},
hash
)
}
// ContractCodeWithPrefix retrieves a blob of data associated with a contract
// hash either from ephemeral in-memory cache, or from persistent storage.
//
// If the code doesn't exist in the in-memory cache, check the storage with
// new code scheme.
func
(
bc
*
BlockChain
)
ContractCodeWithPrefix
(
hash
common
.
Hash
)
([]
byte
,
error
)
{
type
codeReader
interface
{
ContractCodeWithPrefix
(
addrHash
,
codeHash
common
.
Hash
)
([]
byte
,
error
)
}
return
bc
.
stateCache
.
(
codeReader
)
.
ContractCodeWithPrefix
(
common
.
Hash
{},
hash
)
}
// Stop stops the blockchain service. If any imports are currently in progress
// it will abort them using the procInterrupt.
func
(
bc
*
BlockChain
)
Stop
()
{
...
...
@@ -1390,18 +1149,6 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
return
0
,
nil
}
// SetTxLookupLimit is responsible for updating the txlookup limit to the
// original one stored in db if the new mismatches with the old one.
func
(
bc
*
BlockChain
)
SetTxLookupLimit
(
limit
uint64
)
{
bc
.
txLookupLimit
=
limit
}
// TxLookupLimit retrieves the txlookup limit used by blockchain to prune
// stale transaction indices.
func
(
bc
*
BlockChain
)
TxLookupLimit
()
uint64
{
return
bc
.
txLookupLimit
}
var
lastWrite
uint64
// writeBlockWithoutState writes only the block and its metadata to the database,
...
...
@@ -2398,116 +2145,3 @@ func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (i
_
,
err
:=
bc
.
hc
.
InsertHeaderChain
(
chain
,
start
)
return
0
,
err
}
// CurrentHeader retrieves the current head header of the canonical chain. The
// header is retrieved from the HeaderChain's internal cache.
func
(
bc
*
BlockChain
)
CurrentHeader
()
*
types
.
Header
{
return
bc
.
hc
.
CurrentHeader
()
}
// GetTd retrieves a block's total difficulty in the canonical chain from the
// database by hash and number, caching it if found.
func
(
bc
*
BlockChain
)
GetTd
(
hash
common
.
Hash
,
number
uint64
)
*
big
.
Int
{
return
bc
.
hc
.
GetTd
(
hash
,
number
)
}
// GetHeader retrieves a block header from the database by hash and number,
// caching it if found.
func
(
bc
*
BlockChain
)
GetHeader
(
hash
common
.
Hash
,
number
uint64
)
*
types
.
Header
{
// Blockchain might have cached the whole block, only if not go to headerchain
if
block
,
ok
:=
bc
.
blockCache
.
Get
(
hash
);
ok
{
return
block
.
(
*
types
.
Block
)
.
Header
()
}
return
bc
.
hc
.
GetHeader
(
hash
,
number
)
}
// GetHeaderByHash retrieves a block header from the database by hash, caching it if
// found.
func
(
bc
*
BlockChain
)
GetHeaderByHash
(
hash
common
.
Hash
)
*
types
.
Header
{
// Blockchain might have cached the whole block, only if not go to headerchain
if
block
,
ok
:=
bc
.
blockCache
.
Get
(
hash
);
ok
{
return
block
.
(
*
types
.
Block
)
.
Header
()
}
return
bc
.
hc
.
GetHeaderByHash
(
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
,
number
uint64
)
bool
{
return
bc
.
hc
.
HasHeader
(
hash
,
number
)
}
// GetCanonicalHash returns the canonical hash for a given block number
func
(
bc
*
BlockChain
)
GetCanonicalHash
(
number
uint64
)
common
.
Hash
{
return
bc
.
hc
.
GetCanonicalHash
(
number
)
}
// 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
)
{
return
bc
.
hc
.
GetAncestor
(
hash
,
number
,
ancestor
,
maxNonCanonical
)
}
// GetHeaderByNumber retrieves a block header from the database by number,
// caching it (associated with its hash) if found.
func
(
bc
*
BlockChain
)
GetHeaderByNumber
(
number
uint64
)
*
types
.
Header
{
return
bc
.
hc
.
GetHeaderByNumber
(
number
)
}
// GetTransactionLookup retrieves the lookup associate with the given transaction
// hash from the cache or database.
func
(
bc
*
BlockChain
)
GetTransactionLookup
(
hash
common
.
Hash
)
*
rawdb
.
LegacyTxLookupEntry
{
// Short circuit if the txlookup already in the cache, retrieve otherwise
if
lookup
,
exist
:=
bc
.
txLookupCache
.
Get
(
hash
);
exist
{
return
lookup
.
(
*
rawdb
.
LegacyTxLookupEntry
)
}
tx
,
blockHash
,
blockNumber
,
txIndex
:=
rawdb
.
ReadTransaction
(
bc
.
db
,
hash
)
if
tx
==
nil
{
return
nil
}
lookup
:=
&
rawdb
.
LegacyTxLookupEntry
{
BlockHash
:
blockHash
,
BlockIndex
:
blockNumber
,
Index
:
txIndex
}
bc
.
txLookupCache
.
Add
(
hash
,
lookup
)
return
lookup
}
// Config retrieves the chain's fork configuration.
func
(
bc
*
BlockChain
)
Config
()
*
params
.
ChainConfig
{
return
bc
.
chainConfig
}
// Engine retrieves the blockchain's consensus engine.
func
(
bc
*
BlockChain
)
Engine
()
consensus
.
Engine
{
return
bc
.
engine
}
// 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
))
}
// SubscribeBlockProcessingEvent registers a subscription of bool where true means
// block processing has started while false means it has stopped.
func
(
bc
*
BlockChain
)
SubscribeBlockProcessingEvent
(
ch
chan
<-
bool
)
event
.
Subscription
{
return
bc
.
scope
.
Track
(
bc
.
blockProcFeed
.
Subscribe
(
ch
))
}
core/blockchain_reader.go
0 → 100644
View file @
c641cff5
// Copyright 2021 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// 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.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
core
import
(
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/state/snapshot"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
)
// CurrentHeader retrieves the current head header of the canonical chain. The
// header is retrieved from the HeaderChain's internal cache.
func
(
bc
*
BlockChain
)
CurrentHeader
()
*
types
.
Header
{
return
bc
.
hc
.
CurrentHeader
()
}
// CurrentBlock retrieves the current head block of the canonical chain. The
// block is retrieved from the blockchain's internal cache.
func
(
bc
*
BlockChain
)
CurrentBlock
()
*
types
.
Block
{
return
bc
.
currentBlock
.
Load
()
.
(
*
types
.
Block
)
}
// CurrentFastBlock retrieves the current fast-sync head block of the canonical
// chain. The block is retrieved from the blockchain's internal cache.
func
(
bc
*
BlockChain
)
CurrentFastBlock
()
*
types
.
Block
{
return
bc
.
currentFastBlock
.
Load
()
.
(
*
types
.
Block
)
}
// HasHeader checks if a block header is present in the database or not, caching
// it if present.
func
(
bc
*
BlockChain
)
HasHeader
(
hash
common
.
Hash
,
number
uint64
)
bool
{
return
bc
.
hc
.
HasHeader
(
hash
,
number
)
}
// GetHeader retrieves a block header from the database by hash and number,
// caching it if found.
func
(
bc
*
BlockChain
)
GetHeader
(
hash
common
.
Hash
,
number
uint64
)
*
types
.
Header
{
return
bc
.
hc
.
GetHeader
(
hash
,
number
)
}
// GetHeaderByHash retrieves a block header from the database by hash, caching it if
// found.
func
(
bc
*
BlockChain
)
GetHeaderByHash
(
hash
common
.
Hash
)
*
types
.
Header
{
return
bc
.
hc
.
GetHeaderByHash
(
hash
)
}
// GetHeaderByNumber retrieves a block header from the database by number,
// caching it (associated with its hash) if found.
func
(
bc
*
BlockChain
)
GetHeaderByNumber
(
number
uint64
)
*
types
.
Header
{
return
bc
.
hc
.
GetHeaderByNumber
(
number
)
}
// GetBody retrieves a block body (transactions and uncles) from the database by
// hash, caching it if found.
func
(
bc
*
BlockChain
)
GetBody
(
hash
common
.
Hash
)
*
types
.
Body
{
// Short circuit if the body's already in the cache, retrieve otherwise
if
cached
,
ok
:=
bc
.
bodyCache
.
Get
(
hash
);
ok
{
body
:=
cached
.
(
*
types
.
Body
)
return
body
}
number
:=
bc
.
hc
.
GetBlockNumber
(
hash
)
if
number
==
nil
{
return
nil
}
body
:=
rawdb
.
ReadBody
(
bc
.
db
,
hash
,
*
number
)
if
body
==
nil
{
return
nil
}
// Cache the found body for next time and return
bc
.
bodyCache
.
Add
(
hash
,
body
)
return
body
}
// GetBodyRLP retrieves a block body in RLP encoding from the database by hash,
// caching it if found.
func
(
bc
*
BlockChain
)
GetBodyRLP
(
hash
common
.
Hash
)
rlp
.
RawValue
{
// Short circuit if the body's already in the cache, retrieve otherwise
if
cached
,
ok
:=
bc
.
bodyRLPCache
.
Get
(
hash
);
ok
{
return
cached
.
(
rlp
.
RawValue
)
}
number
:=
bc
.
hc
.
GetBlockNumber
(
hash
)
if
number
==
nil
{
return
nil
}
body
:=
rawdb
.
ReadBodyRLP
(
bc
.
db
,
hash
,
*
number
)
if
len
(
body
)
==
0
{
return
nil
}
// Cache the found body for next time and return
bc
.
bodyRLPCache
.
Add
(
hash
,
body
)
return
body
}
// 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
}
return
rawdb
.
HasBody
(
bc
.
db
,
hash
,
number
)
}
// 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
)
}
// GetBlock retrieves a block from the database by hash and number,
// caching it if found.
func
(
bc
*
BlockChain
)
GetBlock
(
hash
common
.
Hash
,
number
uint64
)
*
types
.
Block
{
// Short circuit if the block's already in the cache, retrieve otherwise
if
block
,
ok
:=
bc
.
blockCache
.
Get
(
hash
);
ok
{
return
block
.
(
*
types
.
Block
)
}
block
:=
rawdb
.
ReadBlock
(
bc
.
db
,
hash
,
number
)
if
block
==
nil
{
return
nil
}
// Cache the found block for next time and return
bc
.
blockCache
.
Add
(
block
.
Hash
(),
block
)
return
block
}
// GetBlockByHash retrieves a block from the database by hash, caching it if found.
func
(
bc
*
BlockChain
)
GetBlockByHash
(
hash
common
.
Hash
)
*
types
.
Block
{
number
:=
bc
.
hc
.
GetBlockNumber
(
hash
)
if
number
==
nil
{
return
nil
}
return
bc
.
GetBlock
(
hash
,
*
number
)
}
// GetBlockByNumber retrieves a block from the database by number, caching it
// (associated with its hash) if found.
func
(
bc
*
BlockChain
)
GetBlockByNumber
(
number
uint64
)
*
types
.
Block
{
hash
:=
rawdb
.
ReadCanonicalHash
(
bc
.
db
,
number
)
if
hash
==
(
common
.
Hash
{})
{
return
nil
}
return
bc
.
GetBlock
(
hash
,
number
)
}
// GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
// [deprecated by eth/62]
func
(
bc
*
BlockChain
)
GetBlocksFromHash
(
hash
common
.
Hash
,
n
int
)
(
blocks
[]
*
types
.
Block
)
{
number
:=
bc
.
hc
.
GetBlockNumber
(
hash
)
if
number
==
nil
{
return
nil
}
for
i
:=
0
;
i
<
n
;
i
++
{
block
:=
bc
.
GetBlock
(
hash
,
*
number
)
if
block
==
nil
{
break
}
blocks
=
append
(
blocks
,
block
)
hash
=
block
.
ParentHash
()
*
number
--
}
return
}
// GetReceiptsByHash retrieves the receipts for all transactions in a given block.
func
(
bc
*
BlockChain
)
GetReceiptsByHash
(
hash
common
.
Hash
)
types
.
Receipts
{
if
receipts
,
ok
:=
bc
.
receiptsCache
.
Get
(
hash
);
ok
{
return
receipts
.
(
types
.
Receipts
)
}
number
:=
rawdb
.
ReadHeaderNumber
(
bc
.
db
,
hash
)
if
number
==
nil
{
return
nil
}
receipts
:=
rawdb
.
ReadReceipts
(
bc
.
db
,
hash
,
*
number
,
bc
.
chainConfig
)
if
receipts
==
nil
{
return
nil
}
bc
.
receiptsCache
.
Add
(
hash
,
receipts
)
return
receipts
}
// GetUnclesInChain retrieves all the uncles from a given block backwards until
// a specific distance is reached.
func
(
bc
*
BlockChain
)
GetUnclesInChain
(
block
*
types
.
Block
,
length
int
)
[]
*
types
.
Header
{
uncles
:=
[]
*
types
.
Header
{}
for
i
:=
0
;
block
!=
nil
&&
i
<
length
;
i
++
{
uncles
=
append
(
uncles
,
block
.
Uncles
()
...
)
block
=
bc
.
GetBlock
(
block
.
ParentHash
(),
block
.
NumberU64
()
-
1
)
}
return
uncles
}
// GetCanonicalHash returns the canonical hash for a given block number
func
(
bc
*
BlockChain
)
GetCanonicalHash
(
number
uint64
)
common
.
Hash
{
return
bc
.
hc
.
GetCanonicalHash
(
number
)
}
// 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
)
{
return
bc
.
hc
.
GetAncestor
(
hash
,
number
,
ancestor
,
maxNonCanonical
)
}
// GetTransactionLookup retrieves the lookup associate with the given transaction
// hash from the cache or database.
func
(
bc
*
BlockChain
)
GetTransactionLookup
(
hash
common
.
Hash
)
*
rawdb
.
LegacyTxLookupEntry
{
// Short circuit if the txlookup already in the cache, retrieve otherwise
if
lookup
,
exist
:=
bc
.
txLookupCache
.
Get
(
hash
);
exist
{
return
lookup
.
(
*
rawdb
.
LegacyTxLookupEntry
)
}
tx
,
blockHash
,
blockNumber
,
txIndex
:=
rawdb
.
ReadTransaction
(
bc
.
db
,
hash
)
if
tx
==
nil
{
return
nil
}
lookup
:=
&
rawdb
.
LegacyTxLookupEntry
{
BlockHash
:
blockHash
,
BlockIndex
:
blockNumber
,
Index
:
txIndex
}
bc
.
txLookupCache
.
Add
(
hash
,
lookup
)
return
lookup
}
// GetTd retrieves a block's total difficulty in the canonical chain from the
// database by hash and number, caching it if found.
func
(
bc
*
BlockChain
)
GetTd
(
hash
common
.
Hash
,
number
uint64
)
*
big
.
Int
{
return
bc
.
hc
.
GetTd
(
hash
,
number
)
}
// 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
}
// 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
,
number
uint64
)
bool
{
// Check first that the block itself is known
block
:=
bc
.
GetBlock
(
hash
,
number
)
if
block
==
nil
{
return
false
}
return
bc
.
HasState
(
block
.
Root
())
}
// TrieNode retrieves a blob of data associated with a trie node
// 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
)
}
// ContractCode retrieves a blob of data associated with a contract hash
// either from ephemeral in-memory cache, or from persistent storage.
func
(
bc
*
BlockChain
)
ContractCode
(
hash
common
.
Hash
)
([]
byte
,
error
)
{
return
bc
.
stateCache
.
ContractCode
(
common
.
Hash
{},
hash
)
}
// ContractCodeWithPrefix retrieves a blob of data associated with a contract
// hash either from ephemeral in-memory cache, or from persistent storage.
//
// If the code doesn't exist in the in-memory cache, check the storage with
// new code scheme.
func
(
bc
*
BlockChain
)
ContractCodeWithPrefix
(
hash
common
.
Hash
)
([]
byte
,
error
)
{
type
codeReader
interface
{
ContractCodeWithPrefix
(
addrHash
,
codeHash
common
.
Hash
)
([]
byte
,
error
)
}
return
bc
.
stateCache
.
(
codeReader
)
.
ContractCodeWithPrefix
(
common
.
Hash
{},
hash
)
}
// State returns a new mutable state based on the current HEAD block.
func
(
bc
*
BlockChain
)
State
()
(
*
state
.
StateDB
,
error
)
{
return
bc
.
StateAt
(
bc
.
CurrentBlock
()
.
Root
())
}
// StateAt returns a new mutable state based on a particular point in time.
func
(
bc
*
BlockChain
)
StateAt
(
root
common
.
Hash
)
(
*
state
.
StateDB
,
error
)
{
return
state
.
New
(
root
,
bc
.
stateCache
,
bc
.
snaps
)
}
// Config retrieves the chain's fork configuration.
func
(
bc
*
BlockChain
)
Config
()
*
params
.
ChainConfig
{
return
bc
.
chainConfig
}
// Engine retrieves the blockchain's consensus engine.
func
(
bc
*
BlockChain
)
Engine
()
consensus
.
Engine
{
return
bc
.
engine
}
// Snapshots returns the blockchain snapshot tree.
func
(
bc
*
BlockChain
)
Snapshots
()
*
snapshot
.
Tree
{
return
bc
.
snaps
}
// Validator returns the current validator.
func
(
bc
*
BlockChain
)
Validator
()
Validator
{
return
bc
.
validator
}
// Processor returns the current processor.
func
(
bc
*
BlockChain
)
Processor
()
Processor
{
return
bc
.
processor
}
// StateCache returns the caching database underpinning the blockchain instance.
func
(
bc
*
BlockChain
)
StateCache
()
state
.
Database
{
return
bc
.
stateCache
}
// GasLimit returns the gas limit of the current HEAD block.
func
(
bc
*
BlockChain
)
GasLimit
()
uint64
{
return
bc
.
CurrentBlock
()
.
GasLimit
()
}
// Genesis retrieves the chain's genesis block.
func
(
bc
*
BlockChain
)
Genesis
()
*
types
.
Block
{
return
bc
.
genesisBlock
}
// GetVMConfig returns the block chain VM config.
func
(
bc
*
BlockChain
)
GetVMConfig
()
*
vm
.
Config
{
return
&
bc
.
vmConfig
}
// SetTxLookupLimit is responsible for updating the txlookup limit to the
// original one stored in db if the new mismatches with the old one.
func
(
bc
*
BlockChain
)
SetTxLookupLimit
(
limit
uint64
)
{
bc
.
txLookupLimit
=
limit
}
// TxLookupLimit retrieves the txlookup limit used by blockchain to prune
// stale transaction indices.
func
(
bc
*
BlockChain
)
TxLookupLimit
()
uint64
{
return
bc
.
txLookupLimit
}
// 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
))
}
// SubscribeBlockProcessingEvent registers a subscription of bool where true means
// block processing has started while false means it has stopped.
func
(
bc
*
BlockChain
)
SubscribeBlockProcessingEvent
(
ch
chan
<-
bool
)
event
.
Subscription
{
return
bc
.
scope
.
Track
(
bc
.
blockProcFeed
.
Subscribe
(
ch
))
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment