Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
whqwjb
go-ethereum
提交
507869bf
G
go-ethereum
项目概览
whqwjb
/
go-ethereum
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
go-ethereum
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
507869bf
编写于
7月 01, 2015
作者:
J
Jeffrey Wilcke
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1373 from obscuren/recovery-tools
core, cmd/geth: improved recover functionality
上级
bb418a43
70d5d791
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
133 addition
and
87 deletion
+133
-87
cmd/geth/main.go
cmd/geth/main.go
+29
-7
core/chain_manager.go
core/chain_manager.go
+6
-80
core/chain_util.go
core/chain_util.go
+98
-0
未找到文件。
cmd/geth/main.go
浏览文件 @
507869bf
...
...
@@ -37,7 +37,10 @@ import (
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/metrics"
...
...
@@ -72,10 +75,13 @@ func init() {
{
Action
:
blockRecovery
,
Name
:
"recover"
,
Usage
:
"attempts to recover a corrupted database by setting a new block
head by number
"
,
Usage
:
"attempts to recover a corrupted database by setting a new block
by number or hash. See help recover.
"
,
Description
:
`
The recover commands will attempt to read out the last
block based on that.
recover #number recovers by number
recover <hex> recovers by hash
`
,
},
blocktestCommand
,
...
...
@@ -450,17 +456,33 @@ func unlockAccount(ctx *cli.Context, am *accounts.Manager, account string) (pass
}
func
blockRecovery
(
ctx
*
cli
.
Context
)
{
num
:=
ctx
.
Args
()
.
First
()
if
len
(
ctx
.
Args
())
<
1
{
glog
.
Fatal
(
"recover requires block number"
)
arg
:=
ctx
.
Args
()
.
First
()
if
len
(
ctx
.
Args
())
<
1
&&
len
(
arg
)
>
0
{
glog
.
Fatal
(
"recover requires block number
or hash
"
)
}
cfg
:=
utils
.
MakeEthConfig
(
ClientIdentifier
,
nodeNameVersion
,
ctx
)
ethereum
,
err
:=
eth
.
New
(
cfg
)
blockDb
,
err
:=
ethdb
.
NewLDBDatabase
(
filepath
.
Join
(
cfg
.
DataDir
,
"blockchain"
)
)
if
err
!=
nil
{
utils
.
Fatalf
(
"%v"
,
err
)
glog
.
Fatalln
(
"could not open db:"
,
err
)
}
var
block
*
types
.
Block
if
arg
[
0
]
==
'#'
{
block
=
core
.
GetBlockByNumber
(
blockDb
,
common
.
String2Big
(
arg
[
1
:
])
.
Uint64
())
}
else
{
block
=
core
.
GetBlockByHash
(
blockDb
,
common
.
HexToHash
(
arg
))
}
if
block
==
nil
{
glog
.
Fatalln
(
"block not found. Recovery failed"
)
}
err
=
core
.
WriteHead
(
blockDb
,
block
)
if
err
!=
nil
{
glog
.
Fatalln
(
"block write err"
,
err
)
}
ethereum
.
ChainManager
()
.
Recover
(
common
.
String2Big
(
num
)
.
Uint64
())
glog
.
Infof
(
"Recovery succesful. New HEAD %x
\n
"
,
block
.
Hash
())
}
func
startEth
(
ctx
*
cli
.
Context
,
eth
*
eth
.
Ethereum
)
{
...
...
core/chain_manager.go
浏览文件 @
507869bf
package
core
import
(
"bytes"
"fmt"
"io"
"math/big"
...
...
@@ -17,7 +16,6 @@ import (
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/pow"
"github.com/ethereum/go-ethereum/rlp"
"github.com/hashicorp/golang-lru"
...
...
@@ -40,53 +38,6 @@ const (
checkpointLimit
=
200
)
// CalcDifficulty is the difficulty adjustment algorithm. It returns
// the difficulty that a new block b should have when created at time
// given the parent block's time and difficulty.
func
CalcDifficulty
(
time
int64
,
parentTime
int64
,
parentDiff
*
big
.
Int
)
*
big
.
Int
{
diff
:=
new
(
big
.
Int
)
adjust
:=
new
(
big
.
Int
)
.
Div
(
parentDiff
,
params
.
DifficultyBoundDivisor
)
if
big
.
NewInt
(
time
-
parentTime
)
.
Cmp
(
params
.
DurationLimit
)
<
0
{
diff
.
Add
(
parentDiff
,
adjust
)
}
else
{
diff
.
Sub
(
parentDiff
,
adjust
)
}
if
diff
.
Cmp
(
params
.
MinimumDifficulty
)
<
0
{
return
params
.
MinimumDifficulty
}
return
diff
}
// CalcTD computes the total difficulty of block.
func
CalcTD
(
block
,
parent
*
types
.
Block
)
*
big
.
Int
{
if
parent
==
nil
{
return
block
.
Difficulty
()
}
d
:=
block
.
Difficulty
()
d
.
Add
(
d
,
parent
.
Td
)
return
d
}
// CalcGasLimit computes the gas limit of the next block after parent.
// The result may be modified by the caller.
func
CalcGasLimit
(
parent
*
types
.
Block
)
*
big
.
Int
{
decay
:=
new
(
big
.
Int
)
.
Div
(
parent
.
GasLimit
(),
params
.
GasLimitBoundDivisor
)
contrib
:=
new
(
big
.
Int
)
.
Mul
(
parent
.
GasUsed
(),
big
.
NewInt
(
3
))
contrib
=
contrib
.
Div
(
contrib
,
big
.
NewInt
(
2
))
contrib
=
contrib
.
Div
(
contrib
,
params
.
GasLimitBoundDivisor
)
gl
:=
new
(
big
.
Int
)
.
Sub
(
parent
.
GasLimit
(),
decay
)
gl
=
gl
.
Add
(
gl
,
contrib
)
gl
=
gl
.
Add
(
gl
,
big
.
NewInt
(
1
))
gl
.
Set
(
common
.
BigMax
(
gl
,
params
.
MinGasLimit
))
if
gl
.
Cmp
(
params
.
GenesisGasLimit
)
<
0
{
gl
.
Add
(
parent
.
GasLimit
(),
decay
)
gl
.
Set
(
common
.
BigMin
(
gl
,
params
.
GenesisGasLimit
))
}
return
gl
}
type
ChainManager
struct
{
//eth EthManager
blockDb
common
.
Database
...
...
@@ -238,16 +189,6 @@ func (self *ChainManager) setTransState(statedb *state.StateDB) {
self
.
transState
=
statedb
}
func
(
bc
*
ChainManager
)
Recover
(
num
uint64
)
{
block
:=
bc
.
GetBlockByNumber
(
num
)
if
block
!=
nil
{
bc
.
insert
(
block
)
glog
.
Infof
(
"Recovery succesful. New HEAD %x
\n
"
,
block
.
Hash
())
}
else
{
glog
.
Fatalln
(
"Recovery failed"
)
}
}
func
(
bc
*
ChainManager
)
recover
()
bool
{
data
,
_
:=
bc
.
blockDb
.
Get
([]
byte
(
"checkpoint"
))
if
len
(
data
)
!=
0
{
...
...
@@ -378,12 +319,7 @@ func (self *ChainManager) ExportN(w io.Writer, first uint64, last uint64) error
// insert injects a block into the current chain block chain. Note, this function
// assumes that the `mu` mutex is held!
func
(
bc
*
ChainManager
)
insert
(
block
*
types
.
Block
)
{
key
:=
append
(
blockNumPre
,
block
.
Number
()
.
Bytes
()
...
)
err
:=
bc
.
blockDb
.
Put
(
key
,
block
.
Hash
()
.
Bytes
())
if
err
!=
nil
{
glog
.
Fatal
(
"db write fail:"
,
err
)
}
err
=
bc
.
blockDb
.
Put
([]
byte
(
"LastBlock"
),
block
.
Hash
()
.
Bytes
())
err
:=
WriteHead
(
bc
.
blockDb
,
block
)
if
err
!=
nil
{
glog
.
Fatal
(
"db write fail:"
,
err
)
}
...
...
@@ -458,20 +394,15 @@ func (self *ChainManager) GetBlock(hash common.Hash) *types.Block {
return
block
.
(
*
types
.
Block
)
}
data
,
_
:=
self
.
blockDb
.
Get
(
append
(
blockHashPre
,
hash
[
:
]
...
))
if
len
(
data
)
==
0
{
return
nil
}
var
block
types
.
StorageBlock
if
err
:=
rlp
.
Decode
(
bytes
.
NewReader
(
data
),
&
block
);
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"invalid block RLP for hash %x: %v"
,
hash
,
err
)
block
:=
GetBlockByHash
(
self
.
blockDb
,
hash
)
if
block
==
nil
{
return
nil
}
// Add the block to the cache
self
.
cache
.
Add
(
hash
,
(
*
types
.
Block
)(
&
block
))
self
.
cache
.
Add
(
hash
,
(
*
types
.
Block
)(
block
))
return
(
*
types
.
Block
)(
&
block
)
return
(
*
types
.
Block
)(
block
)
}
func
(
self
*
ChainManager
)
GetBlockByNumber
(
num
uint64
)
*
types
.
Block
{
...
...
@@ -497,12 +428,7 @@ func (self *ChainManager) GetBlocksFromHash(hash common.Hash, n int) (blocks []*
// non blocking version
func
(
self
*
ChainManager
)
getBlockByNumber
(
num
uint64
)
*
types
.
Block
{
key
,
_
:=
self
.
blockDb
.
Get
(
append
(
blockNumPre
,
big
.
NewInt
(
int64
(
num
))
.
Bytes
()
...
))
if
len
(
key
)
==
0
{
return
nil
}
return
self
.
GetBlock
(
common
.
BytesToHash
(
key
))
return
GetBlockByNumber
(
self
.
blockDb
,
num
)
}
func
(
self
*
ChainManager
)
GetUnclesInChain
(
block
*
types
.
Block
,
length
int
)
(
uncles
[]
*
types
.
Header
)
{
...
...
core/chain_util.go
0 → 100644
浏览文件 @
507869bf
package
core
import
(
"bytes"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
)
// CalcDifficulty is the difficulty adjustment algorithm. It returns
// the difficulty that a new block b should have when created at time
// given the parent block's time and difficulty.
func
CalcDifficulty
(
time
int64
,
parentTime
int64
,
parentDiff
*
big
.
Int
)
*
big
.
Int
{
diff
:=
new
(
big
.
Int
)
adjust
:=
new
(
big
.
Int
)
.
Div
(
parentDiff
,
params
.
DifficultyBoundDivisor
)
if
big
.
NewInt
(
time
-
parentTime
)
.
Cmp
(
params
.
DurationLimit
)
<
0
{
diff
.
Add
(
parentDiff
,
adjust
)
}
else
{
diff
.
Sub
(
parentDiff
,
adjust
)
}
if
diff
.
Cmp
(
params
.
MinimumDifficulty
)
<
0
{
return
params
.
MinimumDifficulty
}
return
diff
}
// CalcTD computes the total difficulty of block.
func
CalcTD
(
block
,
parent
*
types
.
Block
)
*
big
.
Int
{
if
parent
==
nil
{
return
block
.
Difficulty
()
}
d
:=
block
.
Difficulty
()
d
.
Add
(
d
,
parent
.
Td
)
return
d
}
// CalcGasLimit computes the gas limit of the next block after parent.
// The result may be modified by the caller.
func
CalcGasLimit
(
parent
*
types
.
Block
)
*
big
.
Int
{
decay
:=
new
(
big
.
Int
)
.
Div
(
parent
.
GasLimit
(),
params
.
GasLimitBoundDivisor
)
contrib
:=
new
(
big
.
Int
)
.
Mul
(
parent
.
GasUsed
(),
big
.
NewInt
(
3
))
contrib
=
contrib
.
Div
(
contrib
,
big
.
NewInt
(
2
))
contrib
=
contrib
.
Div
(
contrib
,
params
.
GasLimitBoundDivisor
)
gl
:=
new
(
big
.
Int
)
.
Sub
(
parent
.
GasLimit
(),
decay
)
gl
=
gl
.
Add
(
gl
,
contrib
)
gl
=
gl
.
Add
(
gl
,
big
.
NewInt
(
1
))
gl
.
Set
(
common
.
BigMax
(
gl
,
params
.
MinGasLimit
))
if
gl
.
Cmp
(
params
.
GenesisGasLimit
)
<
0
{
gl
.
Add
(
parent
.
GasLimit
(),
decay
)
gl
.
Set
(
common
.
BigMin
(
gl
,
params
.
GenesisGasLimit
))
}
return
gl
}
// GetBlockByHash returns the block corresponding to the hash or nil if not found
func
GetBlockByHash
(
db
common
.
Database
,
hash
common
.
Hash
)
*
types
.
Block
{
data
,
_
:=
db
.
Get
(
append
(
blockHashPre
,
hash
[
:
]
...
))
if
len
(
data
)
==
0
{
return
nil
}
var
block
types
.
StorageBlock
if
err
:=
rlp
.
Decode
(
bytes
.
NewReader
(
data
),
&
block
);
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"invalid block RLP for hash %x: %v"
,
hash
,
err
)
return
nil
}
return
(
*
types
.
Block
)(
&
block
)
}
// GetBlockByHash returns the canonical block by number or nil if not found
func
GetBlockByNumber
(
db
common
.
Database
,
number
uint64
)
*
types
.
Block
{
key
,
_
:=
db
.
Get
(
append
(
blockNumPre
,
big
.
NewInt
(
int64
(
number
))
.
Bytes
()
...
))
if
len
(
key
)
==
0
{
return
nil
}
return
GetBlockByHash
(
db
,
common
.
BytesToHash
(
key
))
}
// WriteHead force writes the current head
func
WriteHead
(
db
common
.
Database
,
block
*
types
.
Block
)
error
{
key
:=
append
(
blockNumPre
,
block
.
Number
()
.
Bytes
()
...
)
err
:=
db
.
Put
(
key
,
block
.
Hash
()
.
Bytes
())
if
err
!=
nil
{
return
err
}
err
=
db
.
Put
([]
byte
(
"LastBlock"
),
block
.
Hash
()
.
Bytes
())
if
err
!=
nil
{
return
err
}
return
nil
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录