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
1d42888d
Commit
1d42888d
authored
Jun 16, 2015
by
Felix Lange
Committed by
Jeffrey Wilcke
Jun 29, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core/types: make blocks immutable
parent
654564e1
Changes
17
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
446 additions
and
576 deletions
+446
-576
block_cache_test.go
core/block_cache_test.go
+3
-3
block_processor.go
core/block_processor.go
+49
-46
block_processor_test.go
core/block_processor_test.go
+7
-9
chain_makers.go
core/chain_makers.go
+23
-35
chain_manager.go
core/chain_manager.go
+28
-66
chain_manager_test.go
core/chain_manager_test.go
+15
-15
genesis.go
core/genesis.go
+11
-26
state_transition.go
core/state_transition.go
+5
-4
transaction_pool.go
core/transaction_pool.go
+1
-1
block.go
core/types/block.go
+184
-237
vm_env.go
core/vm_env.go
+17
-17
downloader_test.go
eth/downloader/downloader_test.go
+4
-1
agent.go
miner/agent.go
+2
-4
remote_agent.go
miner/remote_agent.go
+1
-3
worker.go
miner/worker.go
+86
-98
block_test_util.go
tests/block_test_util.go
+5
-6
xeth.go
xeth/xeth.go
+5
-5
No files found.
core/block_cache_test.go
View file @
1d42888d
...
@@ -11,12 +11,12 @@ import (
...
@@ -11,12 +11,12 @@ import (
func
newChain
(
size
int
)
(
chain
[]
*
types
.
Block
)
{
func
newChain
(
size
int
)
(
chain
[]
*
types
.
Block
)
{
var
parentHash
common
.
Hash
var
parentHash
common
.
Hash
for
i
:=
0
;
i
<
size
;
i
++
{
for
i
:=
0
;
i
<
size
;
i
++
{
block
:=
types
.
NewBlock
(
parentHash
,
common
.
Address
{},
common
.
Hash
{},
new
(
big
.
Int
),
0
,
nil
)
head
:=
&
types
.
Header
{
ParentHash
:
parentHash
,
Number
:
big
.
NewInt
(
int64
(
i
))}
block
.
Header
()
.
Number
=
big
.
NewInt
(
int64
(
i
)
)
block
:=
types
.
NewBlock
(
head
,
nil
,
nil
,
nil
)
chain
=
append
(
chain
,
block
)
chain
=
append
(
chain
,
block
)
parentHash
=
block
.
Hash
()
parentHash
=
block
.
Hash
()
}
}
return
return
chain
}
}
func
insertChainCache
(
cache
*
BlockCache
,
chain
[]
*
types
.
Block
)
{
func
insertChainCache
(
cache
*
BlockCache
,
chain
[]
*
types
.
Block
)
{
...
...
core/block_processor.go
View file @
1d42888d
...
@@ -57,8 +57,8 @@ func NewBlockProcessor(db, extra common.Database, pow pow.PoW, chainManager *Cha
...
@@ -57,8 +57,8 @@ func NewBlockProcessor(db, extra common.Database, pow pow.PoW, chainManager *Cha
}
}
func
(
sm
*
BlockProcessor
)
TransitionState
(
statedb
*
state
.
StateDB
,
parent
,
block
*
types
.
Block
,
transientProcess
bool
)
(
receipts
types
.
Receipts
,
err
error
)
{
func
(
sm
*
BlockProcessor
)
TransitionState
(
statedb
*
state
.
StateDB
,
parent
,
block
*
types
.
Block
,
transientProcess
bool
)
(
receipts
types
.
Receipts
,
err
error
)
{
coinbase
:=
statedb
.
GetOrNewStateObject
(
block
.
Header
()
.
Coinbase
)
coinbase
:=
statedb
.
GetOrNewStateObject
(
block
.
Coinbase
()
)
coinbase
.
SetGasLimit
(
block
.
Header
()
.
GasLimit
)
coinbase
.
SetGasLimit
(
block
.
GasLimit
()
)
// Process the transactions on to parent state
// Process the transactions on to parent state
receipts
,
err
=
sm
.
ApplyTransactions
(
coinbase
,
statedb
,
block
,
block
.
Transactions
(),
transientProcess
)
receipts
,
err
=
sm
.
ApplyTransactions
(
coinbase
,
statedb
,
block
,
block
.
Transactions
(),
transientProcess
)
...
@@ -69,11 +69,11 @@ func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block
...
@@ -69,11 +69,11 @@ func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block
return
receipts
,
nil
return
receipts
,
nil
}
}
func
(
self
*
BlockProcessor
)
ApplyTransaction
(
coinbase
*
state
.
StateObject
,
statedb
*
state
.
StateDB
,
block
*
types
.
Block
,
tx
*
types
.
Transaction
,
usedGas
*
big
.
Int
,
transientProcess
bool
)
(
*
types
.
Receipt
,
*
big
.
Int
,
error
)
{
func
(
self
*
BlockProcessor
)
ApplyTransaction
(
coinbase
*
state
.
StateObject
,
statedb
*
state
.
StateDB
,
header
*
types
.
Header
,
tx
*
types
.
Transaction
,
usedGas
*
big
.
Int
,
transientProcess
bool
)
(
*
types
.
Receipt
,
*
big
.
Int
,
error
)
{
// If we are mining this block and validating we want to set the logs back to 0
// If we are mining this block and validating we want to set the logs back to 0
cb
:=
statedb
.
GetStateObject
(
coinbase
.
Address
())
cb
:=
statedb
.
GetStateObject
(
coinbase
.
Address
())
_
,
gas
,
err
:=
ApplyMessage
(
NewEnv
(
statedb
,
self
.
bc
,
tx
,
block
),
tx
,
cb
)
_
,
gas
,
err
:=
ApplyMessage
(
NewEnv
(
statedb
,
self
.
bc
,
tx
,
header
),
tx
,
cb
)
if
err
!=
nil
&&
(
IsNonceErr
(
err
)
||
state
.
IsGasLimitErr
(
err
)
||
IsInvalidTxErr
(
err
))
{
if
err
!=
nil
&&
(
IsNonceErr
(
err
)
||
state
.
IsGasLimitErr
(
err
)
||
IsInvalidTxErr
(
err
))
{
return
nil
,
nil
,
err
return
nil
,
nil
,
err
}
}
...
@@ -108,12 +108,13 @@ func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state
...
@@ -108,12 +108,13 @@ func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state
totalUsedGas
=
big
.
NewInt
(
0
)
totalUsedGas
=
big
.
NewInt
(
0
)
err
error
err
error
cumulativeSum
=
new
(
big
.
Int
)
cumulativeSum
=
new
(
big
.
Int
)
header
=
block
.
Header
()
)
)
for
i
,
tx
:=
range
txs
{
for
i
,
tx
:=
range
txs
{
statedb
.
StartRecord
(
tx
.
Hash
(),
block
.
Hash
(),
i
)
statedb
.
StartRecord
(
tx
.
Hash
(),
block
.
Hash
(),
i
)
receipt
,
txGas
,
err
:=
self
.
ApplyTransaction
(
coinbase
,
statedb
,
block
,
tx
,
totalUsedGas
,
transientProcess
)
receipt
,
txGas
,
err
:=
self
.
ApplyTransaction
(
coinbase
,
statedb
,
header
,
tx
,
totalUsedGas
,
transientProcess
)
if
err
!=
nil
&&
(
IsNonceErr
(
err
)
||
state
.
IsGasLimitErr
(
err
)
||
IsInvalidTxErr
(
err
))
{
if
err
!=
nil
&&
(
IsNonceErr
(
err
)
||
state
.
IsGasLimitErr
(
err
)
||
IsInvalidTxErr
(
err
))
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -142,11 +143,10 @@ func (sm *BlockProcessor) RetryProcess(block *types.Block) (logs state.Logs, err
...
@@ -142,11 +143,10 @@ func (sm *BlockProcessor) RetryProcess(block *types.Block) (logs state.Logs, err
sm
.
mutex
.
Lock
()
sm
.
mutex
.
Lock
()
defer
sm
.
mutex
.
Unlock
()
defer
sm
.
mutex
.
Unlock
()
header
:=
block
.
Header
()
if
!
sm
.
bc
.
HasBlock
(
block
.
ParentHash
())
{
if
!
sm
.
bc
.
HasBlock
(
header
.
ParentHash
)
{
return
nil
,
ParentError
(
block
.
ParentHash
())
return
nil
,
ParentError
(
header
.
ParentHash
)
}
}
parent
:=
sm
.
bc
.
GetBlock
(
header
.
ParentHash
)
parent
:=
sm
.
bc
.
GetBlock
(
block
.
ParentHash
()
)
// FIXME Change to full header validation. See #1225
// FIXME Change to full header validation. See #1225
errch
:=
make
(
chan
bool
)
errch
:=
make
(
chan
bool
)
...
@@ -168,30 +168,32 @@ func (sm *BlockProcessor) Process(block *types.Block) (logs state.Logs, err erro
...
@@ -168,30 +168,32 @@ func (sm *BlockProcessor) Process(block *types.Block) (logs state.Logs, err erro
sm
.
mutex
.
Lock
()
sm
.
mutex
.
Lock
()
defer
sm
.
mutex
.
Unlock
()
defer
sm
.
mutex
.
Unlock
()
header
:=
block
.
Header
()
if
sm
.
bc
.
HasBlock
(
block
.
Hash
())
{
if
sm
.
bc
.
HasBlock
(
header
.
Hash
())
{
return
nil
,
&
KnownBlockError
{
block
.
Number
(),
block
.
Hash
()}
return
nil
,
&
KnownBlockError
{
header
.
Number
,
header
.
Hash
()}
}
}
if
!
sm
.
bc
.
HasBlock
(
header
.
ParentHash
)
{
if
!
sm
.
bc
.
HasBlock
(
block
.
ParentHash
()
)
{
return
nil
,
ParentError
(
header
.
ParentHash
)
return
nil
,
ParentError
(
block
.
ParentHash
()
)
}
}
parent
:=
sm
.
bc
.
GetBlock
(
header
.
ParentHash
)
parent
:=
sm
.
bc
.
GetBlock
(
block
.
ParentHash
()
)
return
sm
.
processWithParent
(
block
,
parent
)
return
sm
.
processWithParent
(
block
,
parent
)
}
}
func
(
sm
*
BlockProcessor
)
processWithParent
(
block
,
parent
*
types
.
Block
)
(
logs
state
.
Logs
,
err
error
)
{
func
(
sm
*
BlockProcessor
)
processWithParent
(
block
,
parent
*
types
.
Block
)
(
logs
state
.
Logs
,
err
error
)
{
// Create a new state based on the parent's root (e.g., create copy)
// Create a new state based on the parent's root (e.g., create copy)
state
:=
state
.
New
(
parent
.
Root
(),
sm
.
db
)
state
:=
state
.
New
(
parent
.
Root
(),
sm
.
db
)
header
:=
block
.
Header
()
uncles
:=
block
.
Uncles
()
txs
:=
block
.
Transactions
()
// Block validation
// Block validation
if
err
=
ValidateHeader
(
sm
.
Pow
,
block
.
Header
()
,
parent
.
Header
(),
false
);
err
!=
nil
{
if
err
=
ValidateHeader
(
sm
.
Pow
,
header
,
parent
.
Header
(),
false
);
err
!=
nil
{
return
return
}
}
// There can be at most two uncles
// There can be at most two uncles
if
len
(
block
.
Uncles
()
)
>
2
{
if
len
(
uncles
)
>
2
{
return
nil
,
ValidationError
(
"Block can only contain maximum 2 uncles (contained %v)"
,
len
(
block
.
Uncles
()
))
return
nil
,
ValidationError
(
"Block can only contain maximum 2 uncles (contained %v)"
,
len
(
uncles
))
}
}
receipts
,
err
:=
sm
.
TransitionState
(
state
,
parent
,
block
,
false
)
receipts
,
err
:=
sm
.
TransitionState
(
state
,
parent
,
block
,
false
)
...
@@ -199,8 +201,6 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
...
@@ -199,8 +201,6 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
return
return
}
}
header
:=
block
.
Header
()
// 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
)
...
@@ -211,7 +211,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
...
@@ -211,7 +211,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
// 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
(
txs
)
if
txSha
!=
header
.
TxHash
{
if
txSha
!=
header
.
TxHash
{
err
=
fmt
.
Errorf
(
"invalid transaction root hash. received=%x calculated=%x"
,
header
.
TxHash
,
txSha
)
err
=
fmt
.
Errorf
(
"invalid transaction root hash. received=%x calculated=%x"
,
header
.
TxHash
,
txSha
)
return
return
...
@@ -225,7 +225,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
...
@@ -225,7 +225,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
}
}
// Verify UncleHash before running other uncle validations
// Verify UncleHash before running other uncle validations
unclesSha
:=
block
.
CalculateUnclesHash
(
)
unclesSha
:=
types
.
CalcUncleHash
(
uncles
)
if
unclesSha
!=
header
.
UncleHash
{
if
unclesSha
!=
header
.
UncleHash
{
err
=
fmt
.
Errorf
(
"invalid uncles root hash. received=%x calculated=%x"
,
header
.
UncleHash
,
unclesSha
)
err
=
fmt
.
Errorf
(
"invalid uncles root hash. received=%x calculated=%x"
,
header
.
UncleHash
,
unclesSha
)
return
return
...
@@ -236,7 +236,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
...
@@ -236,7 +236,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
return
return
}
}
// Accumulate static rewards; block reward, uncle's and uncle inclusion.
// Accumulate static rewards; block reward, uncle's and uncle inclusion.
AccumulateRewards
(
state
,
block
)
AccumulateRewards
(
state
,
header
,
uncles
)
// Commit state objects/accounts to a temporary trie (does not save)
// Commit state objects/accounts to a temporary trie (does not save)
// used to calculate the state root.
// used to calculate the state root.
...
@@ -260,11 +260,34 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
...
@@ -260,11 +260,34 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
return
state
.
Logs
(),
nil
return
state
.
Logs
(),
nil
}
}
// AccumulateRewards credits the coinbase of the given block with the
// mining reward. The total reward consists of the static block reward
// and rewards for included uncles.
func
AccumulateRewards
(
statedb
*
state
.
StateDB
,
header
*
types
.
Header
,
uncles
[]
*
types
.
Header
)
{
reward
:=
new
(
big
.
Int
)
.
Set
(
BlockReward
)
for
_
,
uncle
:=
range
uncles
{
num
:=
new
(
big
.
Int
)
.
Add
(
big
.
NewInt
(
8
),
uncle
.
Number
)
num
.
Sub
(
num
,
header
.
Number
)
r
:=
new
(
big
.
Int
)
r
.
Mul
(
BlockReward
,
num
)
r
.
Div
(
r
,
big
.
NewInt
(
8
))
statedb
.
AddBalance
(
uncle
.
Coinbase
,
r
)
reward
.
Add
(
reward
,
new
(
big
.
Int
)
.
Div
(
BlockReward
,
big
.
NewInt
(
32
)))
}
// Get the account associated with the coinbase
statedb
.
AddBalance
(
header
.
Coinbase
,
reward
)
}
func
(
sm
*
BlockProcessor
)
VerifyUncles
(
statedb
*
state
.
StateDB
,
block
,
parent
*
types
.
Block
)
error
{
func
(
sm
*
BlockProcessor
)
VerifyUncles
(
statedb
*
state
.
StateDB
,
block
,
parent
*
types
.
Block
)
error
{
ancestors
:=
set
.
New
()
ancestors
:=
set
.
New
()
uncles
:=
set
.
New
()
uncles
:=
set
.
New
()
ancestorHeaders
:=
make
(
map
[
common
.
Hash
]
*
types
.
Header
)
ancestorHeaders
:=
make
(
map
[
common
.
Hash
]
*
types
.
Header
)
for
_
,
ancestor
:=
range
sm
.
bc
.
Get
Ancestors
(
block
,
7
)
{
for
_
,
ancestor
:=
range
sm
.
bc
.
Get
BlocksFromHash
(
block
.
ParentHash
()
,
7
)
{
ancestorHeaders
[
ancestor
.
Hash
()]
=
ancestor
.
Header
()
ancestorHeaders
[
ancestor
.
Hash
()]
=
ancestor
.
Header
()
ancestors
.
Add
(
ancestor
.
Hash
())
ancestors
.
Add
(
ancestor
.
Hash
())
// Include ancestors uncles in the uncle set. Uncles must be unique.
// Include ancestors uncles in the uncle set. Uncles must be unique.
...
@@ -325,7 +348,7 @@ func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err erro
...
@@ -325,7 +348,7 @@ func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err erro
// TODO: remove backward compatibility
// TODO: remove backward compatibility
var
(
var
(
parent
=
sm
.
bc
.
GetBlock
(
block
.
Header
()
.
ParentHash
)
parent
=
sm
.
bc
.
GetBlock
(
block
.
ParentHash
()
)
state
=
state
.
New
(
parent
.
Root
(),
sm
.
db
)
state
=
state
.
New
(
parent
.
Root
(),
sm
.
db
)
)
)
...
@@ -341,7 +364,7 @@ func ValidateHeader(pow pow.PoW, block, parent *types.Header, checkPow bool) err
...
@@ -341,7 +364,7 @@ func ValidateHeader(pow pow.PoW, block, parent *types.Header, checkPow bool) err
return
fmt
.
Errorf
(
"Block extra data too long (%d)"
,
len
(
block
.
Extra
))
return
fmt
.
Errorf
(
"Block extra data too long (%d)"
,
len
(
block
.
Extra
))
}
}
expd
:=
CalcDifficulty
(
block
,
parent
)
expd
:=
CalcDifficulty
(
int64
(
block
.
Time
),
int64
(
parent
.
Time
),
parent
.
Difficulty
)
if
expd
.
Cmp
(
block
.
Difficulty
)
!=
0
{
if
expd
.
Cmp
(
block
.
Difficulty
)
!=
0
{
return
fmt
.
Errorf
(
"Difficulty check failed for block %v, %v"
,
block
.
Difficulty
,
expd
)
return
fmt
.
Errorf
(
"Difficulty check failed for block %v, %v"
,
block
.
Difficulty
,
expd
)
}
}
...
@@ -375,26 +398,6 @@ func ValidateHeader(pow pow.PoW, block, parent *types.Header, checkPow bool) err
...
@@ -375,26 +398,6 @@ func ValidateHeader(pow pow.PoW, block, parent *types.Header, checkPow bool) err
return
nil
return
nil
}
}
func
AccumulateRewards
(
statedb
*
state
.
StateDB
,
block
*
types
.
Block
)
{
reward
:=
new
(
big
.
Int
)
.
Set
(
BlockReward
)
for
_
,
uncle
:=
range
block
.
Uncles
()
{
num
:=
new
(
big
.
Int
)
.
Add
(
big
.
NewInt
(
8
),
uncle
.
Number
)
num
.
Sub
(
num
,
block
.
Number
())
r
:=
new
(
big
.
Int
)
r
.
Mul
(
BlockReward
,
num
)
r
.
Div
(
r
,
big
.
NewInt
(
8
))
statedb
.
AddBalance
(
uncle
.
Coinbase
,
r
)
reward
.
Add
(
reward
,
new
(
big
.
Int
)
.
Div
(
BlockReward
,
big
.
NewInt
(
32
)))
}
// Get the account associated with the coinbase
statedb
.
AddBalance
(
block
.
Header
()
.
Coinbase
,
reward
)
}
func
getBlockReceipts
(
db
common
.
Database
,
bhash
common
.
Hash
)
(
receipts
types
.
Receipts
,
err
error
)
{
func
getBlockReceipts
(
db
common
.
Database
,
bhash
common
.
Hash
)
(
receipts
types
.
Receipts
,
err
error
)
{
var
rdata
[]
byte
var
rdata
[]
byte
rdata
,
err
=
db
.
Get
(
append
(
receiptsPre
,
bhash
[
:
]
...
))
rdata
,
err
=
db
.
Get
(
append
(
receiptsPre
,
bhash
[
:
]
...
))
...
...
core/block_processor_test.go
View file @
1d42888d
...
@@ -26,20 +26,18 @@ func proc() (*BlockProcessor, *ChainManager) {
...
@@ -26,20 +26,18 @@ func proc() (*BlockProcessor, *ChainManager) {
}
}
func
TestNumber
(
t
*
testing
.
T
)
{
func
TestNumber
(
t
*
testing
.
T
)
{
_
,
chain
:=
proc
()
block1
:=
chain
.
NewBlock
(
common
.
Address
{})
block1
.
Header
()
.
Number
=
big
.
NewInt
(
3
)
block1
.
Header
()
.
Time
--
pow
:=
ezp
.
New
()
pow
:=
ezp
.
New
()
err
:=
ValidateHeader
(
pow
,
block1
.
Header
(),
chain
.
Genesis
()
.
Header
(),
false
)
bp
,
chain
:=
proc
()
header
:=
makeHeader
(
chain
.
Genesis
(),
0
,
bp
.
db
,
0
)
header
.
Number
=
big
.
NewInt
(
3
)
err
:=
ValidateHeader
(
pow
,
header
,
chain
.
Genesis
()
.
Header
(),
false
)
if
err
!=
BlockNumberErr
{
if
err
!=
BlockNumberErr
{
t
.
Errorf
(
"expected block number error
%v
"
,
err
)
t
.
Errorf
(
"expected block number error
, got %q
"
,
err
)
}
}
block1
=
chain
.
NewBlock
(
common
.
Address
{}
)
header
=
makeHeader
(
chain
.
Genesis
(),
0
,
bp
.
db
,
0
)
err
=
ValidateHeader
(
pow
,
block1
.
Header
()
,
chain
.
Genesis
()
.
Header
(),
false
)
err
=
ValidateHeader
(
pow
,
header
,
chain
.
Genesis
()
.
Header
(),
false
)
if
err
==
BlockNumberErr
{
if
err
==
BlockNumberErr
{
t
.
Errorf
(
"didn't expect block number error"
)
t
.
Errorf
(
"didn't expect block number error"
)
}
}
...
...
core/chain_makers.go
View file @
1d42888d
...
@@ -29,12 +29,8 @@ var (
...
@@ -29,12 +29,8 @@ var (
// Utility functions for making chains on the fly
// Utility functions for making chains on the fly
// Exposed for sake of testing from other packages (eg. go-ethash)
// Exposed for sake of testing from other packages (eg. go-ethash)
func
NewBlockFromParent
(
addr
common
.
Address
,
parent
*
types
.
Block
)
*
types
.
Block
{
return
newBlockFromParent
(
addr
,
parent
)
}
func
MakeBlock
(
bman
*
BlockProcessor
,
parent
*
types
.
Block
,
i
int
,
db
common
.
Database
,
seed
int
)
*
types
.
Block
{
func
MakeBlock
(
bman
*
BlockProcessor
,
parent
*
types
.
Block
,
i
int
,
db
common
.
Database
,
seed
int
)
*
types
.
Block
{
return
makeBlock
(
bman
,
parent
,
i
,
db
,
seed
)
return
types
.
NewBlock
(
makeHeader
(
parent
,
i
,
db
,
seed
),
nil
,
nil
,
nil
)
}
}
func
MakeChain
(
bman
*
BlockProcessor
,
parent
*
types
.
Block
,
max
int
,
db
common
.
Database
,
seed
int
)
types
.
Blocks
{
func
MakeChain
(
bman
*
BlockProcessor
,
parent
*
types
.
Block
,
max
int
,
db
common
.
Database
,
seed
int
)
types
.
Blocks
{
...
@@ -53,46 +49,38 @@ func NewCanonical(n int, db common.Database) (*BlockProcessor, error) {
...
@@ -53,46 +49,38 @@ func NewCanonical(n int, db common.Database) (*BlockProcessor, error) {
return
newCanonical
(
n
,
db
)
return
newCanonical
(
n
,
db
)
}
}
// block time is fixed at 10 seconds
// makeHeader creates the header for a new empty block, simulating
func
newBlockFromParent
(
addr
common
.
Address
,
parent
*
types
.
Block
)
*
types
.
Block
{
// what miner would do. We seed chains by the first byte of the coinbase.
block
:=
types
.
NewBlock
(
parent
.
Hash
(),
addr
,
parent
.
Root
(),
common
.
BigPow
(
2
,
32
),
0
,
nil
)
func
makeHeader
(
parent
*
types
.
Block
,
i
int
,
db
common
.
Database
,
seed
int
)
*
types
.
Header
{
block
.
SetUncles
(
nil
)
block
.
SetTransactions
(
nil
)
block
.
SetReceipts
(
nil
)
header
:=
block
.
Header
()
header
.
Difficulty
=
CalcDifficulty
(
block
.
Header
(),
parent
.
Header
())
header
.
Number
=
new
(
big
.
Int
)
.
Add
(
parent
.
Header
()
.
Number
,
common
.
Big1
)
header
.
Time
=
parent
.
Header
()
.
Time
+
10
header
.
GasLimit
=
CalcGasLimit
(
parent
)
block
.
Td
=
parent
.
Td
return
block
}
// Actually make a block by simulating what miner would do
// we seed chains by the first byte of the coinbase
func
makeBlock
(
bman
*
BlockProcessor
,
parent
*
types
.
Block
,
i
int
,
db
common
.
Database
,
seed
int
)
*
types
.
Block
{
var
addr
common
.
Address
var
addr
common
.
Address
addr
[
0
],
addr
[
19
]
=
byte
(
seed
),
byte
(
i
)
addr
[
0
],
addr
[
19
]
=
byte
(
seed
),
byte
(
i
)
// 'random' coinbase
block
:=
newBlockFromParent
(
addr
,
parent
)
time
:=
parent
.
Time
()
+
10
// block time is fixed at 10 seconds
state
:=
state
.
New
(
block
.
Root
(),
db
)
// ensure that the block's coinbase has the block reward in the state.
state
:=
state
.
New
(
parent
.
Root
(),
db
)
cbase
:=
state
.
GetOrNewStateObject
(
addr
)
cbase
:=
state
.
GetOrNewStateObject
(
addr
)
cbase
.
SetGasLimit
(
CalcGasLimit
(
parent
))
cbase
.
SetGasLimit
(
CalcGasLimit
(
parent
))
cbase
.
AddBalance
(
BlockReward
)
cbase
.
AddBalance
(
BlockReward
)
state
.
Update
()
state
.
Update
()
block
.
SetRoot
(
state
.
Root
())
return
block
return
&
types
.
Header
{
Root
:
state
.
Root
(),
ParentHash
:
parent
.
Hash
(),
Coinbase
:
addr
,
Difficulty
:
CalcDifficulty
(
time
,
parent
.
Time
(),
parent
.
Difficulty
()),
Number
:
new
(
big
.
Int
)
.
Add
(
parent
.
Number
(),
common
.
Big1
),
Time
:
uint64
(
time
),
GasLimit
:
CalcGasLimit
(
parent
),
}
}
}
// Make a chain with real blocks
// makeChain creates a valid chain of empty blocks.
// Runs ProcessWithParent to get proper state roots
func
makeChain
(
bman
*
BlockProcessor
,
parent
*
types
.
Block
,
max
int
,
db
common
.
Database
,
seed
int
)
types
.
Blocks
{
func
makeChain
(
bman
*
BlockProcessor
,
parent
*
types
.
Block
,
max
int
,
db
common
.
Database
,
seed
int
)
types
.
Blocks
{
bman
.
bc
.
currentBlock
=
parent
bman
.
bc
.
currentBlock
=
parent
blocks
:=
make
(
types
.
Blocks
,
max
)
blocks
:=
make
(
types
.
Blocks
,
max
)
for
i
:=
0
;
i
<
max
;
i
++
{
for
i
:=
0
;
i
<
max
;
i
++
{
block
:=
makeBlock
(
bman
,
parent
,
i
,
db
,
seed
)
block
:=
types
.
NewBlock
(
makeHeader
(
parent
,
i
,
db
,
seed
),
nil
,
nil
,
nil
)
// Use ProcessWithParent to verify that we have produced a valid block.
_
,
err
:=
bman
.
processWithParent
(
block
,
parent
)
_
,
err
:=
bman
.
processWithParent
(
block
,
parent
)
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Println
(
"process with parent failed"
,
err
)
fmt
.
Println
(
"process with parent failed"
,
err
)
...
@@ -129,7 +117,7 @@ func newBlockProcessor(db common.Database, cman *ChainManager, eventMux *event.T
...
@@ -129,7 +117,7 @@ func newBlockProcessor(db common.Database, cman *ChainManager, eventMux *event.T
}
}
// Make a new, deterministic canonical chain by running InsertChain
// Make a new, deterministic canonical chain by running InsertChain
// on result of makeChain
// on result of makeChain
.
func
newCanonical
(
n
int
,
db
common
.
Database
)
(
*
BlockProcessor
,
error
)
{
func
newCanonical
(
n
int
,
db
common
.
Database
)
(
*
BlockProcessor
,
error
)
{
eventMux
:=
&
event
.
TypeMux
{}
eventMux
:=
&
event
.
TypeMux
{}
...
...
core/chain_manager.go
View file @
1d42888d
...
@@ -38,23 +38,24 @@ const (
...
@@ -38,23 +38,24 @@ const (
maxTimeFutureBlocks
=
30
maxTimeFutureBlocks
=
30
)
)
func
CalcDifficulty
(
block
,
parent
*
types
.
Header
)
*
big
.
Int
{
// 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
)
diff
:=
new
(
big
.
Int
)
adjust
:=
new
(
big
.
Int
)
.
Div
(
parentDiff
,
params
.
DifficultyBoundDivisor
)
adjust
:=
new
(
big
.
Int
)
.
Div
(
parent
.
Difficulty
,
params
.
DifficultyBoundDivisor
)
if
big
.
NewInt
(
time
-
parentTime
)
.
Cmp
(
params
.
DurationLimit
)
<
0
{
if
big
.
NewInt
(
int64
(
block
.
Time
)
-
int64
(
parent
.
Time
))
.
Cmp
(
params
.
DurationLimit
)
<
0
{
diff
.
Add
(
parentDiff
,
adjust
)
diff
.
Add
(
parent
.
Difficulty
,
adjust
)
}
else
{
}
else
{
diff
.
Sub
(
parent
.
Difficulty
,
adjust
)
diff
.
Sub
(
parent
Diff
,
adjust
)
}
}
if
diff
.
Cmp
(
params
.
MinimumDifficulty
)
<
0
{
if
diff
.
Cmp
(
params
.
MinimumDifficulty
)
<
0
{
return
params
.
MinimumDifficulty
return
params
.
MinimumDifficulty
}
}
return
diff
return
diff
}
}
// CalcTD computes the total difficulty of block.
func
CalcTD
(
block
,
parent
*
types
.
Block
)
*
big
.
Int
{
func
CalcTD
(
block
,
parent
*
types
.
Block
)
*
big
.
Int
{
if
parent
==
nil
{
if
parent
==
nil
{
return
block
.
Difficulty
()
return
block
.
Difficulty
()
...
@@ -62,6 +63,8 @@ func CalcTD(block, parent *types.Block) *big.Int {
...
@@ -62,6 +63,8 @@ func CalcTD(block, parent *types.Block) *big.Int {
return
new
(
big
.
Int
)
.
Add
(
parent
.
Td
,
block
.
Header
()
.
Difficulty
)
return
new
(
big
.
Int
)
.
Add
(
parent
.
Td
,
block
.
Header
()
.
Difficulty
)
}
}
// 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
{
func
CalcGasLimit
(
parent
*
types
.
Block
)
*
big
.
Int
{
decay
:=
new
(
big
.
Int
)
.
Div
(
parent
.
GasLimit
(),
params
.
GasLimitBoundDivisor
)
decay
:=
new
(
big
.
Int
)
.
Div
(
parent
.
GasLimit
(),
params
.
GasLimitBoundDivisor
)
contrib
:=
new
(
big
.
Int
)
.
Mul
(
parent
.
GasUsed
(),
big
.
NewInt
(
3
))
contrib
:=
new
(
big
.
Int
)
.
Mul
(
parent
.
GasUsed
(),
big
.
NewInt
(
3
))
...
@@ -71,11 +74,11 @@ func CalcGasLimit(parent *types.Block) *big.Int {
...
@@ -71,11 +74,11 @@ func CalcGasLimit(parent *types.Block) *big.Int {
gl
:=
new
(
big
.
Int
)
.
Sub
(
parent
.
GasLimit
(),
decay
)
gl
:=
new
(
big
.
Int
)
.
Sub
(
parent
.
GasLimit
(),
decay
)
gl
=
gl
.
Add
(
gl
,
contrib
)
gl
=
gl
.
Add
(
gl
,
contrib
)
gl
=
gl
.
Add
(
gl
,
big
.
NewInt
(
1
))
gl
=
gl
.
Add
(
gl
,
big
.
NewInt
(
1
))
gl
=
common
.
BigMax
(
gl
,
params
.
MinGasLimit
)
gl
.
Set
(
common
.
BigMax
(
gl
,
params
.
MinGasLimit
)
)
if
gl
.
Cmp
(
params
.
GenesisGasLimit
)
<
0
{
if
gl
.
Cmp
(
params
.
GenesisGasLimit
)
<
0
{
gl
2
:=
new
(
big
.
Int
)
.
Add
(
parent
.
GasLimit
(),
decay
)
gl
.
Add
(
parent
.
GasLimit
(),
decay
)
return
common
.
BigMin
(
params
.
GenesisGasLimit
,
gl2
)
gl
.
Set
(
common
.
BigMin
(
gl
,
params
.
GenesisGasLimit
)
)
}
}
return
gl
return
gl
}
}
...
@@ -255,50 +258,11 @@ func (bc *ChainManager) makeCache() {
...
@@ -255,50 +258,11 @@ func (bc *ChainManager) makeCache() {
bc
.
cache
=
NewBlockCache
(
blockCacheLimit
)
bc
.
cache
=
NewBlockCache
(
blockCacheLimit
)
}
}
// load in last `blockCacheLimit` - 1 blocks. Last block is the current.
// load in last `blockCacheLimit` - 1 blocks. Last block is the current.
ancestors
:=
bc
.
GetAncestors
(
bc
.
currentBlock
,
blockCacheLimit
-
1
)
for
_
,
block
:=
range
bc
.
GetBlocksFromHash
(
bc
.
currentBlock
.
Hash
(),
blockCacheLimit
)
{
ancestors
=
append
(
ancestors
,
bc
.
currentBlock
)
for
_
,
block
:=
range
ancestors
{
bc
.
cache
.
Push
(
block
)
bc
.
cache
.
Push
(
block
)
}
}
}
}
// Block creation & chain handling
func
(
bc
*
ChainManager
)
NewBlock
(
coinbase
common
.
Address
)
*
types
.
Block
{
bc
.
mu
.
RLock
()
defer
bc
.
mu
.
RUnlock
()
var
(
root
common
.
Hash
parentHash
common
.
Hash
)
if
bc
.
currentBlock
!=
nil
{
root
=
bc
.
currentBlock
.
Header
()
.
Root
parentHash
=
bc
.
lastBlockHash
}
block
:=
types
.
NewBlock
(
parentHash
,
coinbase
,
root
,
common
.
BigPow
(
2
,
32
),
0
,
nil
)
block
.
SetUncles
(
nil
)
block
.
SetTransactions
(
nil
)
block
.
SetReceipts
(
nil
)
parent
:=
bc
.
currentBlock
if
parent
!=
nil
{
header
:=
block
.
Header
()
header
.
Difficulty
=
CalcDifficulty
(
block
.
Header
(),
parent
.
Header
())
header
.
Number
=
new
(
big
.
Int
)
.
Add
(
parent
.
Header
()
.
Number
,
common
.
Big1
)
header
.
GasLimit
=
CalcGasLimit
(
parent
)
}
return
block
}
func
(
bc
*
ChainManager
)
Reset
()
{
func
(
bc
*
ChainManager
)
Reset
()
{
bc
.
mu
.
Lock
()
bc
.
mu
.
Lock
()
defer
bc
.
mu
.
Unlock
()
defer
bc
.
mu
.
Unlock
()
...
@@ -463,6 +427,19 @@ func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
...
@@ -463,6 +427,19 @@ func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
}
}
// GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
func
(
self
*
ChainManager
)
GetBlocksFromHash
(
hash
common
.
Hash
,
n
int
)
(
blocks
[]
*
types
.
Block
)
{
for
i
:=
0
;
i
<
n
;
i
++
{
block
:=
self
.
GetBlock
(
hash
)
if
block
==
nil
{
break
}
blocks
=
append
(
blocks
,
block
)
hash
=
block
.
ParentHash
()
}
return
}
// non blocking version
// non blocking version
func
(
self
*
ChainManager
)
getBlockByNumber
(
num
uint64
)
*
types
.
Block
{
func
(
self
*
ChainManager
)
getBlockByNumber
(
num
uint64
)
*
types
.
Block
{
key
,
_
:=
self
.
blockDb
.
Get
(
append
(
blockNumPre
,
big
.
NewInt
(
int64
(
num
))
.
Bytes
()
...
))
key
,
_
:=
self
.
blockDb
.
Get
(
append
(
blockNumPre
,
big
.
NewInt
(
int64
(
num
))
.
Bytes
()
...
))
...
@@ -482,19 +459,6 @@ func (self *ChainManager) GetUnclesInChain(block *types.Block, length int) (uncl
...
@@ -482,19 +459,6 @@ func (self *ChainManager) GetUnclesInChain(block *types.Block, length int) (uncl
return
return
}
}
func
(
self
*
ChainManager
)
GetAncestors
(
block
*
types
.
Block
,
length
int
)
(
blocks
[]
*
types
.
Block
)
{
for
i
:=
0
;
i
<
length
;
i
++
{
block
=
self
.
GetBlock
(
block
.
ParentHash
())
if
block
==
nil
{
break
}
blocks
=
append
(
blocks
,
block
)
}
return
}
// setTotalDifficulty updates the TD of the chain manager. Note, this function
// setTotalDifficulty updates the TD of the chain manager. Note, this function
// assumes that the `mu` mutex is held!
// assumes that the `mu` mutex is held!
func
(
bc
*
ChainManager
)
setTotalDifficulty
(
td
*
big
.
Int
)
{
func
(
bc
*
ChainManager
)
setTotalDifficulty
(
td
*
big
.
Int
)
{
...
@@ -621,14 +585,12 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
...
@@ -621,14 +585,12 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
return
i
,
fmt
.
Errorf
(
"%v: BlockFutureErr, %v > %v"
,
BlockFutureErr
,
block
.
Time
(),
max
)
return
i
,
fmt
.
Errorf
(
"%v: BlockFutureErr, %v > %v"
,
BlockFutureErr
,
block
.
Time
(),
max
)
}
}
block
.
SetQueued
(
true
)
self
.
futureBlocks
.
Push
(
block
)
self
.
futureBlocks
.
Push
(
block
)
stats
.
queued
++
stats
.
queued
++
continue
continue
}
}
if
IsParentErr
(
err
)
&&
self
.
futureBlocks
.
Has
(
block
.
ParentHash
())
{
if
IsParentErr
(
err
)
&&
self
.
futureBlocks
.
Has
(
block
.
ParentHash
())
{
block
.
SetQueued
(
true
)
self
.
futureBlocks
.
Push
(
block
)
self
.
futureBlocks
.
Push
(
block
)
stats
.
queued
++
stats
.
queued
++
continue
continue
...
...
core/chain_manager_test.go
View file @
1d42888d
...
@@ -117,7 +117,7 @@ func testChain(chainB types.Blocks, bman *BlockProcessor) (*big.Int, error) {
...
@@ -117,7 +117,7 @@ func testChain(chainB types.Blocks, bman *BlockProcessor) (*big.Int, error) {
}
}
func
loadChain
(
fn
string
,
t
*
testing
.
T
)
(
types
.
Blocks
,
error
)
{
func
loadChain
(
fn
string
,
t
*
testing
.
T
)
(
types
.
Blocks
,
error
)
{
fh
,
err
:=
os
.
OpenFile
(
filepath
.
Join
(
os
.
Getenv
(
"GOPATH"
),
"src"
,
"github.com"
,
"ethereum"
,
"go-ethereum
"
,
"_data"
,
fn
),
os
.
O_RDONLY
,
os
.
ModePerm
)
fh
,
err
:=
os
.
OpenFile
(
filepath
.
Join
(
"..
"
,
"_data"
,
fn
),
os
.
O_RDONLY
,
os
.
ModePerm
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -265,7 +265,7 @@ func TestBrokenChain(t *testing.T) {
...
@@ -265,7 +265,7 @@ func TestBrokenChain(t *testing.T) {
}
}
func
TestChainInsertions
(
t
*
testing
.
T
)
{
func
TestChainInsertions
(
t
*
testing
.
T
)
{
t
.
Skip
(
)
// travil fails.
t
.
Skip
(
"Skipped: outdated test files"
)
db
,
_
:=
ethdb
.
NewMemDatabase
()
db
,
_
:=
ethdb
.
NewMemDatabase
()
...
@@ -303,7 +303,7 @@ func TestChainInsertions(t *testing.T) {
...
@@ -303,7 +303,7 @@ func TestChainInsertions(t *testing.T) {
}
}
func
TestChainMultipleInsertions
(
t
*
testing
.
T
)
{
func
TestChainMultipleInsertions
(
t
*
testing
.
T
)
{
t
.
Skip
(
)
// travil fails.
t
.
Skip
(
"Skipped: outdated test files"
)
db
,
_
:=
ethdb
.
NewMemDatabase
()
db
,
_
:=
ethdb
.
NewMemDatabase
()
...
@@ -346,8 +346,8 @@ func TestChainMultipleInsertions(t *testing.T) {
...
@@ -346,8 +346,8 @@ func TestChainMultipleInsertions(t *testing.T) {
}
}
}
}
func
TestGet
Ancestors
(
t
*
testing
.
T
)
{
func
TestGet
BlocksFromHash
(
t
*
testing
.
T
)
{
t
.
Skip
(
)
// travil fails.
t
.
Skip
(
"Skipped: outdated test files"
)
db
,
_
:=
ethdb
.
NewMemDatabase
()
db
,
_
:=
ethdb
.
NewMemDatabase
()
chainMan
:=
theChainManager
(
db
,
t
)
chainMan
:=
theChainManager
(
db
,
t
)
...
@@ -361,8 +361,8 @@ func TestGetAncestors(t *testing.T) {
...
@@ -361,8 +361,8 @@ func TestGetAncestors(t *testing.T) {
chainMan
.
write
(
block
)
chainMan
.
write
(
block
)
}
}
ancestors
:=
chainMan
.
GetAncestors
(
chain
[
len
(
chain
)
-
1
]
,
4
)
blocks
:=
chainMan
.
GetBlocksFromHash
(
chain
[
len
(
chain
)
-
1
]
.
Hash
()
,
4
)
fmt
.
Println
(
ancestor
s
)
fmt
.
Println
(
block
s
)
}
}
type
bproc
struct
{}
type
bproc
struct
{}
...
@@ -372,15 +372,17 @@ func (bproc) Process(*types.Block) (state.Logs, error) { return nil, nil }
...
@@ -372,15 +372,17 @@ func (bproc) Process(*types.Block) (state.Logs, error) { return nil, nil }
func
makeChainWithDiff
(
genesis
*
types
.
Block
,
d
[]
int
,
seed
byte
)
[]
*
types
.
Block
{
func
makeChainWithDiff
(
genesis
*
types
.
Block
,
d
[]
int
,
seed
byte
)
[]
*
types
.
Block
{
var
chain
[]
*
types
.
Block
var
chain
[]
*
types
.
Block
for
i
,
difficulty
:=
range
d
{
for
i
,
difficulty
:=
range
d
{
header
:=
&
types
.
Header
{
Number
:
big
.
NewInt
(
int64
(
i
+
1
)),
Difficulty
:
big
.
NewInt
(
int64
(
difficulty
))}
header
:=
&
types
.
Header
{
block
:=
types
.
NewBlockWithHeader
(
header
)
Coinbase
:
common
.
Address
{
seed
},
copy
(
block
.
HeaderHash
[
:
2
],
[]
byte
{
byte
(
i
+
1
),
seed
})
Number
:
big
.
NewInt
(
int64
(
i
+
1
)),
Difficulty
:
big
.
NewInt
(
int64
(
difficulty
)),
}
if
i
==
0
{
if
i
==
0
{
block
.
ParentHeader
Hash
=
genesis
.
Hash
()
header
.
Parent
Hash
=
genesis
.
Hash
()
}
else
{
}
else
{
copy
(
block
.
ParentHeaderHash
[
:
2
],
[]
byte
{
byte
(
i
),
seed
}
)
header
.
ParentHash
=
chain
[
i
-
1
]
.
Hash
(
)
}
}
block
:=
types
.
NewBlockWithHeader
(
header
)
chain
=
append
(
chain
,
block
)
chain
=
append
(
chain
,
block
)
}
}
return
chain
return
chain
...
@@ -399,7 +401,6 @@ func chm(genesis *types.Block, db common.Database) *ChainManager {
...
@@ -399,7 +401,6 @@ func chm(genesis *types.Block, db common.Database) *ChainManager {
}
}
func
TestReorgLongest
(
t
*
testing
.
T
)
{
func
TestReorgLongest
(
t
*
testing
.
T
)
{
t
.
Skip
(
"skipped while cache is removed"
)
db
,
_
:=
ethdb
.
NewMemDatabase
()
db
,
_
:=
ethdb
.
NewMemDatabase
()
genesis
:=
GenesisBlock
(
0
,
db
)
genesis
:=
GenesisBlock
(
0
,
db
)
bc
:=
chm
(
genesis
,
db
)
bc
:=
chm
(
genesis
,
db
)
...
@@ -419,7 +420,6 @@ func TestReorgLongest(t *testing.T) {
...
@@ -419,7 +420,6 @@ func TestReorgLongest(t *testing.T) {
}
}
func
TestReorgShortest
(
t
*
testing
.
T
)
{
func
TestReorgShortest
(
t
*
testing
.
T
)
{
t
.
Skip
(
"skipped while cache is removed"
)
db
,
_
:=
ethdb
.
NewMemDatabase
()
db
,
_
:=
ethdb
.
NewMemDatabase
()
genesis
:=
GenesisBlock
(
0
,
db
)
genesis
:=
GenesisBlock
(
0
,
db
)
bc
:=
chm
(
genesis
,
db
)
bc
:=
chm
(
genesis
,
db
)
...
...
core/genesis.go
View file @
1d42888d
...
@@ -11,38 +11,18 @@ import (
...
@@ -11,38 +11,18 @@ import (
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/params"
)
)
/*
// GenesisBlock creates a genesis block with the given nonce.
* This is the special genesis block.
*/
var
ZeroHash256
=
make
([]
byte
,
32
)
var
ZeroHash160
=
make
([]
byte
,
20
)
var
ZeroHash512
=
make
([]
byte
,
64
)
func
GenesisBlock
(
nonce
uint64
,
db
common
.
Database
)
*
types
.
Block
{
func
GenesisBlock
(
nonce
uint64
,
db
common
.
Database
)
*
types
.
Block
{
genesis
:=
types
.
NewBlock
(
common
.
Hash
{},
common
.
Address
{},
common
.
Hash
{},
params
.
GenesisDifficulty
,
nonce
,
nil
)
genesis
.
Header
()
.
Number
=
common
.
Big0
genesis
.
Header
()
.
GasLimit
=
params
.
GenesisGasLimit
genesis
.
Header
()
.
GasUsed
=
common
.
Big0
genesis
.
Header
()
.
Time
=
0
genesis
.
Td
=
common
.
Big0
genesis
.
SetUncles
([]
*
types
.
Header
{})
genesis
.
SetTransactions
(
types
.
Transactions
{})
genesis
.
SetReceipts
(
types
.
Receipts
{})
var
accounts
map
[
string
]
struct
{
var
accounts
map
[
string
]
struct
{
Balance
string
Balance
string
Code
string
Code
string
}
}
err
:=
json
.
Unmarshal
(
GenesisAccounts
,
&
accounts
)
err
:=
json
.
Unmarshal
(
GenesisAccounts
,
&
accounts
)
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Println
(
"
e
nable to decode genesis json data:"
,
err
)
fmt
.
Println
(
"
u
nable to decode genesis json data:"
,
err
)
os
.
Exit
(
1
)
os
.
Exit
(
1
)
}
}
statedb
:=
state
.
New
(
common
.
Hash
{},
db
)
statedb
:=
state
.
New
(
genesis
.
Root
(),
db
)
for
addr
,
account
:=
range
accounts
{
for
addr
,
account
:=
range
accounts
{
codedAddr
:=
common
.
Hex2Bytes
(
addr
)
codedAddr
:=
common
.
Hex2Bytes
(
addr
)
accountState
:=
statedb
.
CreateAccount
(
common
.
BytesToAddress
(
codedAddr
))
accountState
:=
statedb
.
CreateAccount
(
common
.
BytesToAddress
(
codedAddr
))
...
@@ -51,10 +31,15 @@ func GenesisBlock(nonce uint64, db common.Database) *types.Block {
...
@@ -51,10 +31,15 @@ func GenesisBlock(nonce uint64, db common.Database) *types.Block {
statedb
.
UpdateStateObject
(
accountState
)
statedb
.
UpdateStateObject
(
accountState
)
}
}
statedb
.
Sync
()
statedb
.
Sync
()
genesis
.
Header
()
.
Root
=
statedb
.
Root
()
genesis
.
Td
=
params
.
GenesisDifficulty
return
genesis
block
:=
types
.
NewBlock
(
&
types
.
Header
{
Difficulty
:
params
.
GenesisDifficulty
,
GasLimit
:
params
.
GenesisGasLimit
,
Nonce
:
types
.
EncodeNonce
(
nonce
),
Root
:
statedb
.
Root
(),
},
nil
,
nil
,
nil
)
block
.
Td
=
params
.
GenesisDifficulty
return
block
}
}
var
GenesisAccounts
=
[]
byte
(
`{
var
GenesisAccounts
=
[]
byte
(
`{
...
...
core/state_transition.go
View file @
1d42888d
...
@@ -73,16 +73,17 @@ func MessageGasValue(msg Message) *big.Int {
...
@@ -73,16 +73,17 @@ func MessageGasValue(msg Message) *big.Int {
return
new
(
big
.
Int
)
.
Mul
(
msg
.
Gas
(),
msg
.
GasPrice
())
return
new
(
big
.
Int
)
.
Mul
(
msg
.
Gas
(),
msg
.
GasPrice
())
}
}
func
IntrinsicGas
(
msg
Message
)
*
big
.
Int
{
// IntrinsicGas computes the 'intrisic gas' for a message
// with the given data.
func
IntrinsicGas
(
data
[]
byte
)
*
big
.
Int
{
igas
:=
new
(
big
.
Int
)
.
Set
(
params
.
TxGas
)
igas
:=
new
(
big
.
Int
)
.
Set
(
params
.
TxGas
)
for
_
,
byt
:=
range
msg
.
Data
()
{
for
_
,
byt
:=
range
data
{
if
byt
!=
0
{
if
byt
!=
0
{
igas
.
Add
(
igas
,
params
.
TxDataNonZeroGas
)
igas
.
Add
(
igas
,
params
.
TxDataNonZeroGas
)
}
else
{
}
else
{
igas
.
Add
(
igas
,
params
.
TxDataZeroGas
)
igas
.
Add
(
igas
,
params
.
TxDataZeroGas
)
}
}
}
}
return
igas
return
igas
}
}
...
@@ -195,7 +196,7 @@ func (self *StateTransition) transitionState() (ret []byte, usedGas *big.Int, er
...
@@ -195,7 +196,7 @@ func (self *StateTransition) transitionState() (ret []byte, usedGas *big.Int, er
sender
,
_
:=
self
.
From
()
// err checked in preCheck
sender
,
_
:=
self
.
From
()
// err checked in preCheck
// Pay intrinsic gas
// Pay intrinsic gas
if
err
=
self
.
UseGas
(
IntrinsicGas
(
self
.
msg
));
err
!=
nil
{
if
err
=
self
.
UseGas
(
IntrinsicGas
(
self
.
msg
.
Data
()
));
err
!=
nil
{
return
nil
,
nil
,
InvalidTxError
(
err
)
return
nil
,
nil
,
InvalidTxError
(
err
)
}
}
...
...
core/transaction_pool.go
View file @
1d42888d
...
@@ -180,7 +180,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction) error {
...
@@ -180,7 +180,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction) error {
}
}
// Should supply enough intrinsic gas
// Should supply enough intrinsic gas
if
tx
.
Gas
()
.
Cmp
(
IntrinsicGas
(
tx
))
<
0
{
if
tx
.
Gas
()
.
Cmp
(
IntrinsicGas
(
tx
.
Data
()
))
<
0
{
return
ErrIntrinsicGas
return
ErrIntrinsicGas
}
}
...
...
core/types/block.go
View file @
1d42888d
This diff is collapsed.
Click to expand it.
core/vm_env.go
View file @
1d42888d
...
@@ -10,32 +10,32 @@ import (
...
@@ -10,32 +10,32 @@ import (
)
)
type
VMEnv
struct
{
type
VMEnv
struct
{
state
*
state
.
StateDB
state
*
state
.
StateDB
block
*
types
.
Block
header
*
types
.
Header
msg
Message
msg
Message
depth
int
depth
int
chain
*
ChainManager
chain
*
ChainManager
typ
vm
.
Type
typ
vm
.
Type
// structured logging
// structured logging
logs
[]
vm
.
StructLog
logs
[]
vm
.
StructLog
}
}
func
NewEnv
(
state
*
state
.
StateDB
,
chain
*
ChainManager
,
msg
Message
,
block
*
types
.
Block
)
*
VMEnv
{
func
NewEnv
(
state
*
state
.
StateDB
,
chain
*
ChainManager
,
msg
Message
,
header
*
types
.
Header
)
*
VMEnv
{
return
&
VMEnv
{
return
&
VMEnv
{
chain
:
chain
,
chain
:
chain
,
state
:
state
,
state
:
state
,
block
:
block
,
header
:
header
,
msg
:
msg
,
msg
:
msg
,
typ
:
vm
.
StdVmTy
,
typ
:
vm
.
StdVmTy
,
}
}
}
}
func
(
self
*
VMEnv
)
Origin
()
common
.
Address
{
f
,
_
:=
self
.
msg
.
From
();
return
f
}
func
(
self
*
VMEnv
)
Origin
()
common
.
Address
{
f
,
_
:=
self
.
msg
.
From
();
return
f
}
func
(
self
*
VMEnv
)
BlockNumber
()
*
big
.
Int
{
return
self
.
block
.
Number
()
}
func
(
self
*
VMEnv
)
BlockNumber
()
*
big
.
Int
{
return
self
.
header
.
Number
}
func
(
self
*
VMEnv
)
Coinbase
()
common
.
Address
{
return
self
.
block
.
Coinbase
()
}
func
(
self
*
VMEnv
)
Coinbase
()
common
.
Address
{
return
self
.
header
.
Coinbase
}
func
(
self
*
VMEnv
)
Time
()
int64
{
return
self
.
block
.
Time
(
)
}
func
(
self
*
VMEnv
)
Time
()
int64
{
return
int64
(
self
.
header
.
Time
)
}
func
(
self
*
VMEnv
)
Difficulty
()
*
big
.
Int
{
return
self
.
block
.
Difficulty
()
}
func
(
self
*
VMEnv
)
Difficulty
()
*
big
.
Int
{
return
self
.
header
.
Difficulty
}
func
(
self
*
VMEnv
)
GasLimit
()
*
big
.
Int
{
return
self
.
block
.
GasLimit
()
}
func
(
self
*
VMEnv
)
GasLimit
()
*
big
.
Int
{
return
self
.
header
.
GasLimit
}
func
(
self
*
VMEnv
)
Value
()
*
big
.
Int
{
return
self
.
msg
.
Value
()
}
func
(
self
*
VMEnv
)
Value
()
*
big
.
Int
{
return
self
.
msg
.
Value
()
}
func
(
self
*
VMEnv
)
State
()
*
state
.
StateDB
{
return
self
.
state
}
func
(
self
*
VMEnv
)
State
()
*
state
.
StateDB
{
return
self
.
state
}
func
(
self
*
VMEnv
)
Depth
()
int
{
return
self
.
depth
}
func
(
self
*
VMEnv
)
Depth
()
int
{
return
self
.
depth
}
...
...
eth/downloader/downloader_test.go
View file @
1d42888d
...
@@ -40,7 +40,10 @@ func createHashes(amount int, root common.Hash) (hashes []common.Hash) {
...
@@ -40,7 +40,10 @@ func createHashes(amount int, root common.Hash) (hashes []common.Hash) {
// createBlock assembles a new block at the given chain height.
// createBlock assembles a new block at the given chain height.
func
createBlock
(
i
int
,
parent
,
hash
common
.
Hash
)
*
types
.
Block
{
func
createBlock
(
i
int
,
parent
,
hash
common
.
Hash
)
*
types
.
Block
{
header
:=
&
types
.
Header
{
Number
:
big
.
NewInt
(
int64
(
i
))}
header
:=
&
types
.
Header
{
Hash
:
hash
,
Number
:
big
.
NewInt
(
int64
(
i
))
}
block
:=
types
.
NewBlockWithHeader
(
header
)
block
:=
types
.
NewBlockWithHeader
(
header
)
block
.
HeaderHash
=
hash
block
.
HeaderHash
=
hash
block
.
ParentHeaderHash
=
parent
block
.
ParentHeaderHash
=
parent
...
...
miner/agent.go
View file @
1d42888d
...
@@ -90,15 +90,13 @@ done:
...
@@ -90,15 +90,13 @@ done:
}
}
}
}
func
(
self
*
CpuAgent
)
mine
(
block
*
types
.
Block
,
stop
<-
chan
struct
{})
{
func
(
self
*
CpuAgent
)
mine
(
block
*
types
.
Block
,
stop
<-
chan
struct
{})
{
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"(re)started agent[%d]. mining...
\n
"
,
self
.
index
)
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"(re)started agent[%d]. mining...
\n
"
,
self
.
index
)
// Mine
// Mine
nonce
,
mixDigest
:=
self
.
pow
.
Search
(
block
,
stop
)
nonce
,
mixDigest
:=
self
.
pow
.
Search
(
block
,
stop
)
if
nonce
!=
0
{
if
nonce
!=
0
{
block
.
SetNonce
(
nonce
)
self
.
returnCh
<-
block
.
WithMiningResult
(
nonce
,
common
.
BytesToHash
(
mixDigest
))
block
.
Header
()
.
MixDigest
=
common
.
BytesToHash
(
mixDigest
)
self
.
returnCh
<-
block
}
else
{
}
else
{
self
.
returnCh
<-
nil
self
.
returnCh
<-
nil
}
}
...
...
miner/remote_agent.go
View file @
1d42888d
...
@@ -81,9 +81,7 @@ func (a *RemoteAgent) SubmitWork(nonce uint64, mixDigest, seedHash common.Hash)
...
@@ -81,9 +81,7 @@ func (a *RemoteAgent) SubmitWork(nonce uint64, mixDigest, seedHash common.Hash)
// Make sure the external miner was working on the right hash
// Make sure the external miner was working on the right hash
if
a
.
currentWork
!=
nil
&&
a
.
work
!=
nil
{
if
a
.
currentWork
!=
nil
&&
a
.
work
!=
nil
{
a
.
currentWork
.
SetNonce
(
nonce
)
a
.
returnCh
<-
a
.
currentWork
.
WithMiningResult
(
nonce
,
mixDigest
)
a
.
currentWork
.
Header
()
.
MixDigest
=
mixDigest
a
.
returnCh
<-
a
.
currentWork
//a.returnCh <- Work{a.currentWork.Number().Uint64(), nonce, mixDigest.Bytes(), seedHash.Bytes()}
//a.returnCh <- Work{a.currentWork.Number().Uint64(), nonce, mixDigest.Bytes(), seedHash.Bytes()}
return
true
return
true
}
}
...
...
miner/worker.go
View file @
1d42888d
This diff is collapsed.
Click to expand it.
tests/block_test_util.go
View file @
1d42888d
...
@@ -245,7 +245,7 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
...
@@ -245,7 +245,7 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
if
b
.
BlockHeader
==
nil
{
if
b
.
BlockHeader
==
nil
{
continue
// OK - block is supposed to be invalid, continue with next block
continue
// OK - block is supposed to be invalid, continue with next block
}
else
{
}
else
{
return
fmt
.
Errorf
(
"Block RLP decoding failed when expected to succeed: "
,
err
)
return
fmt
.
Errorf
(
"Block RLP decoding failed when expected to succeed:
%v
"
,
err
)
}
}
}
}
// RLP decoding worked, try to insert into chain:
// RLP decoding worked, try to insert into chain:
...
@@ -254,7 +254,7 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
...
@@ -254,7 +254,7 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
if
b
.
BlockHeader
==
nil
{
if
b
.
BlockHeader
==
nil
{
continue
// OK - block is supposed to be invalid, continue with next block
continue
// OK - block is supposed to be invalid, continue with next block
}
else
{
}
else
{
return
fmt
.
Errorf
(
"Block insertion into chain failed: "
,
err
)
return
fmt
.
Errorf
(
"Block insertion into chain failed:
%v
"
,
err
)
}
}
}
}
if
b
.
BlockHeader
==
nil
{
if
b
.
BlockHeader
==
nil
{
...
@@ -262,7 +262,7 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
...
@@ -262,7 +262,7 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
}
}
err
=
t
.
validateBlockHeader
(
b
.
BlockHeader
,
cb
.
Header
())
err
=
t
.
validateBlockHeader
(
b
.
BlockHeader
,
cb
.
Header
())
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"Block header validation failed: "
,
err
)
return
fmt
.
Errorf
(
"Block header validation failed:
%v
"
,
err
)
}
}
}
}
return
nil
return
nil
...
@@ -286,7 +286,7 @@ func (s *BlockTest) validateBlockHeader(h *btHeader, h2 *types.Header) error {
...
@@ -286,7 +286,7 @@ func (s *BlockTest) validateBlockHeader(h *btHeader, h2 *types.Header) error {
expectedNonce
:=
mustConvertBytes
(
h
.
Nonce
)
expectedNonce
:=
mustConvertBytes
(
h
.
Nonce
)
if
!
bytes
.
Equal
(
expectedNonce
,
h2
.
Nonce
[
:
])
{
if
!
bytes
.
Equal
(
expectedNonce
,
h2
.
Nonce
[
:
])
{
return
fmt
.
Errorf
(
"Nonce: expected: %v, decoded: %v"
,
expectedNonce
,
h2
.
Nonce
[
:
]
)
return
fmt
.
Errorf
(
"Nonce: expected: %v, decoded: %v"
,
expectedNonce
,
h2
.
Nonce
)
}
}
expectedNumber
:=
mustConvertBigInt
(
h
.
Number
,
16
)
expectedNumber
:=
mustConvertBigInt
(
h
.
Number
,
16
)
...
@@ -423,9 +423,8 @@ func mustConvertHeader(in btHeader) *types.Header {
...
@@ -423,9 +423,8 @@ func mustConvertHeader(in btHeader) *types.Header {
GasLimit
:
mustConvertBigInt
(
in
.
GasLimit
,
16
),
GasLimit
:
mustConvertBigInt
(
in
.
GasLimit
,
16
),
Difficulty
:
mustConvertBigInt
(
in
.
Difficulty
,
16
),
Difficulty
:
mustConvertBigInt
(
in
.
Difficulty
,
16
),
Time
:
mustConvertUint
(
in
.
Timestamp
,
16
),
Time
:
mustConvertUint
(
in
.
Timestamp
,
16
),
Nonce
:
types
.
EncodeNonce
(
mustConvertUint
(
in
.
Nonce
,
16
)),
}
}
// XXX cheats? :-)
header
.
SetNonce
(
mustConvertUint
(
in
.
Nonce
,
16
))
return
header
return
header
}
}
...
...
xeth/xeth.go
View file @
1d42888d
...
@@ -209,8 +209,8 @@ func (self *XEth) AtStateNum(num int64) *XEth {
...
@@ -209,8 +209,8 @@ func (self *XEth) AtStateNum(num int64) *XEth {
// - could be removed in favour of mining on testdag (natspec e2e + networking)
// - could be removed in favour of mining on testdag (natspec e2e + networking)
// + filters
// + filters
func
(
self
*
XEth
)
ApplyTestTxs
(
statedb
*
state
.
StateDB
,
address
common
.
Address
,
txc
uint64
)
(
uint64
,
*
XEth
)
{
func
(
self
*
XEth
)
ApplyTestTxs
(
statedb
*
state
.
StateDB
,
address
common
.
Address
,
txc
uint64
)
(
uint64
,
*
XEth
)
{
chain
:=
self
.
backend
.
ChainManager
()
block
:=
self
.
backend
.
ChainManager
()
.
NewBlock
(
address
)
header
:=
chain
.
CurrentBlock
()
.
Header
(
)
coinbase
:=
statedb
.
GetStateObject
(
address
)
coinbase
:=
statedb
.
GetStateObject
(
address
)
coinbase
.
SetGasLimit
(
big
.
NewInt
(
10000000
))
coinbase
.
SetGasLimit
(
big
.
NewInt
(
10000000
))
txs
:=
self
.
backend
.
TxPool
()
.
GetQueuedTransactions
()
txs
:=
self
.
backend
.
TxPool
()
.
GetQueuedTransactions
()
...
@@ -218,7 +218,7 @@ func (self *XEth) ApplyTestTxs(statedb *state.StateDB, address common.Address, t
...
@@ -218,7 +218,7 @@ func (self *XEth) ApplyTestTxs(statedb *state.StateDB, address common.Address, t
for
i
:=
0
;
i
<
len
(
txs
);
i
++
{
for
i
:=
0
;
i
<
len
(
txs
);
i
++
{
for
_
,
tx
:=
range
txs
{
for
_
,
tx
:=
range
txs
{
if
tx
.
Nonce
()
==
txc
{
if
tx
.
Nonce
()
==
txc
{
_
,
_
,
err
:=
core
.
ApplyMessage
(
core
.
NewEnv
(
statedb
,
self
.
backend
.
ChainManager
(),
tx
,
block
),
tx
,
coinbase
)
_
,
_
,
err
:=
core
.
ApplyMessage
(
core
.
NewEnv
(
statedb
,
self
.
backend
.
ChainManager
(),
tx
,
header
),
tx
,
coinbase
)
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
err
)
panic
(
err
)
}
}
...
@@ -845,8 +845,8 @@ func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr st
...
@@ -845,8 +845,8 @@ func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr st
msg
.
gasPrice
=
self
.
DefaultGasPrice
()
msg
.
gasPrice
=
self
.
DefaultGasPrice
()
}
}
block
:=
self
.
CurrentBlock
()
header
:=
self
.
CurrentBlock
()
.
Header
()
vmenv
:=
core
.
NewEnv
(
statedb
,
self
.
backend
.
ChainManager
(),
msg
,
block
)
vmenv
:=
core
.
NewEnv
(
statedb
,
self
.
backend
.
ChainManager
(),
msg
,
header
)
res
,
gas
,
err
:=
core
.
ApplyMessage
(
vmenv
,
msg
,
from
)
res
,
gas
,
err
:=
core
.
ApplyMessage
(
vmenv
,
msg
,
from
)
return
common
.
ToHex
(
res
),
gas
.
String
(),
err
return
common
.
ToHex
(
res
),
gas
.
String
(),
err
...
...
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