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
6f714ed7
Commit
6f714ed7
authored
Feb 07, 2019
by
Matthew Halpern
Committed by
Péter Szilágyi
Feb 07, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
light: make chain receiver names consistent (#18997)
parent
7c339ff4
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
143 additions
and
143 deletions
+143
-143
lightchain.go
light/lightchain.go
+143
-143
No files found.
light/lightchain.go
View file @
6f714ed7
...
...
@@ -117,45 +117,45 @@ func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.
}
// addTrustedCheckpoint adds a trusted checkpoint to the blockchain
func
(
self
*
LightChain
)
addTrustedCheckpoint
(
cp
*
params
.
TrustedCheckpoint
)
{
if
self
.
odr
.
ChtIndexer
()
!=
nil
{
StoreChtRoot
(
self
.
chainDb
,
cp
.
SectionIndex
,
cp
.
SectionHead
,
cp
.
CHTRoot
)
self
.
odr
.
ChtIndexer
()
.
AddCheckpoint
(
cp
.
SectionIndex
,
cp
.
SectionHead
)
func
(
lc
*
LightChain
)
addTrustedCheckpoint
(
cp
*
params
.
TrustedCheckpoint
)
{
if
lc
.
odr
.
ChtIndexer
()
!=
nil
{
StoreChtRoot
(
lc
.
chainDb
,
cp
.
SectionIndex
,
cp
.
SectionHead
,
cp
.
CHTRoot
)
lc
.
odr
.
ChtIndexer
()
.
AddCheckpoint
(
cp
.
SectionIndex
,
cp
.
SectionHead
)
}
if
self
.
odr
.
BloomTrieIndexer
()
!=
nil
{
StoreBloomTrieRoot
(
self
.
chainDb
,
cp
.
SectionIndex
,
cp
.
SectionHead
,
cp
.
BloomRoot
)
self
.
odr
.
BloomTrieIndexer
()
.
AddCheckpoint
(
cp
.
SectionIndex
,
cp
.
SectionHead
)
if
lc
.
odr
.
BloomTrieIndexer
()
!=
nil
{
StoreBloomTrieRoot
(
lc
.
chainDb
,
cp
.
SectionIndex
,
cp
.
SectionHead
,
cp
.
BloomRoot
)
lc
.
odr
.
BloomTrieIndexer
()
.
AddCheckpoint
(
cp
.
SectionIndex
,
cp
.
SectionHead
)
}
if
self
.
odr
.
BloomIndexer
()
!=
nil
{
self
.
odr
.
BloomIndexer
()
.
AddCheckpoint
(
cp
.
SectionIndex
,
cp
.
SectionHead
)
if
lc
.
odr
.
BloomIndexer
()
!=
nil
{
lc
.
odr
.
BloomIndexer
()
.
AddCheckpoint
(
cp
.
SectionIndex
,
cp
.
SectionHead
)
}
log
.
Info
(
"Added trusted checkpoint"
,
"chain"
,
cp
.
Name
,
"block"
,
(
cp
.
SectionIndex
+
1
)
*
self
.
indexerConfig
.
ChtSize
-
1
,
"hash"
,
cp
.
SectionHead
)
log
.
Info
(
"Added trusted checkpoint"
,
"chain"
,
cp
.
Name
,
"block"
,
(
cp
.
SectionIndex
+
1
)
*
lc
.
indexerConfig
.
ChtSize
-
1
,
"hash"
,
cp
.
SectionHead
)
}
func
(
self
*
LightChain
)
getProcInterrupt
()
bool
{
return
atomic
.
LoadInt32
(
&
self
.
procInterrupt
)
==
1
func
(
lc
*
LightChain
)
getProcInterrupt
()
bool
{
return
atomic
.
LoadInt32
(
&
lc
.
procInterrupt
)
==
1
}
// Odr returns the ODR backend of the chain
func
(
self
*
LightChain
)
Odr
()
OdrBackend
{
return
self
.
odr
func
(
lc
*
LightChain
)
Odr
()
OdrBackend
{
return
lc
.
odr
}
// loadLastState loads the last known chain state from the database. This method
// assumes that the chain manager mutex is held.
func
(
self
*
LightChain
)
loadLastState
()
error
{
if
head
:=
rawdb
.
ReadHeadHeaderHash
(
self
.
chainDb
);
head
==
(
common
.
Hash
{})
{
func
(
lc
*
LightChain
)
loadLastState
()
error
{
if
head
:=
rawdb
.
ReadHeadHeaderHash
(
lc
.
chainDb
);
head
==
(
common
.
Hash
{})
{
// Corrupt or empty database, init from scratch
self
.
Reset
()
lc
.
Reset
()
}
else
{
if
header
:=
self
.
GetHeaderByHash
(
head
);
header
!=
nil
{
self
.
hc
.
SetCurrentHeader
(
header
)
if
header
:=
lc
.
GetHeaderByHash
(
head
);
header
!=
nil
{
lc
.
hc
.
SetCurrentHeader
(
header
)
}
}
// Issue a status log and return
header
:=
self
.
hc
.
CurrentHeader
()
headerTd
:=
self
.
GetTd
(
header
.
Hash
(),
header
.
Number
.
Uint64
())
header
:=
lc
.
hc
.
CurrentHeader
()
headerTd
:=
lc
.
GetTd
(
header
.
Hash
(),
header
.
Number
.
Uint64
())
log
.
Info
(
"Loaded most recent local header"
,
"number"
,
header
.
Number
,
"hash"
,
header
.
Hash
(),
"td"
,
headerTd
,
"age"
,
common
.
PrettyAge
(
time
.
Unix
(
header
.
Time
.
Int64
(),
0
)))
return
nil
...
...
@@ -163,181 +163,181 @@ func (self *LightChain) loadLastState() error {
// SetHead rewinds the local chain to a new head. Everything above the new
// head will be deleted and the new one set.
func
(
b
c
*
LightChain
)
SetHead
(
head
uint64
)
{
b
c
.
chainmu
.
Lock
()
defer
b
c
.
chainmu
.
Unlock
()
func
(
l
c
*
LightChain
)
SetHead
(
head
uint64
)
{
l
c
.
chainmu
.
Lock
()
defer
l
c
.
chainmu
.
Unlock
()
b
c
.
hc
.
SetHead
(
head
,
nil
)
b
c
.
loadLastState
()
l
c
.
hc
.
SetHead
(
head
,
nil
)
l
c
.
loadLastState
()
}
// GasLimit returns the gas limit of the current HEAD block.
func
(
self
*
LightChain
)
GasLimit
()
uint64
{
return
self
.
hc
.
CurrentHeader
()
.
GasLimit
func
(
lc
*
LightChain
)
GasLimit
()
uint64
{
return
lc
.
hc
.
CurrentHeader
()
.
GasLimit
}
// Reset purges the entire blockchain, restoring it to its genesis state.
func
(
b
c
*
LightChain
)
Reset
()
{
bc
.
ResetWithGenesisBlock
(
b
c
.
genesisBlock
)
func
(
l
c
*
LightChain
)
Reset
()
{
lc
.
ResetWithGenesisBlock
(
l
c
.
genesisBlock
)
}
// ResetWithGenesisBlock purges the entire blockchain, restoring it to the
// specified genesis state.
func
(
b
c
*
LightChain
)
ResetWithGenesisBlock
(
genesis
*
types
.
Block
)
{
func
(
l
c
*
LightChain
)
ResetWithGenesisBlock
(
genesis
*
types
.
Block
)
{
// Dump the entire block chain and purge the caches
b
c
.
SetHead
(
0
)
l
c
.
SetHead
(
0
)
b
c
.
chainmu
.
Lock
()
defer
b
c
.
chainmu
.
Unlock
()
l
c
.
chainmu
.
Lock
()
defer
l
c
.
chainmu
.
Unlock
()
// Prepare the genesis block and reinitialise the chain
rawdb
.
WriteTd
(
b
c
.
chainDb
,
genesis
.
Hash
(),
genesis
.
NumberU64
(),
genesis
.
Difficulty
())
rawdb
.
WriteBlock
(
b
c
.
chainDb
,
genesis
)
rawdb
.
WriteTd
(
l
c
.
chainDb
,
genesis
.
Hash
(),
genesis
.
NumberU64
(),
genesis
.
Difficulty
())
rawdb
.
WriteBlock
(
l
c
.
chainDb
,
genesis
)
b
c
.
genesisBlock
=
genesis
bc
.
hc
.
SetGenesis
(
b
c
.
genesisBlock
.
Header
())
bc
.
hc
.
SetCurrentHeader
(
b
c
.
genesisBlock
.
Header
())
l
c
.
genesisBlock
=
genesis
lc
.
hc
.
SetGenesis
(
l
c
.
genesisBlock
.
Header
())
lc
.
hc
.
SetCurrentHeader
(
l
c
.
genesisBlock
.
Header
())
}
// Accessors
// Engine retrieves the light chain's consensus engine.
func
(
bc
*
LightChain
)
Engine
()
consensus
.
Engine
{
return
b
c
.
engine
}
func
(
lc
*
LightChain
)
Engine
()
consensus
.
Engine
{
return
l
c
.
engine
}
// Genesis returns the genesis block
func
(
b
c
*
LightChain
)
Genesis
()
*
types
.
Block
{
return
b
c
.
genesisBlock
func
(
l
c
*
LightChain
)
Genesis
()
*
types
.
Block
{
return
l
c
.
genesisBlock
}
// State returns a new mutable state based on the current HEAD block.
func
(
b
c
*
LightChain
)
State
()
(
*
state
.
StateDB
,
error
)
{
func
(
l
c
*
LightChain
)
State
()
(
*
state
.
StateDB
,
error
)
{
return
nil
,
errors
.
New
(
"not implemented, needs client/server interface split"
)
}
// GetBody retrieves a block body (transactions and uncles) from the database
// or ODR service by hash, caching it if found.
func
(
self
*
LightChain
)
GetBody
(
ctx
context
.
Context
,
hash
common
.
Hash
)
(
*
types
.
Body
,
error
)
{
func
(
lc
*
LightChain
)
GetBody
(
ctx
context
.
Context
,
hash
common
.
Hash
)
(
*
types
.
Body
,
error
)
{
// Short circuit if the body's already in the cache, retrieve otherwise
if
cached
,
ok
:=
self
.
bodyCache
.
Get
(
hash
);
ok
{
if
cached
,
ok
:=
lc
.
bodyCache
.
Get
(
hash
);
ok
{
body
:=
cached
.
(
*
types
.
Body
)
return
body
,
nil
}
number
:=
self
.
hc
.
GetBlockNumber
(
hash
)
number
:=
lc
.
hc
.
GetBlockNumber
(
hash
)
if
number
==
nil
{
return
nil
,
errors
.
New
(
"unknown block"
)
}
body
,
err
:=
GetBody
(
ctx
,
self
.
odr
,
hash
,
*
number
)
body
,
err
:=
GetBody
(
ctx
,
lc
.
odr
,
hash
,
*
number
)
if
err
!=
nil
{
return
nil
,
err
}
// Cache the found body for next time and return
self
.
bodyCache
.
Add
(
hash
,
body
)
lc
.
bodyCache
.
Add
(
hash
,
body
)
return
body
,
nil
}
// GetBodyRLP retrieves a block body in RLP encoding from the database or
// ODR service by hash, caching it if found.
func
(
self
*
LightChain
)
GetBodyRLP
(
ctx
context
.
Context
,
hash
common
.
Hash
)
(
rlp
.
RawValue
,
error
)
{
func
(
lc
*
LightChain
)
GetBodyRLP
(
ctx
context
.
Context
,
hash
common
.
Hash
)
(
rlp
.
RawValue
,
error
)
{
// Short circuit if the body's already in the cache, retrieve otherwise
if
cached
,
ok
:=
self
.
bodyRLPCache
.
Get
(
hash
);
ok
{
if
cached
,
ok
:=
lc
.
bodyRLPCache
.
Get
(
hash
);
ok
{
return
cached
.
(
rlp
.
RawValue
),
nil
}
number
:=
self
.
hc
.
GetBlockNumber
(
hash
)
number
:=
lc
.
hc
.
GetBlockNumber
(
hash
)
if
number
==
nil
{
return
nil
,
errors
.
New
(
"unknown block"
)
}
body
,
err
:=
GetBodyRLP
(
ctx
,
self
.
odr
,
hash
,
*
number
)
body
,
err
:=
GetBodyRLP
(
ctx
,
lc
.
odr
,
hash
,
*
number
)
if
err
!=
nil
{
return
nil
,
err
}
// Cache the found body for next time and return
self
.
bodyRLPCache
.
Add
(
hash
,
body
)
lc
.
bodyRLPCache
.
Add
(
hash
,
body
)
return
body
,
nil
}
// HasBlock checks if a block is fully present in the database or not, caching
// it if present.
func
(
b
c
*
LightChain
)
HasBlock
(
hash
common
.
Hash
,
number
uint64
)
bool
{
blk
,
_
:=
b
c
.
GetBlock
(
NoOdr
,
hash
,
number
)
func
(
l
c
*
LightChain
)
HasBlock
(
hash
common
.
Hash
,
number
uint64
)
bool
{
blk
,
_
:=
l
c
.
GetBlock
(
NoOdr
,
hash
,
number
)
return
blk
!=
nil
}
// GetBlock retrieves a block from the database or ODR service by hash and number,
// caching it if found.
func
(
self
*
LightChain
)
GetBlock
(
ctx
context
.
Context
,
hash
common
.
Hash
,
number
uint64
)
(
*
types
.
Block
,
error
)
{
func
(
lc
*
LightChain
)
GetBlock
(
ctx
context
.
Context
,
hash
common
.
Hash
,
number
uint64
)
(
*
types
.
Block
,
error
)
{
// Short circuit if the block's already in the cache, retrieve otherwise
if
block
,
ok
:=
self
.
blockCache
.
Get
(
hash
);
ok
{
if
block
,
ok
:=
lc
.
blockCache
.
Get
(
hash
);
ok
{
return
block
.
(
*
types
.
Block
),
nil
}
block
,
err
:=
GetBlock
(
ctx
,
self
.
odr
,
hash
,
number
)
block
,
err
:=
GetBlock
(
ctx
,
lc
.
odr
,
hash
,
number
)
if
err
!=
nil
{
return
nil
,
err
}
// Cache the found block for next time and return
self
.
blockCache
.
Add
(
block
.
Hash
(),
block
)
lc
.
blockCache
.
Add
(
block
.
Hash
(),
block
)
return
block
,
nil
}
// GetBlockByHash retrieves a block from the database or ODR service by hash,
// caching it if found.
func
(
self
*
LightChain
)
GetBlockByHash
(
ctx
context
.
Context
,
hash
common
.
Hash
)
(
*
types
.
Block
,
error
)
{
number
:=
self
.
hc
.
GetBlockNumber
(
hash
)
func
(
lc
*
LightChain
)
GetBlockByHash
(
ctx
context
.
Context
,
hash
common
.
Hash
)
(
*
types
.
Block
,
error
)
{
number
:=
lc
.
hc
.
GetBlockNumber
(
hash
)
if
number
==
nil
{
return
nil
,
errors
.
New
(
"unknown block"
)
}
return
self
.
GetBlock
(
ctx
,
hash
,
*
number
)
return
lc
.
GetBlock
(
ctx
,
hash
,
*
number
)
}
// GetBlockByNumber retrieves a block from the database or ODR service by
// number, caching it (associated with its hash) if found.
func
(
self
*
LightChain
)
GetBlockByNumber
(
ctx
context
.
Context
,
number
uint64
)
(
*
types
.
Block
,
error
)
{
hash
,
err
:=
GetCanonicalHash
(
ctx
,
self
.
odr
,
number
)
func
(
lc
*
LightChain
)
GetBlockByNumber
(
ctx
context
.
Context
,
number
uint64
)
(
*
types
.
Block
,
error
)
{
hash
,
err
:=
GetCanonicalHash
(
ctx
,
lc
.
odr
,
number
)
if
hash
==
(
common
.
Hash
{})
||
err
!=
nil
{
return
nil
,
err
}
return
self
.
GetBlock
(
ctx
,
hash
,
number
)
return
lc
.
GetBlock
(
ctx
,
hash
,
number
)
}
// Stop stops the blockchain service. If any imports are currently in progress
// it will abort them using the procInterrupt.
func
(
b
c
*
LightChain
)
Stop
()
{
if
!
atomic
.
CompareAndSwapInt32
(
&
b
c
.
running
,
0
,
1
)
{
func
(
l
c
*
LightChain
)
Stop
()
{
if
!
atomic
.
CompareAndSwapInt32
(
&
l
c
.
running
,
0
,
1
)
{
return
}
close
(
b
c
.
quit
)
atomic
.
StoreInt32
(
&
b
c
.
procInterrupt
,
1
)
close
(
l
c
.
quit
)
atomic
.
StoreInt32
(
&
l
c
.
procInterrupt
,
1
)
b
c
.
wg
.
Wait
()
l
c
.
wg
.
Wait
()
log
.
Info
(
"Blockchain manager stopped"
)
}
// Rollback is designed to remove a chain of links from the database that aren't
// certain enough to be valid.
func
(
self
*
LightChain
)
Rollback
(
chain
[]
common
.
Hash
)
{
self
.
chainmu
.
Lock
()
defer
self
.
chainmu
.
Unlock
()
func
(
lc
*
LightChain
)
Rollback
(
chain
[]
common
.
Hash
)
{
lc
.
chainmu
.
Lock
()
defer
lc
.
chainmu
.
Unlock
()
for
i
:=
len
(
chain
)
-
1
;
i
>=
0
;
i
--
{
hash
:=
chain
[
i
]
if
head
:=
self
.
hc
.
CurrentHeader
();
head
.
Hash
()
==
hash
{
self
.
hc
.
SetCurrentHeader
(
self
.
GetHeader
(
head
.
ParentHash
,
head
.
Number
.
Uint64
()
-
1
))
if
head
:=
lc
.
hc
.
CurrentHeader
();
head
.
Hash
()
==
hash
{
lc
.
hc
.
SetCurrentHeader
(
lc
.
GetHeader
(
head
.
ParentHash
,
head
.
Number
.
Uint64
()
-
1
))
}
}
}
// postChainEvents iterates over the events generated by a chain insertion and
// posts them into the event feed.
func
(
self
*
LightChain
)
postChainEvents
(
events
[]
interface
{})
{
func
(
lc
*
LightChain
)
postChainEvents
(
events
[]
interface
{})
{
for
_
,
event
:=
range
events
{
switch
ev
:=
event
.
(
type
)
{
case
core
.
ChainEvent
:
if
self
.
CurrentHeader
()
.
Hash
()
==
ev
.
Hash
{
self
.
chainHeadFeed
.
Send
(
core
.
ChainHeadEvent
{
Block
:
ev
.
Block
})
if
lc
.
CurrentHeader
()
.
Hash
()
==
ev
.
Hash
{
lc
.
chainHeadFeed
.
Send
(
core
.
ChainHeadEvent
{
Block
:
ev
.
Block
})
}
self
.
chainFeed
.
Send
(
ev
)
lc
.
chainFeed
.
Send
(
ev
)
case
core
.
ChainSideEvent
:
self
.
chainSideFeed
.
Send
(
ev
)
lc
.
chainSideFeed
.
Send
(
ev
)
}
}
}
...
...
@@ -353,25 +353,25 @@ func (self *LightChain) postChainEvents(events []interface{}) {
//
// In the case of a light chain, InsertHeaderChain also creates and posts light
// chain events when necessary.
func
(
self
*
LightChain
)
InsertHeaderChain
(
chain
[]
*
types
.
Header
,
checkFreq
int
)
(
int
,
error
)
{
if
atomic
.
LoadInt32
(
&
self
.
disableCheckFreq
)
==
1
{
func
(
lc
*
LightChain
)
InsertHeaderChain
(
chain
[]
*
types
.
Header
,
checkFreq
int
)
(
int
,
error
)
{
if
atomic
.
LoadInt32
(
&
lc
.
disableCheckFreq
)
==
1
{
checkFreq
=
0
}
start
:=
time
.
Now
()
if
i
,
err
:=
self
.
hc
.
ValidateHeaderChain
(
chain
,
checkFreq
);
err
!=
nil
{
if
i
,
err
:=
lc
.
hc
.
ValidateHeaderChain
(
chain
,
checkFreq
);
err
!=
nil
{
return
i
,
err
}
// Make sure only one thread manipulates the chain at once
self
.
chainmu
.
Lock
()
defer
self
.
chainmu
.
Unlock
()
lc
.
chainmu
.
Lock
()
defer
lc
.
chainmu
.
Unlock
()
self
.
wg
.
Add
(
1
)
defer
self
.
wg
.
Done
()
lc
.
wg
.
Add
(
1
)
defer
lc
.
wg
.
Done
()
var
events
[]
interface
{}
whFunc
:=
func
(
header
*
types
.
Header
)
error
{
status
,
err
:=
self
.
hc
.
WriteHeader
(
header
)
status
,
err
:=
lc
.
hc
.
WriteHeader
(
header
)
switch
status
{
case
core
.
CanonStatTy
:
...
...
@@ -384,51 +384,51 @@ func (self *LightChain) InsertHeaderChain(chain []*types.Header, checkFreq int)
}
return
err
}
i
,
err
:=
self
.
hc
.
InsertHeaderChain
(
chain
,
whFunc
,
start
)
self
.
postChainEvents
(
events
)
i
,
err
:=
lc
.
hc
.
InsertHeaderChain
(
chain
,
whFunc
,
start
)
lc
.
postChainEvents
(
events
)
return
i
,
err
}
// CurrentHeader retrieves the current head header of the canonical chain. The
// header is retrieved from the HeaderChain's internal cache.
func
(
self
*
LightChain
)
CurrentHeader
()
*
types
.
Header
{
return
self
.
hc
.
CurrentHeader
()
func
(
lc
*
LightChain
)
CurrentHeader
()
*
types
.
Header
{
return
lc
.
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
(
self
*
LightChain
)
GetTd
(
hash
common
.
Hash
,
number
uint64
)
*
big
.
Int
{
return
self
.
hc
.
GetTd
(
hash
,
number
)
func
(
lc
*
LightChain
)
GetTd
(
hash
common
.
Hash
,
number
uint64
)
*
big
.
Int
{
return
lc
.
hc
.
GetTd
(
hash
,
number
)
}
// GetTdByHash retrieves a block's total difficulty in the canonical chain from the
// database by hash, caching it if found.
func
(
self
*
LightChain
)
GetTdByHash
(
hash
common
.
Hash
)
*
big
.
Int
{
return
self
.
hc
.
GetTdByHash
(
hash
)
func
(
lc
*
LightChain
)
GetTdByHash
(
hash
common
.
Hash
)
*
big
.
Int
{
return
lc
.
hc
.
GetTdByHash
(
hash
)
}
// GetHeader retrieves a block header from the database by hash and number,
// caching it if found.
func
(
self
*
LightChain
)
GetHeader
(
hash
common
.
Hash
,
number
uint64
)
*
types
.
Header
{
return
self
.
hc
.
GetHeader
(
hash
,
number
)
func
(
lc
*
LightChain
)
GetHeader
(
hash
common
.
Hash
,
number
uint64
)
*
types
.
Header
{
return
lc
.
hc
.
GetHeader
(
hash
,
number
)
}
// GetHeaderByHash retrieves a block header from the database by hash, caching it if
// found.
func
(
self
*
LightChain
)
GetHeaderByHash
(
hash
common
.
Hash
)
*
types
.
Header
{
return
self
.
hc
.
GetHeaderByHash
(
hash
)
func
(
lc
*
LightChain
)
GetHeaderByHash
(
hash
common
.
Hash
)
*
types
.
Header
{
return
lc
.
hc
.
GetHeaderByHash
(
hash
)
}
// HasHeader checks if a block header is present in the database or not, caching
// it if present.
func
(
b
c
*
LightChain
)
HasHeader
(
hash
common
.
Hash
,
number
uint64
)
bool
{
return
b
c
.
hc
.
HasHeader
(
hash
,
number
)
func
(
l
c
*
LightChain
)
HasHeader
(
hash
common
.
Hash
,
number
uint64
)
bool
{
return
l
c
.
hc
.
HasHeader
(
hash
,
number
)
}
// GetBlockHashesFromHash retrieves a number of block hashes starting at a given
// hash, fetching towards the genesis block.
func
(
self
*
LightChain
)
GetBlockHashesFromHash
(
hash
common
.
Hash
,
max
uint64
)
[]
common
.
Hash
{
return
self
.
hc
.
GetBlockHashesFromHash
(
hash
,
max
)
func
(
lc
*
LightChain
)
GetBlockHashesFromHash
(
hash
common
.
Hash
,
max
uint64
)
[]
common
.
Hash
{
return
lc
.
hc
.
GetBlockHashesFromHash
(
hash
,
max
)
}
// GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or
...
...
@@ -436,56 +436,56 @@ func (self *LightChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []c
// 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
(
b
c
*
LightChain
)
GetAncestor
(
hash
common
.
Hash
,
number
,
ancestor
uint64
,
maxNonCanonical
*
uint64
)
(
common
.
Hash
,
uint64
)
{
b
c
.
chainmu
.
RLock
()
defer
b
c
.
chainmu
.
RUnlock
()
func
(
l
c
*
LightChain
)
GetAncestor
(
hash
common
.
Hash
,
number
,
ancestor
uint64
,
maxNonCanonical
*
uint64
)
(
common
.
Hash
,
uint64
)
{
l
c
.
chainmu
.
RLock
()
defer
l
c
.
chainmu
.
RUnlock
()
return
b
c
.
hc
.
GetAncestor
(
hash
,
number
,
ancestor
,
maxNonCanonical
)
return
l
c
.
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
(
self
*
LightChain
)
GetHeaderByNumber
(
number
uint64
)
*
types
.
Header
{
return
self
.
hc
.
GetHeaderByNumber
(
number
)
func
(
lc
*
LightChain
)
GetHeaderByNumber
(
number
uint64
)
*
types
.
Header
{
return
lc
.
hc
.
GetHeaderByNumber
(
number
)
}
// GetHeaderByNumberOdr retrieves a block header from the database or network
// by number, caching it (associated with its hash) if found.
func
(
self
*
LightChain
)
GetHeaderByNumberOdr
(
ctx
context
.
Context
,
number
uint64
)
(
*
types
.
Header
,
error
)
{
if
header
:=
self
.
hc
.
GetHeaderByNumber
(
number
);
header
!=
nil
{
func
(
lc
*
LightChain
)
GetHeaderByNumberOdr
(
ctx
context
.
Context
,
number
uint64
)
(
*
types
.
Header
,
error
)
{
if
header
:=
lc
.
hc
.
GetHeaderByNumber
(
number
);
header
!=
nil
{
return
header
,
nil
}
return
GetHeaderByNumber
(
ctx
,
self
.
odr
,
number
)
return
GetHeaderByNumber
(
ctx
,
lc
.
odr
,
number
)
}
// Config retrieves the header chain's chain configuration.
func
(
self
*
LightChain
)
Config
()
*
params
.
ChainConfig
{
return
self
.
hc
.
Config
()
}
func
(
lc
*
LightChain
)
Config
()
*
params
.
ChainConfig
{
return
lc
.
hc
.
Config
()
}
func
(
self
*
LightChain
)
SyncCht
(
ctx
context
.
Context
)
bool
{
func
(
lc
*
LightChain
)
SyncCht
(
ctx
context
.
Context
)
bool
{
// If we don't have a CHT indexer, abort
if
self
.
odr
.
ChtIndexer
()
==
nil
{
if
lc
.
odr
.
ChtIndexer
()
==
nil
{
return
false
}
// Ensure the remote CHT head is ahead of us
head
:=
self
.
CurrentHeader
()
.
Number
.
Uint64
()
sections
,
_
,
_
:=
self
.
odr
.
ChtIndexer
()
.
Sections
()
head
:=
lc
.
CurrentHeader
()
.
Number
.
Uint64
()
sections
,
_
,
_
:=
lc
.
odr
.
ChtIndexer
()
.
Sections
()
latest
:=
sections
*
self
.
indexerConfig
.
ChtSize
-
1
if
clique
:=
self
.
hc
.
Config
()
.
Clique
;
clique
!=
nil
{
latest
:=
sections
*
lc
.
indexerConfig
.
ChtSize
-
1
if
clique
:=
lc
.
hc
.
Config
()
.
Clique
;
clique
!=
nil
{
latest
-=
latest
%
clique
.
Epoch
// epoch snapshot for clique
}
if
head
>=
latest
{
return
false
}
// Retrieve the latest useful header and update to it
if
header
,
err
:=
GetHeaderByNumber
(
ctx
,
self
.
odr
,
latest
);
header
!=
nil
&&
err
==
nil
{
self
.
chainmu
.
Lock
()
defer
self
.
chainmu
.
Unlock
()
if
header
,
err
:=
GetHeaderByNumber
(
ctx
,
lc
.
odr
,
latest
);
header
!=
nil
&&
err
==
nil
{
lc
.
chainmu
.
Lock
()
defer
lc
.
chainmu
.
Unlock
()
// Ensure the chain didn't move past the latest block while retrieving it
if
self
.
hc
.
CurrentHeader
()
.
Number
.
Uint64
()
<
header
.
Number
.
Uint64
()
{
if
lc
.
hc
.
CurrentHeader
()
.
Number
.
Uint64
()
<
header
.
Number
.
Uint64
()
{
log
.
Info
(
"Updated latest header based on CHT"
,
"number"
,
header
.
Number
,
"hash"
,
header
.
Hash
(),
"age"
,
common
.
PrettyAge
(
time
.
Unix
(
header
.
Time
.
Int64
(),
0
)))
self
.
hc
.
SetCurrentHeader
(
header
)
lc
.
hc
.
SetCurrentHeader
(
header
)
}
return
true
}
...
...
@@ -494,48 +494,48 @@ func (self *LightChain) SyncCht(ctx context.Context) bool {
// LockChain locks the chain mutex for reading so that multiple canonical hashes can be
// retrieved while it is guaranteed that they belong to the same version of the chain
func
(
self
*
LightChain
)
LockChain
()
{
self
.
chainmu
.
RLock
()
func
(
lc
*
LightChain
)
LockChain
()
{
lc
.
chainmu
.
RLock
()
}
// UnlockChain unlocks the chain mutex
func
(
self
*
LightChain
)
UnlockChain
()
{
self
.
chainmu
.
RUnlock
()
func
(
lc
*
LightChain
)
UnlockChain
()
{
lc
.
chainmu
.
RUnlock
()
}
// SubscribeChainEvent registers a subscription of ChainEvent.
func
(
self
*
LightChain
)
SubscribeChainEvent
(
ch
chan
<-
core
.
ChainEvent
)
event
.
Subscription
{
return
self
.
scope
.
Track
(
self
.
chainFeed
.
Subscribe
(
ch
))
func
(
lc
*
LightChain
)
SubscribeChainEvent
(
ch
chan
<-
core
.
ChainEvent
)
event
.
Subscription
{
return
lc
.
scope
.
Track
(
lc
.
chainFeed
.
Subscribe
(
ch
))
}
// SubscribeChainHeadEvent registers a subscription of ChainHeadEvent.
func
(
self
*
LightChain
)
SubscribeChainHeadEvent
(
ch
chan
<-
core
.
ChainHeadEvent
)
event
.
Subscription
{
return
self
.
scope
.
Track
(
self
.
chainHeadFeed
.
Subscribe
(
ch
))
func
(
lc
*
LightChain
)
SubscribeChainHeadEvent
(
ch
chan
<-
core
.
ChainHeadEvent
)
event
.
Subscription
{
return
lc
.
scope
.
Track
(
lc
.
chainHeadFeed
.
Subscribe
(
ch
))
}
// SubscribeChainSideEvent registers a subscription of ChainSideEvent.
func
(
self
*
LightChain
)
SubscribeChainSideEvent
(
ch
chan
<-
core
.
ChainSideEvent
)
event
.
Subscription
{
return
self
.
scope
.
Track
(
self
.
chainSideFeed
.
Subscribe
(
ch
))
func
(
lc
*
LightChain
)
SubscribeChainSideEvent
(
ch
chan
<-
core
.
ChainSideEvent
)
event
.
Subscription
{
return
lc
.
scope
.
Track
(
lc
.
chainSideFeed
.
Subscribe
(
ch
))
}
// SubscribeLogsEvent implements the interface of filters.Backend
// LightChain does not send logs events, so return an empty subscription.
func
(
self
*
LightChain
)
SubscribeLogsEvent
(
ch
chan
<-
[]
*
types
.
Log
)
event
.
Subscription
{
return
self
.
scope
.
Track
(
new
(
event
.
Feed
)
.
Subscribe
(
ch
))
func
(
lc
*
LightChain
)
SubscribeLogsEvent
(
ch
chan
<-
[]
*
types
.
Log
)
event
.
Subscription
{
return
lc
.
scope
.
Track
(
new
(
event
.
Feed
)
.
Subscribe
(
ch
))
}
// SubscribeRemovedLogsEvent implements the interface of filters.Backend
// LightChain does not send core.RemovedLogsEvent, so return an empty subscription.
func
(
self
*
LightChain
)
SubscribeRemovedLogsEvent
(
ch
chan
<-
core
.
RemovedLogsEvent
)
event
.
Subscription
{
return
self
.
scope
.
Track
(
new
(
event
.
Feed
)
.
Subscribe
(
ch
))
func
(
lc
*
LightChain
)
SubscribeRemovedLogsEvent
(
ch
chan
<-
core
.
RemovedLogsEvent
)
event
.
Subscription
{
return
lc
.
scope
.
Track
(
new
(
event
.
Feed
)
.
Subscribe
(
ch
))
}
// DisableCheckFreq disables header validation. This is used for ultralight mode.
func
(
self
*
LightChain
)
DisableCheckFreq
()
{
atomic
.
StoreInt32
(
&
self
.
disableCheckFreq
,
1
)
func
(
lc
*
LightChain
)
DisableCheckFreq
()
{
atomic
.
StoreInt32
(
&
lc
.
disableCheckFreq
,
1
)
}
// EnableCheckFreq enables header validation.
func
(
self
*
LightChain
)
EnableCheckFreq
()
{
atomic
.
StoreInt32
(
&
self
.
disableCheckFreq
,
0
)
func
(
lc
*
LightChain
)
EnableCheckFreq
()
{
atomic
.
StoreInt32
(
&
lc
.
disableCheckFreq
,
0
)
}
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