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
daad2b25
Commit
daad2b25
authored
Mar 10, 2016
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: cache fresh headers and tds to avoid db trashing
parent
8b58cd01
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
52 additions
and
20 deletions
+52
-20
blockchain.go
core/blockchain.go
+2
-2
headerchain.go
core/headerchain.go
+50
-18
No files found.
core/blockchain.go
View file @
daad2b25
...
...
@@ -368,7 +368,7 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) {
defer
bc
.
mu
.
Unlock
()
// Prepare the genesis block and reinitialise the chain
if
err
:=
WriteTd
(
bc
.
chainDb
,
genesis
.
Hash
(),
genesis
.
Difficulty
());
err
!=
nil
{
if
err
:=
bc
.
hc
.
WriteTd
(
genesis
.
Hash
(),
genesis
.
Difficulty
());
err
!=
nil
{
glog
.
Fatalf
(
"failed to write genesis block TD: %v"
,
err
)
}
if
err
:=
WriteBlock
(
bc
.
chainDb
,
genesis
);
err
!=
nil
{
...
...
@@ -788,7 +788,7 @@ func (self *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err
status
=
SideStatTy
}
// Irrelevant of the canonical status, write the block itself to the database
if
err
:=
WriteTd
(
self
.
chainDb
,
block
.
Hash
(),
externTd
);
err
!=
nil
{
if
err
:=
self
.
hc
.
WriteTd
(
block
.
Hash
(),
externTd
);
err
!=
nil
{
glog
.
Fatalf
(
"failed to write block total difficulty: %v"
,
err
)
}
if
err
:=
WriteBlock
(
self
.
chainDb
,
block
);
err
!=
nil
{
...
...
core/headerchain.go
View file @
daad2b25
...
...
@@ -43,11 +43,13 @@ type HeaderChain struct {
chainDb
ethdb
.
Database
genesisHeader
*
types
.
Header
currentHeader
*
types
.
Header
// Current head of the header chain (may be above the block chain!)
headerCache
*
lru
.
Cache
// Cache for the most recent block headers
tdCache
*
lru
.
Cache
// Cache for the most recent block total difficulties
currentHeader
*
types
.
Header
// Current head of the header chain (may be above the block chain!)
currentHeaderHash
common
.
Hash
// Hash of the current head of the header chain (prevent recomputing all the time)
procInterrupt
func
()
bool
headerCache
*
lru
.
Cache
// Cache for the most recent block headers
tdCache
*
lru
.
Cache
// Cache for the most recent block total difficulties
procInterrupt
func
()
bool
rand
*
mrand
.
Rand
getValidator
getHeaderValidatorFn
...
...
@@ -95,6 +97,7 @@ func NewHeaderChain(chainDb ethdb.Database, getValidator getHeaderValidatorFn, p
hc
.
currentHeader
=
chead
}
}
hc
.
currentHeaderHash
=
hc
.
currentHeader
.
Hash
()
return
hc
,
nil
}
...
...
@@ -109,12 +112,17 @@ func NewHeaderChain(chainDb ethdb.Database, getValidator getHeaderValidatorFn, p
// in two scenarios: pure-header mode of operation (light clients), or properly
// separated header/block phases (non-archive clients).
func
(
hc
*
HeaderChain
)
WriteHeader
(
header
*
types
.
Header
)
(
status
WriteStatus
,
err
error
)
{
// Cache some values to prevent constant recalculation
var
(
hash
=
header
.
Hash
()
number
=
header
.
Number
.
Uint64
()
)
// Calculate the total difficulty of the header
ptd
:=
hc
.
GetTd
(
header
.
ParentHash
)
if
ptd
==
nil
{
return
NonStatTy
,
ParentError
(
header
.
ParentHash
)
}
localTd
:=
hc
.
GetTd
(
hc
.
currentHeader
.
Hash
()
)
localTd
:=
hc
.
GetTd
(
hc
.
currentHeader
Hash
)
externTd
:=
new
(
big
.
Int
)
.
Add
(
header
.
Difficulty
,
ptd
)
// If the total difficulty is higher than our known, add it to the canonical chain
...
...
@@ -122,34 +130,44 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er
// Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf
if
externTd
.
Cmp
(
localTd
)
>
0
||
(
externTd
.
Cmp
(
localTd
)
==
0
&&
mrand
.
Float64
()
<
0.5
)
{
// Delete any canonical number assignments above the new head
for
i
:=
header
.
Number
.
Uint64
()
+
1
;
GetCanonicalHash
(
hc
.
chainDb
,
i
)
!=
(
common
.
Hash
{});
i
++
{
for
i
:=
number
+
1
;
GetCanonicalHash
(
hc
.
chainDb
,
i
)
!=
(
common
.
Hash
{});
i
++
{
DeleteCanonicalHash
(
hc
.
chainDb
,
i
)
}
// Overwrite any stale canonical number assignments
head
:=
hc
.
GetHeader
(
header
.
ParentHash
)
for
GetCanonicalHash
(
hc
.
chainDb
,
head
.
Number
.
Uint64
())
!=
head
.
Hash
()
{
WriteCanonicalHash
(
hc
.
chainDb
,
head
.
Hash
(),
head
.
Number
.
Uint64
())
head
=
hc
.
GetHeader
(
head
.
ParentHash
)
var
(
headHash
=
header
.
ParentHash
headHeader
=
hc
.
GetHeader
(
headHash
)
headNumber
=
headHeader
.
Number
.
Uint64
()
)
for
GetCanonicalHash
(
hc
.
chainDb
,
headNumber
)
!=
headHash
{
WriteCanonicalHash
(
hc
.
chainDb
,
headHash
,
headNumber
)
headHash
=
headHeader
.
ParentHash
headHeader
=
hc
.
GetHeader
(
headHash
)
headNumber
=
headHeader
.
Number
.
Uint64
()
}
// Extend the canonical chain with the new header
if
err
:=
WriteCanonicalHash
(
hc
.
chainDb
,
h
eader
.
Hash
(),
header
.
Number
.
Uint64
()
);
err
!=
nil
{
if
err
:=
WriteCanonicalHash
(
hc
.
chainDb
,
h
ash
,
number
);
err
!=
nil
{
glog
.
Fatalf
(
"failed to insert header number: %v"
,
err
)
}
if
err
:=
WriteHeadHeaderHash
(
hc
.
chainDb
,
h
eader
.
Hash
()
);
err
!=
nil
{
if
err
:=
WriteHeadHeaderHash
(
hc
.
chainDb
,
h
ash
);
err
!=
nil
{
glog
.
Fatalf
(
"failed to insert head header hash: %v"
,
err
)
}
hc
.
currentHeader
=
types
.
CopyHeader
(
header
)
hc
.
currentHeaderHash
,
hc
.
currentHeader
=
hash
,
types
.
CopyHeader
(
header
)
status
=
CanonStatTy
}
else
{
status
=
SideStatTy
}
// Irrelevant of the canonical status, write the header itself to the database
if
err
:=
WriteTd
(
hc
.
chainDb
,
header
.
Hash
()
,
externTd
);
err
!=
nil
{
if
err
:=
hc
.
WriteTd
(
hash
,
externTd
);
err
!=
nil
{
glog
.
Fatalf
(
"failed to write header total difficulty: %v"
,
err
)
}
if
err
:=
WriteHeader
(
hc
.
chainDb
,
header
);
err
!=
nil
{
glog
.
Fatalf
(
"failed to write header contents: %v"
,
err
)
}
hc
.
headerCache
.
Add
(
hash
,
header
)
return
}
...
...
@@ -285,10 +303,11 @@ func (hc *HeaderChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []co
// Iterate the headers until enough is collected or the genesis reached
chain
:=
make
([]
common
.
Hash
,
0
,
max
)
for
i
:=
uint64
(
0
);
i
<
max
;
i
++
{
if
header
=
hc
.
GetHeader
(
header
.
ParentHash
);
header
==
nil
{
next
:=
header
.
ParentHash
if
header
=
hc
.
GetHeader
(
next
);
header
==
nil
{
break
}
chain
=
append
(
chain
,
header
.
Hash
()
)
chain
=
append
(
chain
,
next
)
if
header
.
Number
.
Cmp
(
common
.
Big0
)
==
0
{
break
}
...
...
@@ -312,6 +331,16 @@ func (hc *HeaderChain) GetTd(hash common.Hash) *big.Int {
return
td
}
// WriteTd stores a block's total difficulty into the database, also caching it
// along the way.
func
(
hc
*
HeaderChain
)
WriteTd
(
hash
common
.
Hash
,
td
*
big
.
Int
)
error
{
if
err
:=
WriteTd
(
hc
.
chainDb
,
hash
,
td
);
err
!=
nil
{
return
err
}
hc
.
tdCache
.
Add
(
hash
,
new
(
big
.
Int
)
.
Set
(
td
))
return
nil
}
// GetHeader retrieves a block header from the database by hash, caching it if
// found.
func
(
hc
*
HeaderChain
)
GetHeader
(
hash
common
.
Hash
)
*
types
.
Header
{
...
...
@@ -324,7 +353,7 @@ func (hc *HeaderChain) GetHeader(hash common.Hash) *types.Header {
return
nil
}
// Cache the found header for next time and return
hc
.
headerCache
.
Add
(
h
eader
.
Hash
()
,
header
)
hc
.
headerCache
.
Add
(
h
ash
,
header
)
return
header
}
...
...
@@ -356,6 +385,7 @@ func (hc *HeaderChain) SetCurrentHeader(head *types.Header) {
glog
.
Fatalf
(
"failed to insert head header hash: %v"
,
err
)
}
hc
.
currentHeader
=
head
hc
.
currentHeaderHash
=
head
.
Hash
()
}
// DeleteCallback is a callback function that is called by SetHead before
...
...
@@ -390,7 +420,9 @@ func (hc *HeaderChain) SetHead(head uint64, delFn DeleteCallback) {
if
hc
.
currentHeader
==
nil
{
hc
.
currentHeader
=
hc
.
genesisHeader
}
if
err
:=
WriteHeadHeaderHash
(
hc
.
chainDb
,
hc
.
currentHeader
.
Hash
());
err
!=
nil
{
hc
.
currentHeaderHash
=
hc
.
currentHeader
.
Hash
()
if
err
:=
WriteHeadHeaderHash
(
hc
.
chainDb
,
hc
.
currentHeaderHash
);
err
!=
nil
{
glog
.
Fatalf
(
"failed to reset head header hash: %v"
,
err
)
}
}
...
...
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