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
da1efdae
Unverified
Commit
da1efdae
authored
Feb 04, 2019
by
Martin Holst Swende
Committed by
Péter Szilágyi
Feb 08, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: repro #18977
parent
4f3d22f0
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
104 additions
and
1 deletion
+104
-1
blockchain_test.go
core/blockchain_test.go
+48
-0
chain_makers.go
core/chain_makers.go
+56
-1
No files found.
core/blockchain_test.go
View file @
da1efdae
...
...
@@ -1483,3 +1483,51 @@ func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
benchmarkLargeNumberOfValueToNonexisting
(
b
,
numTxs
,
numBlocks
,
recipientFn
,
dataFn
)
}
// Tests that importing a very large side fork, which is larger than the canon chain,
// but where the difficulty per block is kept low: this means that it will not
// overtake the 'canon' chain until after it's passed canon by about 200 blocks.
func
TestLargeOldSidechainWithALowTdChain
(
t
*
testing
.
T
)
{
// Generate a canonical chain to act as the main dataset
engine
:=
ethash
.
NewFaker
()
db
:=
ethdb
.
NewMemDatabase
()
genesis
:=
new
(
Genesis
)
.
MustCommit
(
db
)
// We must use a pretty long chain to ensure that the fork
// doesn't overtake us until after at least 128 blocks post tip
blocks
,
_
:=
generateChain
(
params
.
TestChainConfig
,
genesis
,
engine
,
db
,
6
*
triesInMemory
,
func
(
i
int
,
b
*
BlockGen
)
{
b
.
SetCoinbase
(
common
.
Address
{
1
})
},
makeHeaderWithLargeDifficulty
)
// Import the canonical chain
diskdb
:=
ethdb
.
NewMemDatabase
()
new
(
Genesis
)
.
MustCommit
(
diskdb
)
chain
,
err
:=
NewBlockChain
(
diskdb
,
nil
,
params
.
TestChainConfig
,
engine
,
vm
.
Config
{},
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to create tester chain: %v"
,
err
)
}
for
i
:=
0
;
i
<
len
(
blocks
);
i
++
{
if
_
,
err
:=
chain
.
InsertChain
(
blocks
[
i
:
i
+
1
]);
err
!=
nil
{
t
.
Fatalf
(
"block %d: failed to insert into chain: %v"
,
i
,
err
)
}
}
// Dereference all the recent tries and ensure no past trie is left in
for
i
:=
0
;
i
<
triesInMemory
;
i
++
{
chain
.
stateCache
.
TrieDB
()
.
Dereference
(
blocks
[
len
(
blocks
)
-
1
-
i
]
.
Root
())
}
// Generate fork chain, starting from an early block
parent
:=
blocks
[
10
]
fork
,
_
:=
generateChain
(
params
.
TestChainConfig
,
parent
,
engine
,
db
,
256
+
6
*
triesInMemory
,
func
(
i
int
,
b
*
BlockGen
)
{
b
.
SetCoinbase
(
common
.
Address
{
2
})
},
makeHeaderWithSmallDifficulty
)
// And now import the fork
if
i
,
err
:=
chain
.
InsertChain
(
fork
);
err
!=
nil
{
t
.
Fatalf
(
"block %d: failed to insert into chain: %v"
,
i
,
err
)
}
head
:=
chain
.
CurrentBlock
()
if
got
:=
fork
[
len
(
fork
)
-
1
]
.
Hash
();
got
!=
head
.
Hash
()
{
t
.
Fatalf
(
"head wrong, expected %x got %x"
,
head
.
Hash
(),
got
)
}
td
:=
chain
.
GetTd
(
head
.
Hash
(),
head
.
NumberU64
())
fmt
.
Printf
(
"td %v"
,
td
)
}
core/chain_makers.go
View file @
da1efdae
...
...
@@ -48,6 +48,8 @@ type BlockGen struct {
engine
consensus
.
Engine
}
type
headerGenFn
func
(
chain
consensus
.
ChainReader
,
parent
*
types
.
Block
,
state
*
state
.
StateDB
,
engine
consensus
.
Engine
)
*
types
.
Header
// SetCoinbase sets the coinbase of the generated block.
// It can be called at most once.
func
(
b
*
BlockGen
)
SetCoinbase
(
addr
common
.
Address
)
{
...
...
@@ -170,6 +172,10 @@ func (b *BlockGen) OffsetTime(seconds int64) {
// values. Inserting them into BlockChain requires use of FakePow or
// a similar non-validating proof of work implementation.
func
GenerateChain
(
config
*
params
.
ChainConfig
,
parent
*
types
.
Block
,
engine
consensus
.
Engine
,
db
ethdb
.
Database
,
n
int
,
gen
func
(
int
,
*
BlockGen
))
([]
*
types
.
Block
,
[]
types
.
Receipts
)
{
return
generateChain
(
config
,
parent
,
engine
,
db
,
n
,
gen
,
makeHeader
)
}
func
generateChain
(
config
*
params
.
ChainConfig
,
parent
*
types
.
Block
,
engine
consensus
.
Engine
,
db
ethdb
.
Database
,
n
int
,
gen
func
(
int
,
*
BlockGen
),
headerGen
headerGenFn
)
([]
*
types
.
Block
,
[]
types
.
Receipts
)
{
if
config
==
nil
{
config
=
params
.
TestChainConfig
}
...
...
@@ -177,7 +183,8 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
chainreader
:=
&
fakeChainReader
{
config
:
config
}
genblock
:=
func
(
i
int
,
parent
*
types
.
Block
,
statedb
*
state
.
StateDB
)
(
*
types
.
Block
,
types
.
Receipts
)
{
b
:=
&
BlockGen
{
i
:
i
,
chain
:
blocks
,
parent
:
parent
,
statedb
:
statedb
,
config
:
config
,
engine
:
engine
}
b
.
header
=
makeHeader
(
chainreader
,
parent
,
statedb
,
b
.
engine
)
//b.header = makeHeader(chainreader, parent, statedb, b.engine)
b
.
header
=
headerGen
(
chainreader
,
parent
,
statedb
,
b
.
engine
)
// Mutate the state and block according to any hard-fork specs
if
daoBlock
:=
config
.
DAOForkBlock
;
daoBlock
!=
nil
{
...
...
@@ -248,6 +255,54 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S
}
}
func
makeHeaderWithLargeDifficulty
(
chain
consensus
.
ChainReader
,
parent
*
types
.
Block
,
state
*
state
.
StateDB
,
engine
consensus
.
Engine
)
*
types
.
Header
{
var
time
*
big
.
Int
if
parent
.
Time
()
==
nil
{
time
=
big
.
NewInt
(
1
)
}
else
{
time
=
new
(
big
.
Int
)
.
Add
(
parent
.
Time
(),
big
.
NewInt
(
1
))
// block time is fixed at 10 seconds
}
return
&
types
.
Header
{
Root
:
state
.
IntermediateRoot
(
chain
.
Config
()
.
IsEIP158
(
parent
.
Number
())),
ParentHash
:
parent
.
Hash
(),
Coinbase
:
parent
.
Coinbase
(),
Difficulty
:
engine
.
CalcDifficulty
(
chain
,
time
.
Uint64
(),
&
types
.
Header
{
Number
:
parent
.
Number
(),
Time
:
new
(
big
.
Int
)
.
Sub
(
time
,
big
.
NewInt
(
1
)),
Difficulty
:
parent
.
Difficulty
(),
UncleHash
:
parent
.
UncleHash
(),
}),
GasLimit
:
CalcGasLimit
(
parent
,
parent
.
GasLimit
(),
parent
.
GasLimit
()),
Number
:
new
(
big
.
Int
)
.
Add
(
parent
.
Number
(),
common
.
Big1
),
Time
:
time
,
}
}
func
makeHeaderWithSmallDifficulty
(
chain
consensus
.
ChainReader
,
parent
*
types
.
Block
,
state
*
state
.
StateDB
,
engine
consensus
.
Engine
)
*
types
.
Header
{
var
time
*
big
.
Int
if
parent
.
Time
()
==
nil
{
time
=
big
.
NewInt
(
30
)
}
else
{
time
=
new
(
big
.
Int
)
.
Add
(
parent
.
Time
(),
big
.
NewInt
(
30
))
// block time is fixed at 10 seconds
}
return
&
types
.
Header
{
Root
:
state
.
IntermediateRoot
(
chain
.
Config
()
.
IsEIP158
(
parent
.
Number
())),
ParentHash
:
parent
.
Hash
(),
Coinbase
:
parent
.
Coinbase
(),
Difficulty
:
engine
.
CalcDifficulty
(
chain
,
time
.
Uint64
(),
&
types
.
Header
{
Number
:
parent
.
Number
(),
Time
:
new
(
big
.
Int
)
.
Sub
(
time
,
big
.
NewInt
(
30
)),
Difficulty
:
parent
.
Difficulty
(),
UncleHash
:
parent
.
UncleHash
(),
}),
GasLimit
:
CalcGasLimit
(
parent
,
parent
.
GasLimit
(),
parent
.
GasLimit
()),
Number
:
new
(
big
.
Int
)
.
Add
(
parent
.
Number
(),
common
.
Big1
),
Time
:
time
,
}
}
// makeHeaderChain creates a deterministic chain of headers rooted at parent.
func
makeHeaderChain
(
parent
*
types
.
Header
,
n
int
,
engine
consensus
.
Engine
,
db
ethdb
.
Database
,
seed
int
)
[]
*
types
.
Header
{
blocks
:=
makeBlockChain
(
types
.
NewBlockWithHeader
(
parent
),
n
,
engine
,
db
,
seed
)
...
...
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