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
a87089fd
Commit
a87089fd
authored
Jul 08, 2016
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd, core, miner: add extradata validation to consensus rules
parent
1e24c2e4
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
275 additions
and
216 deletions
+275
-216
dao_test.go
cmd/geth/dao_test.go
+110
-184
genesis_test.go
cmd/geth/genesis_test.go
+2
-1
flags.go
cmd/utils/flags.go
+26
-27
block_validator.go
core/block_validator.go
+21
-0
block_validator_test.go
core/block_validator_test.go
+105
-0
config.go
core/config.go
+3
-2
worker.go
miner/worker.go
+8
-2
No files found.
cmd/geth/dao_test.go
View file @
a87089fd
This diff is collapsed.
Click to expand it.
cmd/geth/genesis_test.go
View file @
a87089fd
...
...
@@ -75,7 +75,8 @@ var customGenesisTests = []struct {
"timestamp" : "0x00",
"config" : {
"homesteadBlock" : 314,
"daoForkBlock" : 141
"daoForkBlock" : 141,
"daoForkSupport" : true
},
}`
,
query
:
"eth.getBlock(0).nonce"
,
...
...
cmd/utils/flags.go
View file @
a87089fd
...
...
@@ -798,43 +798,42 @@ func MustMakeChainConfig(ctx *cli.Context) *core.ChainConfig {
// MustMakeChainConfigFromDb reads the chain configuration from the given database.
func
MustMakeChainConfigFromDb
(
ctx
*
cli
.
Context
,
db
ethdb
.
Database
)
*
core
.
ChainConfig
{
// If the chain is already initialized, use any existing chain configs
config
:=
new
(
core
.
ChainConfig
)
if
genesis
:=
core
.
GetBlock
(
db
,
core
.
GetCanonicalHash
(
db
,
0
),
0
);
genesis
!=
nil
{
storedConfig
,
err
:=
core
.
GetChainConfig
(
db
,
genesis
.
Hash
())
if
err
==
nil
{
// Force override any existing configs if explicitly requested
switch
{
case
storedConfig
.
DAOForkBlock
==
nil
&&
ctx
.
GlobalBool
(
SupportDAOFork
.
Name
)
&&
ctx
.
GlobalBool
(
TestNetFlag
.
Name
)
:
storedConfig
.
DAOForkBlock
=
params
.
TestNetDAOForkBlock
case
storedConfig
.
DAOForkBlock
==
nil
&&
ctx
.
GlobalBool
(
SupportDAOFork
.
Name
)
:
storedConfig
.
DAOForkBlock
=
params
.
MainNetDAOForkBlock
case
ctx
.
GlobalBool
(
OpposeDAOFork
.
Name
)
:
storedConfig
.
DAOForkBlock
=
nil
}
return
storedConfig
}
else
if
err
!=
core
.
ChainConfigNotFoundErr
{
switch
err
{
case
nil
:
config
=
storedConfig
case
core
.
ChainConfigNotFoundErr
:
// No configs found, use empty, will populate below
default
:
Fatalf
(
"Could not make chain configuration: %v"
,
err
)
}
}
// If the chain is uninitialized nor no configs are present, create one
var
homesteadBlock
*
big
.
Int
if
ctx
.
GlobalBool
(
TestNetFlag
.
Name
)
{
homesteadBlock
=
params
.
TestNetHomesteadBlock
}
else
{
homesteadBlock
=
params
.
MainNetHomesteadBlock
// Set any missing fields due to them being unset or system upgrade
if
config
.
HomesteadBlock
==
nil
{
if
ctx
.
GlobalBool
(
TestNetFlag
.
Name
)
{
config
.
HomesteadBlock
=
new
(
big
.
Int
)
.
Set
(
params
.
TestNetHomesteadBlock
)
}
else
{
config
.
HomesteadBlock
=
new
(
big
.
Int
)
.
Set
(
params
.
MainNetHomesteadBlock
)
}
}
var
daoForkBlock
*
big
.
Int
if
config
.
DAOForkBlock
==
nil
{
if
ctx
.
GlobalBool
(
TestNetFlag
.
Name
)
{
config
.
DAOForkBlock
=
new
(
big
.
Int
)
.
Set
(
params
.
TestNetDAOForkBlock
)
}
else
{
config
.
DAOForkBlock
=
new
(
big
.
Int
)
.
Set
(
params
.
MainNetDAOForkBlock
)
}
}
// Force override any existing configs if explicitly requested
switch
{
case
ctx
.
GlobalBool
(
SupportDAOFork
.
Name
)
&&
ctx
.
GlobalBool
(
TestNetFlag
.
Name
)
:
daoForkBlock
=
params
.
TestNetDAOForkBlock
case
ctx
.
GlobalBool
(
SupportDAOFork
.
Name
)
:
daoForkBlock
=
params
.
MainNetDAOForkBlock
config
.
DAOForkSupport
=
true
case
ctx
.
GlobalBool
(
OpposeDAOFork
.
Name
)
:
daoForkBlock
=
nil
}
return
&
core
.
ChainConfig
{
HomesteadBlock
:
homesteadBlock
,
DAOForkBlock
:
daoForkBlock
,
config
.
DAOForkSupport
=
false
}
return
config
}
// MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails.
...
...
core/block_validator.go
View file @
a87089fd
...
...
@@ -17,6 +17,7 @@
package
core
import
(
"bytes"
"fmt"
"math/big"
"time"
...
...
@@ -247,6 +248,26 @@ func ValidateHeader(config *ChainConfig, pow pow.PoW, header *types.Header, pare
return
&
BlockNonceErr
{
header
.
Number
,
header
.
Hash
(),
header
.
Nonce
.
Uint64
()}
}
}
// DAO hard-fork extension to the header validity: a) if the node is no-fork,
// do not accept blocks in the [fork, fork+10) range with the fork specific
// extra-data set; b) if the node is pro-fork, require blocks in the specific
// range to have the unique extra-data set.
if
daoBlock
:=
config
.
DAOForkBlock
;
daoBlock
!=
nil
{
// Check whether the block is among the fork extra-override range
limit
:=
new
(
big
.
Int
)
.
Add
(
daoBlock
,
params
.
DAOForkExtraRange
)
if
daoBlock
.
Cmp
(
header
.
Number
)
<=
0
&&
header
.
Number
.
Cmp
(
limit
)
<
0
{
// Depending whether we support or oppose the fork, verrift the extra-data contents
if
config
.
DAOForkSupport
{
if
bytes
.
Compare
(
header
.
Extra
,
params
.
DAOForkBlockExtra
)
!=
0
{
return
ValidationError
(
"DAO pro-fork bad block extra-data: 0x%x"
,
header
.
Extra
)
}
}
else
{
if
bytes
.
Compare
(
header
.
Extra
,
params
.
DAOForkBlockExtra
)
==
0
{
return
ValidationError
(
"DAO no-fork bad block extra-data: 0x%x"
,
header
.
Extra
)
}
}
}
}
return
nil
}
...
...
core/block_validator_test.go
View file @
a87089fd
...
...
@@ -27,6 +27,7 @@ import (
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/pow/ezp"
)
...
...
@@ -92,3 +93,107 @@ func TestPutReceipt(t *testing.T) {
t
.
Error
(
"expected to get 1 receipt, got none."
)
}
}
// Tests that DAO-fork enabled clients can properly filter out fork-commencing
// blocks based on their extradata fields.
func
TestDAOForkRangeExtradata
(
t
*
testing
.
T
)
{
forkBlock
:=
big
.
NewInt
(
32
)
// Generate a common prefix for both pro-forkers and non-forkers
db
,
_
:=
ethdb
.
NewMemDatabase
()
genesis
:=
WriteGenesisBlockForTesting
(
db
)
prefix
,
_
:=
GenerateChain
(
genesis
,
db
,
int
(
forkBlock
.
Int64
()
-
1
),
func
(
i
int
,
gen
*
BlockGen
)
{})
// Create the concurrent, conflicting two nodes
proDb
,
_
:=
ethdb
.
NewMemDatabase
()
WriteGenesisBlockForTesting
(
proDb
)
proBc
,
_
:=
NewBlockChain
(
proDb
,
&
ChainConfig
{
HomesteadBlock
:
big
.
NewInt
(
0
),
DAOForkBlock
:
forkBlock
,
DAOForkSupport
:
true
},
new
(
FakePow
),
new
(
event
.
TypeMux
))
conDb
,
_
:=
ethdb
.
NewMemDatabase
()
WriteGenesisBlockForTesting
(
conDb
)
conBc
,
_
:=
NewBlockChain
(
conDb
,
&
ChainConfig
{
HomesteadBlock
:
big
.
NewInt
(
0
),
DAOForkBlock
:
forkBlock
,
DAOForkSupport
:
false
},
new
(
FakePow
),
new
(
event
.
TypeMux
))
if
_
,
err
:=
proBc
.
InsertChain
(
prefix
);
err
!=
nil
{
t
.
Fatalf
(
"pro-fork: failed to import chain prefix: %v"
,
err
)
}
if
_
,
err
:=
conBc
.
InsertChain
(
prefix
);
err
!=
nil
{
t
.
Fatalf
(
"con-fork: failed to import chain prefix: %v"
,
err
)
}
// Try to expand both pro-fork and non-fork chains iteratively with other camp's blocks
for
i
:=
int64
(
0
);
i
<
params
.
DAOForkExtraRange
.
Int64
();
i
++
{
// Create a pro-fork block, and try to feed into the no-fork chain
db
,
_
=
ethdb
.
NewMemDatabase
()
WriteGenesisBlockForTesting
(
db
)
bc
,
_
:=
NewBlockChain
(
db
,
&
ChainConfig
{
HomesteadBlock
:
big
.
NewInt
(
0
)},
new
(
FakePow
),
new
(
event
.
TypeMux
))
blocks
:=
conBc
.
GetBlocksFromHash
(
conBc
.
CurrentBlock
()
.
Hash
(),
int
(
conBc
.
CurrentBlock
()
.
NumberU64
()
+
1
))
for
j
:=
0
;
j
<
len
(
blocks
)
/
2
;
j
++
{
blocks
[
j
],
blocks
[
len
(
blocks
)
-
1
-
j
]
=
blocks
[
len
(
blocks
)
-
1
-
j
],
blocks
[
j
]
}
if
_
,
err
:=
bc
.
InsertChain
(
blocks
);
err
!=
nil
{
t
.
Fatalf
(
"failed to import contra-fork chain for expansion: %v"
,
err
)
}
blocks
,
_
=
GenerateChain
(
conBc
.
CurrentBlock
(),
db
,
1
,
func
(
i
int
,
gen
*
BlockGen
)
{
gen
.
SetExtra
(
params
.
DAOForkBlockExtra
)
})
if
_
,
err
:=
conBc
.
InsertChain
(
blocks
);
err
==
nil
{
t
.
Fatalf
(
"contra-fork chain accepted pro-fork block: %v"
,
blocks
[
0
])
}
// Create a proper no-fork block for the contra-forker
blocks
,
_
=
GenerateChain
(
conBc
.
CurrentBlock
(),
db
,
1
,
func
(
i
int
,
gen
*
BlockGen
)
{})
if
_
,
err
:=
conBc
.
InsertChain
(
blocks
);
err
!=
nil
{
t
.
Fatalf
(
"contra-fork chain didn't accepted no-fork block: %v"
,
err
)
}
// Create a no-fork block, and try to feed into the pro-fork chain
db
,
_
=
ethdb
.
NewMemDatabase
()
WriteGenesisBlockForTesting
(
db
)
bc
,
_
=
NewBlockChain
(
db
,
&
ChainConfig
{
HomesteadBlock
:
big
.
NewInt
(
0
)},
new
(
FakePow
),
new
(
event
.
TypeMux
))
blocks
=
proBc
.
GetBlocksFromHash
(
proBc
.
CurrentBlock
()
.
Hash
(),
int
(
proBc
.
CurrentBlock
()
.
NumberU64
()
+
1
))
for
j
:=
0
;
j
<
len
(
blocks
)
/
2
;
j
++
{
blocks
[
j
],
blocks
[
len
(
blocks
)
-
1
-
j
]
=
blocks
[
len
(
blocks
)
-
1
-
j
],
blocks
[
j
]
}
if
_
,
err
:=
bc
.
InsertChain
(
blocks
);
err
!=
nil
{
t
.
Fatalf
(
"failed to import pro-fork chain for expansion: %v"
,
err
)
}
blocks
,
_
=
GenerateChain
(
proBc
.
CurrentBlock
(),
db
,
1
,
func
(
i
int
,
gen
*
BlockGen
)
{})
if
_
,
err
:=
proBc
.
InsertChain
(
blocks
);
err
==
nil
{
t
.
Fatalf
(
"pro-fork chain accepted contra-fork block: %v"
,
blocks
[
0
])
}
// Create a proper pro-fork block for the pro-forker
blocks
,
_
=
GenerateChain
(
proBc
.
CurrentBlock
(),
db
,
1
,
func
(
i
int
,
gen
*
BlockGen
)
{
gen
.
SetExtra
(
params
.
DAOForkBlockExtra
)
})
if
_
,
err
:=
proBc
.
InsertChain
(
blocks
);
err
!=
nil
{
t
.
Fatalf
(
"pro-fork chain didn't accepted pro-fork block: %v"
,
err
)
}
}
// Verify that contra-forkers accept pro-fork extra-datas after forking finishes
db
,
_
=
ethdb
.
NewMemDatabase
()
WriteGenesisBlockForTesting
(
db
)
bc
,
_
:=
NewBlockChain
(
db
,
&
ChainConfig
{
HomesteadBlock
:
big
.
NewInt
(
0
)},
new
(
FakePow
),
new
(
event
.
TypeMux
))
blocks
:=
conBc
.
GetBlocksFromHash
(
conBc
.
CurrentBlock
()
.
Hash
(),
int
(
conBc
.
CurrentBlock
()
.
NumberU64
()
+
1
))
for
j
:=
0
;
j
<
len
(
blocks
)
/
2
;
j
++
{
blocks
[
j
],
blocks
[
len
(
blocks
)
-
1
-
j
]
=
blocks
[
len
(
blocks
)
-
1
-
j
],
blocks
[
j
]
}
if
_
,
err
:=
bc
.
InsertChain
(
blocks
);
err
!=
nil
{
t
.
Fatalf
(
"failed to import contra-fork chain for expansion: %v"
,
err
)
}
blocks
,
_
=
GenerateChain
(
conBc
.
CurrentBlock
(),
db
,
1
,
func
(
i
int
,
gen
*
BlockGen
)
{
gen
.
SetExtra
(
params
.
DAOForkBlockExtra
)
})
if
_
,
err
:=
conBc
.
InsertChain
(
blocks
);
err
!=
nil
{
t
.
Fatalf
(
"contra-fork chain didn't accept pro-fork block post-fork: %v"
,
err
)
}
// Verify that pro-forkers accept contra-fork extra-datas after forking finishes
db
,
_
=
ethdb
.
NewMemDatabase
()
WriteGenesisBlockForTesting
(
db
)
bc
,
_
=
NewBlockChain
(
db
,
&
ChainConfig
{
HomesteadBlock
:
big
.
NewInt
(
0
)},
new
(
FakePow
),
new
(
event
.
TypeMux
))
blocks
=
proBc
.
GetBlocksFromHash
(
proBc
.
CurrentBlock
()
.
Hash
(),
int
(
proBc
.
CurrentBlock
()
.
NumberU64
()
+
1
))
for
j
:=
0
;
j
<
len
(
blocks
)
/
2
;
j
++
{
blocks
[
j
],
blocks
[
len
(
blocks
)
-
1
-
j
]
=
blocks
[
len
(
blocks
)
-
1
-
j
],
blocks
[
j
]
}
if
_
,
err
:=
bc
.
InsertChain
(
blocks
);
err
!=
nil
{
t
.
Fatalf
(
"failed to import pro-fork chain for expansion: %v"
,
err
)
}
blocks
,
_
=
GenerateChain
(
proBc
.
CurrentBlock
(),
db
,
1
,
func
(
i
int
,
gen
*
BlockGen
)
{})
if
_
,
err
:=
proBc
.
InsertChain
(
blocks
);
err
!=
nil
{
t
.
Fatalf
(
"pro-fork chain didn't accept contra-fork block post-fork: %v"
,
err
)
}
}
core/config.go
View file @
a87089fd
...
...
@@ -31,8 +31,9 @@ var ChainConfigNotFoundErr = errors.New("ChainConfig not found") // general conf
// that any network, identified by its genesis block, can have its own
// set of configuration options.
type
ChainConfig
struct
{
HomesteadBlock
*
big
.
Int
`json:"homesteadBlock"`
// homestead switch block (0 = already homestead)
DAOForkBlock
*
big
.
Int
`json:"daoForkBlock"`
// TheDAO hard-fork block (nil = no fork)
HomesteadBlock
*
big
.
Int
`json:"homesteadBlock"`
// Homestead switch block (nil = no fork, 0 = already homestead)
DAOForkBlock
*
big
.
Int
`json:"daoForkBlock"`
// TheDAO hard-fork switch block (nil = no fork)
DAOForkSupport
bool
`json:"daoForkSupport"`
// Whether the nodes supports or opposes the DAO hard-fork
VmConfig
vm
.
Config
`json:"-"`
}
...
...
miner/worker.go
View file @
a87089fd
...
...
@@ -17,6 +17,7 @@
package
miner
import
(
"bytes"
"fmt"
"math/big"
"sync"
...
...
@@ -469,12 +470,17 @@ func (self *worker) commitNewWork() {
Extra
:
self
.
extra
,
Time
:
big
.
NewInt
(
tstamp
),
}
// If we are
doing a
DAO hard-fork check whether to override the extra-data or not
// If we are
care about The
DAO hard-fork check whether to override the extra-data or not
if
daoBlock
:=
self
.
config
.
DAOForkBlock
;
daoBlock
!=
nil
{
// Check whether the block is among the fork extra-override range
limit
:=
new
(
big
.
Int
)
.
Add
(
daoBlock
,
params
.
DAOForkExtraRange
)
if
daoBlock
.
Cmp
(
header
.
Number
)
<=
0
&&
header
.
Number
.
Cmp
(
limit
)
<
0
{
header
.
Extra
=
common
.
CopyBytes
(
params
.
DAOForkBlockExtra
)
// Depending whether we support or oppose the fork, override differently
if
self
.
config
.
DAOForkSupport
{
header
.
Extra
=
common
.
CopyBytes
(
params
.
DAOForkBlockExtra
)
}
else
if
bytes
.
Compare
(
header
.
Extra
,
params
.
DAOForkBlockExtra
)
==
0
{
header
.
Extra
=
[]
byte
{}
// If miner opposes, don't let it use the reserved extra-data
}
}
}
previous
:=
self
.
current
...
...
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