Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
whqwjb
go-ethereum
提交
ae837c47
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,发现更多精彩内容 >>
提交
ae837c47
编写于
3月 20, 2014
作者:
M
Maran
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
More mining rework
上级
2be2fc79
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
171 addition
and
39 deletion
+171
-39
ethchain/block.go
ethchain/block.go
+3
-0
ethchain/block_chain.go
ethchain/block_chain.go
+1
-2
ethchain/dagger.go
ethchain/dagger.go
+5
-11
ethchain/state_manager.go
ethchain/state_manager.go
+8
-20
ethchain/transaction_pool.go
ethchain/transaction_pool.go
+4
-5
ethminer/miner.go
ethminer/miner.go
+149
-0
peer.go
peer.go
+1
-1
未找到文件。
ethchain/block.go
浏览文件 @
ae837c47
...
...
@@ -304,6 +304,9 @@ func NewUncleBlockFromValue(header *ethutil.Value) *Block {
func
(
block
*
Block
)
String
()
string
{
return
fmt
.
Sprintf
(
"Block(%x):
\n
PrevHash:%x
\n
UncleSha:%x
\n
Coinbase:%x
\n
Root:%x
\n
TxSha:%x
\n
Diff:%v
\n
Time:%d
\n
Nonce:%x
\n
Txs:%d
\n
"
,
block
.
Hash
(),
block
.
PrevHash
,
block
.
UncleSha
,
block
.
Coinbase
,
block
.
state
.
trie
.
Root
,
block
.
TxSha
,
block
.
Difficulty
,
block
.
Time
,
block
.
Nonce
,
len
(
block
.
transactions
))
}
func
(
block
*
Block
)
GetRoot
()
interface
{}
{
return
block
.
state
.
trie
.
Root
}
//////////// UNEXPORTED /////////////////
func
(
block
*
Block
)
header
()
[]
interface
{}
{
...
...
ethchain/block_chain.go
浏览文件 @
ae837c47
...
...
@@ -44,7 +44,6 @@ func (bc *BlockChain) NewBlock(coinbase []byte, txs []*Transaction) *Block {
hash
=
bc
.
LastBlockHash
lastBlockTime
=
bc
.
CurrentBlock
.
Time
}
block
:=
CreateBlock
(
root
,
hash
,
...
...
@@ -181,8 +180,8 @@ func (bc *BlockChain) SetTotalDifficulty(td *big.Int) {
// Add a block to the chain and record addition information
func
(
bc
*
BlockChain
)
Add
(
block
*
Block
)
{
bc
.
writeBlockInfo
(
block
)
// Prepare the genesis block
bc
.
CurrentBlock
=
block
bc
.
LastBlockHash
=
block
.
Hash
()
...
...
ethchain/dagger.go
浏览文件 @
ae837c47
...
...
@@ -11,7 +11,7 @@ import (
)
type
PoW
interface
{
Search
(
block
*
Block
,
miner
Chan
chan
ethutil
.
React
)
[]
byte
Search
(
block
*
Block
,
react
Chan
chan
ethutil
.
React
)
[]
byte
Verify
(
hash
[]
byte
,
diff
*
big
.
Int
,
nonce
[]
byte
)
bool
}
...
...
@@ -19,7 +19,7 @@ type EasyPow struct {
hash
*
big
.
Int
}
func
(
pow
*
EasyPow
)
Search
(
block
*
Block
,
miner
Chan
chan
ethutil
.
React
)
[]
byte
{
func
(
pow
*
EasyPow
)
Search
(
block
*
Block
,
react
Chan
chan
ethutil
.
React
)
[]
byte
{
r
:=
rand
.
New
(
rand
.
NewSource
(
time
.
Now
()
.
UnixNano
()))
hash
:=
block
.
HashNoNonce
()
diff
:=
block
.
Difficulty
...
...
@@ -28,15 +28,9 @@ func (pow *EasyPow) Search(block *Block, minerChan chan ethutil.React) []byte {
for
{
select
{
case
chanMessage
:=
<-
minerChan
:
if
_
,
ok
:=
chanMessage
.
Resource
.
(
*
Block
);
ok
{
log
.
Println
(
"BREAKING OUT: BLOCK"
)
return
nil
}
if
_
,
ok
:=
chanMessage
.
Resource
.
(
*
Transaction
);
ok
{
log
.
Println
(
"BREAKING OUT: TX"
)
return
nil
}
case
<-
reactChan
:
log
.
Println
(
"[pow] Received reactor event; breaking out."
)
return
nil
default
:
i
++
if
i
%
1234567
==
0
{
...
...
ethchain/state_manager.go
浏览文件 @
ae837c47
...
...
@@ -50,9 +50,6 @@ type StateManager struct {
// Comparative state it used for comparing and validating end
// results
compState
*
State
// Mining state, solely used for mining
miningState
*
State
}
func
NewStateManager
(
ethereum
EthManager
)
*
StateManager
{
...
...
@@ -65,7 +62,6 @@ func NewStateManager(ethereum EthManager) *StateManager {
bc
:
ethereum
.
BlockChain
(),
}
sm
.
procState
=
ethereum
.
BlockChain
()
.
CurrentBlock
.
State
()
return
sm
}
...
...
@@ -73,10 +69,6 @@ func (sm *StateManager) ProcState() *State {
return
sm
.
procState
}
func
(
sm
*
StateManager
)
MiningState
()
*
State
{
return
sm
.
miningState
}
// Watches any given address and puts it in the address state store
func
(
sm
*
StateManager
)
WatchAddr
(
addr
[]
byte
)
*
AccountState
{
//XXX account := sm.bc.CurrentBlock.state.GetAccount(addr)
...
...
@@ -105,8 +97,6 @@ func (sm *StateManager) MakeContract(tx *Transaction) {
sm
.
procState
.
states
[
string
(
tx
.
Hash
()[
12
:
])]
=
contract
.
state
}
}
func
(
sm
*
StateManager
)
ApplyTransaction
(
block
*
Block
,
tx
*
Transaction
)
{
}
func
(
sm
*
StateManager
)
ApplyTransactions
(
block
*
Block
,
txs
[]
*
Transaction
)
{
// Process each transaction/contract
...
...
@@ -136,17 +126,13 @@ func (sm *StateManager) Prepare(processer *State, comparative *State) {
sm
.
procState
=
processer
}
func
(
sm
*
StateManager
)
PrepareMiningState
()
{
sm
.
miningState
=
sm
.
BlockChain
()
.
CurrentBlock
.
State
()
}
// Default prepare function
func
(
sm
*
StateManager
)
PrepareDefault
(
block
*
Block
)
{
sm
.
Prepare
(
sm
.
BlockChain
()
.
CurrentBlock
.
State
(),
block
.
State
())
}
// Block processing and validating with a given (temporarily) state
func
(
sm
*
StateManager
)
ProcessBlock
(
block
*
Block
)
error
{
func
(
sm
*
StateManager
)
ProcessBlock
(
block
*
Block
,
dontReact
bool
)
error
{
// Processing a blocks may never happen simultaneously
sm
.
mutex
.
Lock
()
defer
sm
.
mutex
.
Unlock
()
...
...
@@ -155,7 +141,6 @@ func (sm *StateManager) ProcessBlock(block *Block) error {
// nodes this won't happen because Commit would have been called
// before that.
defer
sm
.
bc
.
CurrentBlock
.
Undo
()
hash
:=
block
.
Hash
()
if
sm
.
bc
.
HasBlock
(
hash
)
{
...
...
@@ -207,7 +192,9 @@ func (sm *StateManager) ProcessBlock(block *Block) error {
}
ethutil
.
Config
.
Log
.
Infof
(
"[STATE] Added block #%d (%x)
\n
"
,
block
.
BlockInfo
()
.
Number
,
block
.
Hash
())
sm
.
Ethereum
.
Reactor
()
.
Post
(
"newBlock"
,
block
)
if
dontReact
==
false
{
sm
.
Ethereum
.
Reactor
()
.
Post
(
"newBlock"
,
block
)
}
}
else
{
fmt
.
Println
(
"total diff failed"
)
}
...
...
@@ -285,15 +272,16 @@ func CalculateUncleReward(block *Block) *big.Int {
}
func
(
sm
*
StateManager
)
AccumelateRewards
(
block
*
Block
)
error
{
// Get the coinbase rlp data
//XXX addr := processor.state.GetAccount(block.Coinbase)
addr
:=
sm
.
procState
.
GetAccount
(
block
.
Coinbase
)
// Reward amount of ether to the coinbase address
addr
.
AddFee
(
CalculateBlockReward
(
block
,
len
(
block
.
Uncles
)))
//XXX processor.state.UpdateAccount(block.Coinbase, addr)
sm
.
procState
.
UpdateAccount
(
block
.
Coinbase
,
addr
)
var
acc
[]
byte
copy
(
acc
,
block
.
Coinbase
)
sm
.
procState
.
UpdateAccount
(
acc
,
addr
)
for
_
,
uncle
:=
range
block
.
Uncles
{
uncleAddr
:=
sm
.
procState
.
GetAccount
(
uncle
.
Coinbase
)
uncleAddr
.
AddFee
(
CalculateUncleReward
(
uncle
))
...
...
ethchain/transaction_pool.go
浏览文件 @
ae837c47
...
...
@@ -91,7 +91,6 @@ func (pool *TxPool) addTransaction(tx *Transaction) {
// Process transaction validates the Tx and processes funds from the
// sender to the recipient.
func
(
pool
*
TxPool
)
ProcessTransaction
(
tx
*
Transaction
,
block
*
Block
)
(
err
error
)
{
log
.
Println
(
"Processing TX"
)
defer
func
()
{
if
r
:=
recover
();
r
!=
nil
{
log
.
Println
(
r
)
...
...
@@ -105,11 +104,11 @@ func (pool *TxPool) ProcessTransaction(tx *Transaction, block *Block) (err error
// funds won't invalidate this transaction but simple ignores it.
totAmount
:=
new
(
big
.
Int
)
.
Add
(
tx
.
Value
,
new
(
big
.
Int
)
.
Mul
(
TxFee
,
TxFeeRat
))
if
sender
.
Amount
.
Cmp
(
totAmount
)
<
0
{
return
errors
.
New
(
"Insufficient amount in sender's account"
)
return
errors
.
New
(
"
[TXPL]
Insufficient amount in sender's account"
)
}
if
sender
.
Nonce
!=
tx
.
Nonce
{
return
fmt
.
Errorf
(
"
Invalid nonce %d(%d)"
,
tx
.
Nonce
,
sender
.
Nonce
)
return
fmt
.
Errorf
(
"
[TXPL] Invalid account nonce, state nonce is %d transactoin nonce is %d instead"
,
sender
.
Nonce
,
tx
.
Nonce
)
}
// Get the receiver
...
...
@@ -145,7 +144,7 @@ func (pool *TxPool) ValidateTransaction(tx *Transaction) error {
block
:=
pool
.
Ethereum
.
BlockChain
()
.
CurrentBlock
// Something has gone horribly wrong if this happens
if
block
==
nil
{
return
errors
.
New
(
"No last block on the block chain"
)
return
errors
.
New
(
"
[TXPL]
No last block on the block chain"
)
}
// Get the sender
...
...
@@ -156,7 +155,7 @@ func (pool *TxPool) ValidateTransaction(tx *Transaction) error {
// Make sure there's enough in the sender's account. Having insufficient
// funds won't invalidate this transaction but simple ignores it.
if
sender
.
Amount
.
Cmp
(
totAmount
)
<
0
{
return
fmt
.
Errorf
(
"Insufficient amount in sender's (%x) account"
,
tx
.
Sender
())
return
fmt
.
Errorf
(
"
[TXPL]
Insufficient amount in sender's (%x) account"
,
tx
.
Sender
())
}
// Increment the nonce making each tx valid only once to prevent replay
...
...
ethminer/miner.go
0 → 100644
浏览文件 @
ae837c47
package
ethminer
import
(
"bytes"
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/eth-go/ethwire"
"log"
)
type
Miner
struct
{
pow
ethchain
.
PoW
ethereum
ethchain
.
EthManager
coinbase
[]
byte
reactChan
chan
ethutil
.
React
txs
[]
*
ethchain
.
Transaction
uncles
[]
*
ethchain
.
Block
block
*
ethchain
.
Block
powChan
chan
[]
byte
quitChan
chan
ethutil
.
React
}
func
NewDefaultMiner
(
coinbase
[]
byte
,
ethereum
ethchain
.
EthManager
)
Miner
{
reactChan
:=
make
(
chan
ethutil
.
React
,
1
)
// This is the channel that receives 'updates' when ever a new transaction or block comes in
powChan
:=
make
(
chan
[]
byte
,
1
)
// This is the channel that receives valid sha hases for a given block
quitChan
:=
make
(
chan
ethutil
.
React
,
1
)
// This is the channel that can exit the miner thread
ethereum
.
Reactor
()
.
Subscribe
(
"newBlock"
,
reactChan
)
ethereum
.
Reactor
()
.
Subscribe
(
"newTx"
,
reactChan
)
// We need the quit chan to be a Reactor event.
// The POW search method is actually blocking and if we don't
// listen to the reactor events inside of the pow itself
// The miner overseer will never get the reactor events themselves
// Only after the miner will find the sha
ethereum
.
Reactor
()
.
Subscribe
(
"newBlock"
,
quitChan
)
ethereum
.
Reactor
()
.
Subscribe
(
"newTx"
,
quitChan
)
miner
:=
Miner
{
pow
:
&
ethchain
.
EasyPow
{},
ethereum
:
ethereum
,
coinbase
:
coinbase
,
reactChan
:
reactChan
,
powChan
:
powChan
,
quitChan
:
quitChan
,
}
// Insert initial TXs in our little miner 'pool'
miner
.
txs
=
ethereum
.
TxPool
()
.
Flush
()
miner
.
block
=
ethereum
.
BlockChain
()
.
NewBlock
(
miner
.
coinbase
,
miner
.
txs
)
return
miner
}
func
(
miner
*
Miner
)
Start
()
{
// Prepare inital block
miner
.
ethereum
.
StateManager
()
.
Prepare
(
miner
.
block
.
State
(),
miner
.
block
.
State
())
go
func
()
{
miner
.
listener
()
}()
}
func
(
miner
*
Miner
)
listener
()
{
for
{
select
{
case
chanMessage
:=
<-
miner
.
reactChan
:
if
block
,
ok
:=
chanMessage
.
Resource
.
(
*
ethchain
.
Block
);
ok
{
log
.
Println
(
"[miner] Got new block via Reactor"
)
if
bytes
.
Compare
(
miner
.
ethereum
.
BlockChain
()
.
CurrentBlock
.
Hash
(),
block
.
Hash
())
==
0
{
// TODO: Perhaps continue mining to get some uncle rewards
log
.
Println
(
"[miner] New top block found resetting state"
)
// Filter out which Transactions we have that were not in this block
var
newtxs
[]
*
ethchain
.
Transaction
for
_
,
tx
:=
range
miner
.
txs
{
found
:=
false
for
_
,
othertx
:=
range
block
.
Transactions
()
{
if
bytes
.
Compare
(
tx
.
Hash
(),
othertx
.
Hash
())
==
0
{
found
=
true
}
}
if
found
==
false
{
newtxs
=
append
(
newtxs
,
tx
)
}
}
miner
.
txs
=
newtxs
// Setup a fresh state to mine on
miner
.
block
=
miner
.
ethereum
.
BlockChain
()
.
NewBlock
(
miner
.
coinbase
,
miner
.
txs
)
}
else
{
if
bytes
.
Compare
(
block
.
PrevHash
,
miner
.
ethereum
.
BlockChain
()
.
CurrentBlock
.
PrevHash
)
==
0
{
log
.
Println
(
"[miner] Adding uncle block"
)
miner
.
uncles
=
append
(
miner
.
uncles
,
block
)
miner
.
ethereum
.
StateManager
()
.
Prepare
(
miner
.
block
.
State
(),
miner
.
block
.
State
())
}
}
}
if
tx
,
ok
:=
chanMessage
.
Resource
.
(
*
ethchain
.
Transaction
);
ok
{
log
.
Println
(
"[miner] Got new transaction from Reactor"
,
tx
)
found
:=
false
for
_
,
ctx
:=
range
miner
.
txs
{
if
found
=
bytes
.
Compare
(
ctx
.
Hash
(),
tx
.
Hash
())
==
0
;
found
{
break
}
}
if
found
==
false
{
log
.
Println
(
"[miner] We did not know about this transaction, adding"
)
miner
.
txs
=
append
(
miner
.
txs
,
tx
)
miner
.
block
.
SetTransactions
(
miner
.
txs
)
}
else
{
log
.
Println
(
"[miner] We already had this transaction, ignoring"
)
}
}
default
:
log
.
Println
(
"[miner] Mining on block. Includes"
,
len
(
miner
.
txs
),
"transactions"
)
// Apply uncles
if
len
(
miner
.
uncles
)
>
0
{
miner
.
block
.
SetUncles
(
miner
.
uncles
)
}
// Apply all transactions to the block
miner
.
ethereum
.
StateManager
()
.
ApplyTransactions
(
miner
.
block
,
miner
.
block
.
Transactions
())
miner
.
ethereum
.
StateManager
()
.
AccumelateRewards
(
miner
.
block
)
// Search the nonce
log
.
Println
(
"[miner] Initialision complete, starting mining"
)
miner
.
block
.
Nonce
=
miner
.
pow
.
Search
(
miner
.
block
,
miner
.
quitChan
)
if
miner
.
block
.
Nonce
!=
nil
{
miner
.
ethereum
.
StateManager
()
.
PrepareDefault
(
miner
.
block
)
err
:=
miner
.
ethereum
.
StateManager
()
.
ProcessBlock
(
miner
.
block
,
true
)
if
err
!=
nil
{
log
.
Println
(
"Error result from process block:"
,
err
)
log
.
Println
(
miner
.
block
)
}
else
{
if
!
miner
.
ethereum
.
StateManager
()
.
Pow
.
Verify
(
miner
.
block
.
HashNoNonce
(),
miner
.
block
.
Difficulty
,
miner
.
block
.
Nonce
)
{
log
.
Printf
(
"Second stage verification error: Block's nonce is invalid (= %v)
\n
"
,
ethutil
.
Hex
(
miner
.
block
.
Nonce
))
}
miner
.
ethereum
.
Broadcast
(
ethwire
.
MsgBlockTy
,
[]
interface
{}{
miner
.
block
.
Value
()
.
Val
})
log
.
Printf
(
"[miner] 🔨 Mined block %x
\n
"
,
miner
.
block
.
Hash
())
log
.
Println
(
miner
.
block
)
miner
.
txs
=
[]
*
ethchain
.
Transaction
{}
// Move this somewhere neat
miner
.
block
=
miner
.
ethereum
.
BlockChain
()
.
NewBlock
(
miner
.
coinbase
,
miner
.
txs
)
}
}
}
}
}
peer.go
浏览文件 @
ae837c47
...
...
@@ -295,7 +295,7 @@ func (p *Peer) HandleInbound() {
block
=
ethchain
.
NewBlockFromRlpValue
(
msg
.
Data
.
Get
(
i
))
p
.
ethereum
.
StateManager
()
.
PrepareDefault
(
block
)
err
=
p
.
ethereum
.
StateManager
()
.
ProcessBlock
(
block
)
err
=
p
.
ethereum
.
StateManager
()
.
ProcessBlock
(
block
,
true
)
if
err
!=
nil
{
if
ethutil
.
Config
.
Debug
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录