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
ada9c774
Unverified
Commit
ada9c774
authored
Dec 17, 2021
by
Sina Mahmoodi
Committed by
GitHub
Dec 17, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
eth, les: update unclean shutdown markers regularly (#24077)
Fixes #22580 Co-authored-by:
Felix Lange
<
fjl@twurst.com
>
parent
3e47e38a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
145 additions
and
39 deletions
+145
-39
accessors_metadata.go
core/rawdb/accessors_metadata.go
+22
-0
backend.go
eth/backend.go
+14
-14
shutdown_tracker.go
internal/shutdowncheck/shutdown_tracker.go
+85
-0
client.go
les/client.go
+24
-25
No files found.
core/rawdb/accessors_metadata.go
View file @
ada9c774
...
...
@@ -139,6 +139,28 @@ func PopUncleanShutdownMarker(db ethdb.KeyValueStore) {
}
}
// UpdateUncleanShutdownMarker updates the last marker's timestamp to now.
func
UpdateUncleanShutdownMarker
(
db
ethdb
.
KeyValueStore
)
{
var
uncleanShutdowns
crashList
// Read old data
if
data
,
err
:=
db
.
Get
(
uncleanShutdownKey
);
err
!=
nil
{
log
.
Warn
(
"Error reading unclean shutdown markers"
,
"error"
,
err
)
}
else
if
err
:=
rlp
.
DecodeBytes
(
data
,
&
uncleanShutdowns
);
err
!=
nil
{
log
.
Warn
(
"Error decoding unclean shutdown markers"
,
"error"
,
err
)
}
// This shouldn't happen because we push a marker on Backend instantiation
count
:=
len
(
uncleanShutdowns
.
Recent
)
if
count
==
0
{
log
.
Warn
(
"No unclean shutdown marker to update"
)
return
}
uncleanShutdowns
.
Recent
[
count
-
1
]
=
uint64
(
time
.
Now
()
.
Unix
())
data
,
_
:=
rlp
.
EncodeToBytes
(
uncleanShutdowns
)
if
err
:=
db
.
Put
(
uncleanShutdownKey
,
data
);
err
!=
nil
{
log
.
Warn
(
"Failed to write unclean-shutdown marker"
,
"err"
,
err
)
}
}
// ReadTransitionStatus retrieves the eth2 transition status from the database
func
ReadTransitionStatus
(
db
ethdb
.
KeyValueReader
)
[]
byte
{
data
,
_
:=
db
.
Get
(
transitionStatusKey
)
...
...
eth/backend.go
View file @
ada9c774
...
...
@@ -47,6 +47,7 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/internal/shutdowncheck"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/miner"
"github.com/ethereum/go-ethereum/node"
...
...
@@ -97,6 +98,8 @@ type Ethereum struct {
p2pServer
*
p2p
.
Server
lock
sync
.
RWMutex
// Protects the variadic fields (e.g. gas price and etherbase)
shutdownTracker
*
shutdowncheck
.
ShutdownTracker
// Tracks if and when the node has shutdown ungracefully
}
// New creates a new Ethereum object (including the
...
...
@@ -157,6 +160,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
bloomRequests
:
make
(
chan
chan
*
bloombits
.
Retrieval
),
bloomIndexer
:
core
.
NewBloomIndexer
(
chainDb
,
params
.
BloomBitsBlocks
,
params
.
BloomConfirms
),
p2pServer
:
stack
.
Server
(),
shutdownTracker
:
shutdowncheck
.
NewShutdownTracker
(
chainDb
),
}
bcVersion
:=
rawdb
.
ReadDatabaseVersion
(
chainDb
)
...
...
@@ -262,19 +266,9 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
stack
.
RegisterProtocols
(
eth
.
Protocols
())
stack
.
RegisterLifecycle
(
eth
)
// Check for unclean shutdown
if
uncleanShutdowns
,
discards
,
err
:=
rawdb
.
PushUncleanShutdownMarker
(
chainDb
);
err
!=
nil
{
log
.
Error
(
"Could not update unclean-shutdown-marker list"
,
"error"
,
err
)
}
else
{
if
discards
>
0
{
log
.
Warn
(
"Old unclean shutdowns found"
,
"count"
,
discards
)
}
for
_
,
tstamp
:=
range
uncleanShutdowns
{
t
:=
time
.
Unix
(
int64
(
tstamp
),
0
)
log
.
Warn
(
"Unclean shutdown detected"
,
"booted"
,
t
,
"age"
,
common
.
PrettyAge
(
t
))
}
}
// Successful startup; push a marker and check previous unclean shutdowns.
eth
.
shutdownTracker
.
MarkStartup
()
return
eth
,
nil
}
...
...
@@ -549,6 +543,9 @@ func (s *Ethereum) Start() error {
// Start the bloom bits servicing goroutines
s
.
startBloomHandlers
(
params
.
BloomBitsBlocks
)
// Regularly update shutdown marker
s
.
shutdownTracker
.
Start
()
// Figure out a max peers count based on the server limits
maxPeers
:=
s
.
p2pServer
.
MaxPeers
if
s
.
config
.
LightServ
>
0
{
...
...
@@ -577,7 +574,10 @@ func (s *Ethereum) Stop() error {
s
.
miner
.
Close
()
s
.
blockchain
.
Stop
()
s
.
engine
.
Close
()
rawdb
.
PopUncleanShutdownMarker
(
s
.
chainDb
)
// Clean shutdown marker as the last thing before closing db
s
.
shutdownTracker
.
Stop
()
s
.
chainDb
.
Close
()
s
.
eventMux
.
Stop
()
...
...
internal/shutdowncheck/shutdown_tracker.go
0 → 100644
View file @
ada9c774
// 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
shutdowncheck
import
(
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
)
// ShutdownTracker is a service that reports previous unclean shutdowns
// upon start. It needs to be started after a successful start-up and stopped
// after a successful shutdown, just before the db is closed.
type
ShutdownTracker
struct
{
db
ethdb
.
Database
stopCh
chan
struct
{}
}
// NewShutdownTracker creates a new ShutdownTracker instance and has
// no other side-effect.
func
NewShutdownTracker
(
db
ethdb
.
Database
)
*
ShutdownTracker
{
return
&
ShutdownTracker
{
db
:
db
,
stopCh
:
make
(
chan
struct
{}),
}
}
// MarkStartup is to be called in the beginning when the node starts. It will:
// - Push a new startup marker to the db
// - Report previous unclean shutdowns
func
(
t
*
ShutdownTracker
)
MarkStartup
()
{
if
uncleanShutdowns
,
discards
,
err
:=
rawdb
.
PushUncleanShutdownMarker
(
t
.
db
);
err
!=
nil
{
log
.
Error
(
"Could not update unclean-shutdown-marker list"
,
"error"
,
err
)
}
else
{
if
discards
>
0
{
log
.
Warn
(
"Old unclean shutdowns found"
,
"count"
,
discards
)
}
for
_
,
tstamp
:=
range
uncleanShutdowns
{
t
:=
time
.
Unix
(
int64
(
tstamp
),
0
)
log
.
Warn
(
"Unclean shutdown detected"
,
"booted"
,
t
,
"age"
,
common
.
PrettyAge
(
t
))
}
}
}
// Start runs an event loop that updates the current marker's timestamp every 5 minutes.
func
(
t
*
ShutdownTracker
)
Start
()
{
go
func
()
{
ticker
:=
time
.
NewTicker
(
5
*
time
.
Minute
)
defer
ticker
.
Stop
()
for
{
select
{
case
<-
ticker
.
C
:
rawdb
.
UpdateUncleanShutdownMarker
(
t
.
db
)
case
<-
t
.
stopCh
:
return
}
}
}()
}
// Stop will stop the update loop and clear the current marker.
func
(
t
*
ShutdownTracker
)
Stop
()
{
// Stop update loop.
t
.
stopCh
<-
struct
{}{}
// Clear last marker.
rawdb
.
PopUncleanShutdownMarker
(
t
.
db
)
}
les/client.go
View file @
ada9c774
...
...
@@ -35,6 +35,7 @@ import (
"github.com/ethereum/go-ethereum/eth/gasprice"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/internal/shutdowncheck"
"github.com/ethereum/go-ethereum/les/downloader"
"github.com/ethereum/go-ethereum/les/vflux"
vfc
"github.com/ethereum/go-ethereum/les/vflux/client"
...
...
@@ -77,6 +78,8 @@ type LightEthereum struct {
p2pServer
*
p2p
.
Server
p2pConfig
*
p2p
.
Config
udpEnabled
bool
shutdownTracker
*
shutdowncheck
.
ShutdownTracker
// Tracks if and when the node has shutdown ungracefully
}
// New creates an instance of the light client.
...
...
@@ -107,17 +110,18 @@ func New(stack *node.Node, config *ethconfig.Config) (*LightEthereum, error) {
lesDb
:
lesDb
,
closeCh
:
make
(
chan
struct
{}),
},
peers
:
peers
,
eventMux
:
stack
.
EventMux
(),
reqDist
:
newRequestDistributor
(
peers
,
&
mclock
.
System
{}),
accountManager
:
stack
.
AccountManager
(),
merger
:
merger
,
engine
:
ethconfig
.
CreateConsensusEngine
(
stack
,
chainConfig
,
&
config
.
Ethash
,
nil
,
false
,
chainDb
),
bloomRequests
:
make
(
chan
chan
*
bloombits
.
Retrieval
),
bloomIndexer
:
core
.
NewBloomIndexer
(
chainDb
,
params
.
BloomBitsBlocksClient
,
params
.
HelperTrieConfirmations
),
p2pServer
:
stack
.
Server
(),
p2pConfig
:
&
stack
.
Config
()
.
P2P
,
udpEnabled
:
stack
.
Config
()
.
P2P
.
DiscoveryV5
,
peers
:
peers
,
eventMux
:
stack
.
EventMux
(),
reqDist
:
newRequestDistributor
(
peers
,
&
mclock
.
System
{}),
accountManager
:
stack
.
AccountManager
(),
merger
:
merger
,
engine
:
ethconfig
.
CreateConsensusEngine
(
stack
,
chainConfig
,
&
config
.
Ethash
,
nil
,
false
,
chainDb
),
bloomRequests
:
make
(
chan
chan
*
bloombits
.
Retrieval
),
bloomIndexer
:
core
.
NewBloomIndexer
(
chainDb
,
params
.
BloomBitsBlocksClient
,
params
.
HelperTrieConfirmations
),
p2pServer
:
stack
.
Server
(),
p2pConfig
:
&
stack
.
Config
()
.
P2P
,
udpEnabled
:
stack
.
Config
()
.
P2P
.
DiscoveryV5
,
shutdownTracker
:
shutdowncheck
.
NewShutdownTracker
(
chainDb
),
}
var
prenegQuery
vfc
.
QueryFunc
...
...
@@ -185,19 +189,9 @@ func New(stack *node.Node, config *ethconfig.Config) (*LightEthereum, error) {
stack
.
RegisterProtocols
(
leth
.
Protocols
())
stack
.
RegisterLifecycle
(
leth
)
// Check for unclean shutdown
if
uncleanShutdowns
,
discards
,
err
:=
rawdb
.
PushUncleanShutdownMarker
(
chainDb
);
err
!=
nil
{
log
.
Error
(
"Could not update unclean-shutdown-marker list"
,
"error"
,
err
)
}
else
{
if
discards
>
0
{
log
.
Warn
(
"Old unclean shutdowns found"
,
"count"
,
discards
)
}
for
_
,
tstamp
:=
range
uncleanShutdowns
{
t
:=
time
.
Unix
(
int64
(
tstamp
),
0
)
log
.
Warn
(
"Unclean shutdown detected"
,
"booted"
,
t
,
"age"
,
common
.
PrettyAge
(
t
))
}
}
// Successful startup; push a marker and check previous unclean shutdowns.
leth
.
shutdownTracker
.
MarkStartup
()
return
leth
,
nil
}
...
...
@@ -352,6 +346,9 @@ func (s *LightEthereum) Protocols() []p2p.Protocol {
func
(
s
*
LightEthereum
)
Start
()
error
{
log
.
Warn
(
"Light client mode is an experimental feature"
)
// Regularly update shutdown marker
s
.
shutdownTracker
.
Start
()
if
s
.
udpEnabled
&&
s
.
p2pServer
.
DiscV5
==
nil
{
s
.
udpEnabled
=
false
log
.
Error
(
"Discovery v5 is not initialized"
)
...
...
@@ -387,7 +384,9 @@ func (s *LightEthereum) Stop() error {
s
.
engine
.
Close
()
s
.
pruner
.
close
()
s
.
eventMux
.
Stop
()
rawdb
.
PopUncleanShutdownMarker
(
s
.
chainDb
)
// Clean shutdown marker as the last thing before closing db
s
.
shutdownTracker
.
Stop
()
s
.
chainDb
.
Close
()
s
.
lesDb
.
Close
()
s
.
wg
.
Wait
()
...
...
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