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
c04c8f10
Commit
c04c8f10
authored
Nov 23, 2016
by
Jeffrey Wilcke
Committed by
GitHub
Nov 23, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: improved bad block error reporting (#3320)
parent
e05d35e6
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
47 additions
and
18 deletions
+47
-18
block_validator.go
core/block_validator.go
+8
-8
blockchain.go
core/blockchain.go
+21
-8
blockchain_test.go
core/blockchain_test.go
+2
-2
backend.go
eth/backend.go
+2
-0
config.go
params/config.go
+14
-0
No files found.
core/block_validator.go
View file @
c04c8f10
...
@@ -93,14 +93,14 @@ func (v *BlockValidator) ValidateBlock(block *types.Block) error {
...
@@ -93,14 +93,14 @@ func (v *BlockValidator) ValidateBlock(block *types.Block) error {
// Verify UncleHash before running other uncle validations
// Verify UncleHash before running other uncle validations
unclesSha
:=
types
.
CalcUncleHash
(
block
.
Uncles
())
unclesSha
:=
types
.
CalcUncleHash
(
block
.
Uncles
())
if
unclesSha
!=
header
.
UncleHash
{
if
unclesSha
!=
header
.
UncleHash
{
return
fmt
.
Errorf
(
"invalid uncles root hash
. received=%x calculated=%x
"
,
header
.
UncleHash
,
unclesSha
)
return
fmt
.
Errorf
(
"invalid uncles root hash
(remote: %x local: %x)
"
,
header
.
UncleHash
,
unclesSha
)
}
}
// The transactions Trie's root (R = (Tr [[i, RLP(T1)], [i, RLP(T2)], ... [n, RLP(Tn)]]))
// The transactions Trie's root (R = (Tr [[i, RLP(T1)], [i, RLP(T2)], ... [n, RLP(Tn)]]))
// can be used by light clients to make sure they've received the correct Txs
// can be used by light clients to make sure they've received the correct Txs
txSha
:=
types
.
DeriveSha
(
block
.
Transactions
())
txSha
:=
types
.
DeriveSha
(
block
.
Transactions
())
if
txSha
!=
header
.
TxHash
{
if
txSha
!=
header
.
TxHash
{
return
fmt
.
Errorf
(
"invalid transaction root hash
. received=%x calculated=%x
"
,
header
.
TxHash
,
txSha
)
return
fmt
.
Errorf
(
"invalid transaction root hash
(remote: %x local: %x)
"
,
header
.
TxHash
,
txSha
)
}
}
return
nil
return
nil
...
@@ -113,23 +113,23 @@ func (v *BlockValidator) ValidateBlock(block *types.Block) error {
...
@@ -113,23 +113,23 @@ func (v *BlockValidator) ValidateBlock(block *types.Block) error {
func
(
v
*
BlockValidator
)
ValidateState
(
block
,
parent
*
types
.
Block
,
statedb
*
state
.
StateDB
,
receipts
types
.
Receipts
,
usedGas
*
big
.
Int
)
(
err
error
)
{
func
(
v
*
BlockValidator
)
ValidateState
(
block
,
parent
*
types
.
Block
,
statedb
*
state
.
StateDB
,
receipts
types
.
Receipts
,
usedGas
*
big
.
Int
)
(
err
error
)
{
header
:=
block
.
Header
()
header
:=
block
.
Header
()
if
block
.
GasUsed
()
.
Cmp
(
usedGas
)
!=
0
{
if
block
.
GasUsed
()
.
Cmp
(
usedGas
)
!=
0
{
return
ValidationError
(
fmt
.
Sprintf
(
"
gas used error (%v /
%v)"
,
block
.
GasUsed
(),
usedGas
))
return
ValidationError
(
fmt
.
Sprintf
(
"
invalid gas used (remote: %v local:
%v)"
,
block
.
GasUsed
(),
usedGas
))
}
}
// Validate the received block's bloom with the one derived from the generated receipts.
// Validate the received block's bloom with the one derived from the generated receipts.
// For valid blocks this should always validate to true.
// For valid blocks this should always validate to true.
rbloom
:=
types
.
CreateBloom
(
receipts
)
rbloom
:=
types
.
CreateBloom
(
receipts
)
if
rbloom
!=
header
.
Bloom
{
if
rbloom
!=
header
.
Bloom
{
return
fmt
.
Errorf
(
"
unable to replicate block's bloom=%x vs calculated bloom=%x
"
,
header
.
Bloom
,
rbloom
)
return
fmt
.
Errorf
(
"
invalid bloom (remote: %x local: %x)
"
,
header
.
Bloom
,
rbloom
)
}
}
// Tre receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, R1]]))
// Tre receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, R1]]))
receiptSha
:=
types
.
DeriveSha
(
receipts
)
receiptSha
:=
types
.
DeriveSha
(
receipts
)
if
receiptSha
!=
header
.
ReceiptHash
{
if
receiptSha
!=
header
.
ReceiptHash
{
return
fmt
.
Errorf
(
"invalid receipt root hash
. received=%x calculated=%x
"
,
header
.
ReceiptHash
,
receiptSha
)
return
fmt
.
Errorf
(
"invalid receipt root hash
(remote: %x local: %x)
"
,
header
.
ReceiptHash
,
receiptSha
)
}
}
// Validate the state root against the received state root and throw
// Validate the state root against the received state root and throw
// an error if they don't match.
// an error if they don't match.
if
root
:=
statedb
.
IntermediateRoot
(
v
.
config
.
IsEIP158
(
header
.
Number
));
header
.
Root
!=
root
{
if
root
:=
statedb
.
IntermediateRoot
(
v
.
config
.
IsEIP158
(
header
.
Number
));
header
.
Root
!=
root
{
return
fmt
.
Errorf
(
"invalid merkle root
: header=%x computed=%x
"
,
header
.
Root
,
root
)
return
fmt
.
Errorf
(
"invalid merkle root
(remote: %x local: %x)
"
,
header
.
Root
,
root
)
}
}
return
nil
return
nil
}
}
...
@@ -223,7 +223,7 @@ func ValidateHeader(config *params.ChainConfig, pow pow.PoW, header *types.Heade
...
@@ -223,7 +223,7 @@ func ValidateHeader(config *params.ChainConfig, pow pow.PoW, header *types.Heade
expd
:=
CalcDifficulty
(
config
,
header
.
Time
.
Uint64
(),
parent
.
Time
.
Uint64
(),
parent
.
Number
,
parent
.
Difficulty
)
expd
:=
CalcDifficulty
(
config
,
header
.
Time
.
Uint64
(),
parent
.
Time
.
Uint64
(),
parent
.
Number
,
parent
.
Difficulty
)
if
expd
.
Cmp
(
header
.
Difficulty
)
!=
0
{
if
expd
.
Cmp
(
header
.
Difficulty
)
!=
0
{
return
fmt
.
Errorf
(
"Difficulty check failed for header
%v, %v
"
,
header
.
Difficulty
,
expd
)
return
fmt
.
Errorf
(
"Difficulty check failed for header
(remote: %v local: %v)
"
,
header
.
Difficulty
,
expd
)
}
}
a
:=
new
(
big
.
Int
)
.
Set
(
parent
.
GasLimit
)
a
:=
new
(
big
.
Int
)
.
Set
(
parent
.
GasLimit
)
...
@@ -232,7 +232,7 @@ func ValidateHeader(config *params.ChainConfig, pow pow.PoW, header *types.Heade
...
@@ -232,7 +232,7 @@ func ValidateHeader(config *params.ChainConfig, pow pow.PoW, header *types.Heade
b
:=
new
(
big
.
Int
)
.
Set
(
parent
.
GasLimit
)
b
:=
new
(
big
.
Int
)
.
Set
(
parent
.
GasLimit
)
b
=
b
.
Div
(
b
,
params
.
GasLimitBoundDivisor
)
b
=
b
.
Div
(
b
,
params
.
GasLimitBoundDivisor
)
if
!
(
a
.
Cmp
(
b
)
<
0
)
||
(
header
.
GasLimit
.
Cmp
(
params
.
MinGasLimit
)
==
-
1
)
{
if
!
(
a
.
Cmp
(
b
)
<
0
)
||
(
header
.
GasLimit
.
Cmp
(
params
.
MinGasLimit
)
==
-
1
)
{
return
fmt
.
Errorf
(
"GasLimit check failed for header
%v (%v > %v)"
,
header
.
GasLimit
,
a
,
b
)
return
fmt
.
Errorf
(
"GasLimit check failed for header
(remote: %v local_max: %v)"
,
header
.
GasLimit
,
b
)
}
}
num
:=
new
(
big
.
Int
)
.
Set
(
parent
.
Number
)
num
:=
new
(
big
.
Int
)
.
Set
(
parent
.
Number
)
...
...
core/blockchain.go
View file @
c04c8f10
...
@@ -878,7 +878,7 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
...
@@ -878,7 +878,7 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
if
BadHashes
[
block
.
Hash
()]
{
if
BadHashes
[
block
.
Hash
()]
{
err
:=
BadHashError
(
block
.
Hash
())
err
:=
BadHashError
(
block
.
Hash
())
reportBlock
(
block
,
err
)
self
.
reportBlock
(
block
,
nil
,
err
)
return
i
,
err
return
i
,
err
}
}
// Stage 1 validation of the block using the chain's validator
// Stage 1 validation of the block using the chain's validator
...
@@ -910,7 +910,7 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
...
@@ -910,7 +910,7 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
continue
continue
}
}
reportBlock
(
block
,
err
)
self
.
reportBlock
(
block
,
nil
,
err
)
return
i
,
err
return
i
,
err
}
}
...
@@ -924,19 +924,19 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
...
@@ -924,19 +924,19 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
err
=
self
.
stateCache
.
Reset
(
chain
[
i
-
1
]
.
Root
())
err
=
self
.
stateCache
.
Reset
(
chain
[
i
-
1
]
.
Root
())
}
}
if
err
!=
nil
{
if
err
!=
nil
{
reportBlock
(
block
,
err
)
self
.
reportBlock
(
block
,
nil
,
err
)
return
i
,
err
return
i
,
err
}
}
// Process block using the parent state as reference point.
// Process block using the parent state as reference point.
receipts
,
logs
,
usedGas
,
err
:=
self
.
processor
.
Process
(
block
,
self
.
stateCache
,
vm
.
Config
{})
receipts
,
logs
,
usedGas
,
err
:=
self
.
processor
.
Process
(
block
,
self
.
stateCache
,
vm
.
Config
{})
if
err
!=
nil
{
if
err
!=
nil
{
reportBlock
(
block
,
err
)
self
.
reportBlock
(
block
,
receipts
,
err
)
return
i
,
err
return
i
,
err
}
}
// Validate the state using the default validator
// Validate the state using the default validator
err
=
self
.
Validator
()
.
ValidateState
(
block
,
self
.
GetBlock
(
block
.
ParentHash
(),
block
.
NumberU64
()
-
1
),
self
.
stateCache
,
receipts
,
usedGas
)
err
=
self
.
Validator
()
.
ValidateState
(
block
,
self
.
GetBlock
(
block
.
ParentHash
(),
block
.
NumberU64
()
-
1
),
self
.
stateCache
,
receipts
,
usedGas
)
if
err
!=
nil
{
if
err
!=
nil
{
reportBlock
(
block
,
err
)
self
.
reportBlock
(
block
,
receipts
,
err
)
return
i
,
err
return
i
,
err
}
}
// Write state changes to database
// Write state changes to database
...
@@ -1207,10 +1207,23 @@ func (self *BlockChain) update() {
...
@@ -1207,10 +1207,23 @@ func (self *BlockChain) update() {
}
}
// reportBlock logs a bad block error.
// reportBlock logs a bad block error.
func
reportBlock
(
block
*
types
.
Block
,
err
error
)
{
func
(
bc
*
BlockChain
)
reportBlock
(
block
*
types
.
Block
,
receipts
types
.
Receipts
,
err
error
)
{
if
glog
.
V
(
logger
.
Error
)
{
if
glog
.
V
(
logger
.
Error
)
{
glog
.
Errorf
(
"Bad block #%v (%s)
\n
"
,
block
.
Number
(),
block
.
Hash
()
.
Hex
())
var
receiptString
string
glog
.
Errorf
(
" %v"
,
err
)
for
_
,
receipt
:=
range
receipts
{
receiptString
+=
fmt
.
Sprintf
(
"
\t
%v
\n
"
,
receipt
)
}
glog
.
Errorf
(
`
########## BAD BLOCK #########
Chain config: %v
Number: %v
Hash: 0x%x
%v
Error: %v
##############################
`
,
bc
.
config
,
block
.
Number
(),
block
.
Hash
(),
receiptString
,
err
)
}
}
}
}
...
...
core/blockchain_test.go
View file @
c04c8f10
...
@@ -143,12 +143,12 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
...
@@ -143,12 +143,12 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
}
}
receipts
,
_
,
usedGas
,
err
:=
blockchain
.
Processor
()
.
Process
(
block
,
statedb
,
vm
.
Config
{})
receipts
,
_
,
usedGas
,
err
:=
blockchain
.
Processor
()
.
Process
(
block
,
statedb
,
vm
.
Config
{})
if
err
!=
nil
{
if
err
!=
nil
{
reportBlock
(
block
,
err
)
blockchain
.
reportBlock
(
block
,
receipts
,
err
)
return
err
return
err
}
}
err
=
blockchain
.
Validator
()
.
ValidateState
(
block
,
blockchain
.
GetBlockByHash
(
block
.
ParentHash
()),
statedb
,
receipts
,
usedGas
)
err
=
blockchain
.
Validator
()
.
ValidateState
(
block
,
blockchain
.
GetBlockByHash
(
block
.
ParentHash
()),
statedb
,
receipts
,
usedGas
)
if
err
!=
nil
{
if
err
!=
nil
{
reportBlock
(
block
,
err
)
blockchain
.
reportBlock
(
block
,
receipts
,
err
)
return
err
return
err
}
}
blockchain
.
mu
.
Lock
()
blockchain
.
mu
.
Lock
()
...
...
eth/backend.go
View file @
c04c8f10
...
@@ -218,6 +218,8 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
...
@@ -218,6 +218,8 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
eth
.
chainConfig
=
config
.
ChainConfig
eth
.
chainConfig
=
config
.
ChainConfig
glog
.
V
(
logger
.
Info
)
.
Infoln
(
"Chain config:"
,
eth
.
chainConfig
)
eth
.
blockchain
,
err
=
core
.
NewBlockChain
(
chainDb
,
eth
.
chainConfig
,
eth
.
pow
,
eth
.
EventMux
())
eth
.
blockchain
,
err
=
core
.
NewBlockChain
(
chainDb
,
eth
.
chainConfig
,
eth
.
pow
,
eth
.
EventMux
())
if
err
!=
nil
{
if
err
!=
nil
{
if
err
==
core
.
ErrNoGenesis
{
if
err
==
core
.
ErrNoGenesis
{
...
...
params/config.go
View file @
c04c8f10
...
@@ -17,6 +17,7 @@
...
@@ -17,6 +17,7 @@
package
params
package
params
import
(
import
(
"fmt"
"math/big"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
...
@@ -66,6 +67,19 @@ type ChainConfig struct {
...
@@ -66,6 +67,19 @@ type ChainConfig struct {
EIP158Block
*
big
.
Int
`json:"eip158Block"`
// EIP158 HF block
EIP158Block
*
big
.
Int
`json:"eip158Block"`
// EIP158 HF block
}
}
// String implements the Stringer interface.
func
(
c
*
ChainConfig
)
String
()
string
{
return
fmt
.
Sprintf
(
"{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v}"
,
c
.
ChainId
,
c
.
HomesteadBlock
,
c
.
DAOForkBlock
,
c
.
DAOForkSupport
,
c
.
EIP150Block
,
c
.
EIP155Block
,
c
.
EIP158Block
,
)
}
var
(
var
(
TestChainConfig
=
&
ChainConfig
{
big
.
NewInt
(
1
),
new
(
big
.
Int
),
new
(
big
.
Int
),
true
,
new
(
big
.
Int
),
common
.
Hash
{},
new
(
big
.
Int
),
new
(
big
.
Int
)}
TestChainConfig
=
&
ChainConfig
{
big
.
NewInt
(
1
),
new
(
big
.
Int
),
new
(
big
.
Int
),
true
,
new
(
big
.
Int
),
common
.
Hash
{},
new
(
big
.
Int
),
new
(
big
.
Int
)}
TestRules
=
TestChainConfig
.
Rules
(
new
(
big
.
Int
))
TestRules
=
TestChainConfig
.
Rules
(
new
(
big
.
Int
))
...
...
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