Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
whqwjb
go-ethereum
提交
d9966d61
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,发现更多精彩内容 >>
提交
d9966d61
编写于
3月 14, 2015
作者:
O
obscuren
浏览文件
操作
浏览文件
下载
差异文件
merge
上级
12cee137
67f8f83a
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
346 addition
and
20 deletion
+346
-20
cmd/ethereum/blocktest.go
cmd/ethereum/blocktest.go
+66
-0
cmd/ethereum/main.go
cmd/ethereum/main.go
+11
-8
cmd/mist/main.go
cmd/mist/main.go
+3
-1
cmd/utils/flags.go
cmd/utils/flags.go
+3
-3
core/types/block.go
core/types/block.go
+2
-2
eth/backend.go
eth/backend.go
+21
-6
tests/blocktest.go
tests/blocktest.go
+240
-0
未找到文件。
cmd/ethereum/blocktest.go
0 → 100644
浏览文件 @
d9966d61
package
main
import
(
"fmt"
"github.com/codegangsta/cli"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/tests"
)
var
blocktestCmd
=
cli
.
Command
{
Action
:
runblocktest
,
Name
:
"blocktest"
,
Usage
:
`loads a block test file`
,
Description
:
`
The first argument should be a block test file.
The second argument is the name of a block test from the file.
The block test will be loaded into an in-memory database.
If loading succeeds, the RPC server is started. Clients will
be able to interact with the chain defined by the test.
`
,
}
func
runblocktest
(
ctx
*
cli
.
Context
)
{
if
len
(
ctx
.
Args
())
!=
2
{
utils
.
Fatalf
(
"This command requires two arguments."
)
}
file
,
testname
:=
ctx
.
Args
()[
0
],
ctx
.
Args
()[
1
]
bt
,
err
:=
tests
.
LoadBlockTests
(
file
)
if
err
!=
nil
{
utils
.
Fatalf
(
"%v"
,
err
)
}
test
,
ok
:=
bt
[
testname
]
if
!
ok
{
utils
.
Fatalf
(
"Test file does not contain test named %q"
,
testname
)
}
cfg
:=
utils
.
MakeEthConfig
(
ClientIdentifier
,
Version
,
ctx
)
cfg
.
NewDB
=
func
(
path
string
)
(
ethutil
.
Database
,
error
)
{
return
ethdb
.
NewMemDatabase
()
}
ethereum
,
err
:=
eth
.
New
(
cfg
)
if
err
!=
nil
{
utils
.
Fatalf
(
"%v"
,
err
)
}
// import the genesis block
ethereum
.
ResetWithGenesisBlock
(
test
.
Genesis
)
// import pre accounts
if
err
:=
test
.
InsertPreState
(
ethereum
.
StateDb
());
err
!=
nil
{
utils
.
Fatalf
(
"could not insert genesis accounts: %v"
,
err
)
}
// insert the test blocks, which will execute all transactions
chain
:=
ethereum
.
ChainManager
()
if
err
:=
chain
.
InsertChain
(
test
.
Blocks
);
err
!=
nil
{
utils
.
Fatalf
(
"Block Test load error: %v"
,
err
)
}
else
{
fmt
.
Println
(
"Block Test chain loaded, starting ethereum."
)
}
startEth
(
ctx
,
ethereum
)
}
cmd/ethereum/main.go
浏览文件 @
d9966d61
...
...
@@ -53,6 +53,7 @@ func init() {
app
.
Action
=
run
app
.
HideVersion
=
true
// we have a command to print the version
app
.
Commands
=
[]
cli
.
Command
{
blocktestCmd
,
{
Action
:
version
,
Name
:
"version"
,
...
...
@@ -156,24 +157,26 @@ func main() {
func
run
(
ctx
*
cli
.
Context
)
{
fmt
.
Printf
(
"Welcome to the FRONTIER
\n
"
)
utils
.
HandleInterrupt
()
eth
,
err
:=
utils
.
GetEthereum
(
ClientIdentifier
,
Version
,
ctx
)
cfg
:=
utils
.
MakeEthConfig
(
ClientIdentifier
,
Version
,
ctx
)
ethereum
,
err
:=
eth
.
New
(
cfg
)
if
err
!=
nil
{
utils
.
Fatalf
(
"%v"
,
err
)
}
startEth
(
ctx
,
eth
)
startEth
(
ctx
,
eth
ereum
)
// this blocks the thread
eth
.
WaitForShutdown
()
eth
ereum
.
WaitForShutdown
()
}
func
runjs
(
ctx
*
cli
.
Context
)
{
eth
,
err
:=
utils
.
GetEthereum
(
ClientIdentifier
,
Version
,
ctx
)
cfg
:=
utils
.
MakeEthConfig
(
ClientIdentifier
,
Version
,
ctx
)
ethereum
,
err
:=
eth
.
New
(
cfg
)
if
err
!=
nil
{
utils
.
Fatalf
(
"%v"
,
err
)
}
startEth
(
ctx
,
eth
)
repl
:=
newJSRE
(
eth
)
startEth
(
ctx
,
eth
ereum
)
repl
:=
newJSRE
(
eth
ereum
)
if
len
(
ctx
.
Args
())
==
0
{
repl
.
interactive
()
}
else
{
...
...
@@ -181,8 +184,8 @@ func runjs(ctx *cli.Context) {
repl
.
exec
(
file
)
}
}
eth
.
Stop
()
eth
.
WaitForShutdown
()
eth
ereum
.
Stop
()
eth
ereum
.
WaitForShutdown
()
}
func
startEth
(
ctx
*
cli
.
Context
,
eth
*
eth
.
Ethereum
)
{
...
...
cmd/mist/main.go
浏览文件 @
d9966d61
...
...
@@ -28,6 +28,7 @@ import (
"github.com/codegangsta/cli"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/ui/qt/webengine"
...
...
@@ -95,7 +96,8 @@ func run(ctx *cli.Context) {
tstart
:=
time
.
Now
()
// TODO: show qml popup instead of exiting if initialization fails.
ethereum
,
err
:=
utils
.
GetEthereum
(
ClientIdentifier
,
Version
,
ctx
)
cfg
:=
utils
.
MakeEthConfig
(
ClientIdentifier
,
Version
,
ctx
)
ethereum
,
err
:=
eth
.
New
(
cfg
)
if
err
!=
nil
{
utils
.
Fatalf
(
"%v"
,
err
)
}
...
...
cmd/utils/flags.go
浏览文件 @
d9966d61
...
...
@@ -191,8 +191,8 @@ func GetNodeKey(ctx *cli.Context) (key *ecdsa.PrivateKey) {
return
key
}
func
GetEthereum
(
clientID
,
version
string
,
ctx
*
cli
.
Context
)
(
*
eth
.
Ethereum
,
error
)
{
return
eth
.
New
(
&
eth
.
Config
{
func
MakeEthConfig
(
clientID
,
version
string
,
ctx
*
cli
.
Context
)
*
eth
.
Config
{
return
&
eth
.
Config
{
Name
:
ethutil
.
MakeName
(
clientID
,
version
),
DataDir
:
ctx
.
GlobalString
(
DataDirFlag
.
Name
),
LogFile
:
ctx
.
GlobalString
(
LogFileFlag
.
Name
),
...
...
@@ -208,7 +208,7 @@ func GetEthereum(clientID, version string, ctx *cli.Context) (*eth.Ethereum, err
Shh
:
true
,
Dial
:
true
,
BootNodes
:
ctx
.
GlobalString
(
BootnodesFlag
.
Name
),
}
)
}
}
func
GetChain
(
ctx
*
cli
.
Context
)
(
*
core
.
ChainManager
,
ethutil
.
Database
,
ethutil
.
Database
)
{
...
...
core/types/block.go
浏览文件 @
d9966d61
...
...
@@ -15,7 +15,7 @@ import (
type
Header
struct
{
// Hash to the previous block
ParentHash
ethutil
.
Bytes
ParentHash
[]
byte
// Uncles of this block
UncleHash
[]
byte
// The coin base address
...
...
@@ -41,7 +41,7 @@ type Header struct {
// Extra data
Extra
string
// Mix digest for quick checking to prevent DOS
MixDigest
ethutil
.
Bytes
MixDigest
[]
byte
// Nonce
Nonce
[]
byte
}
...
...
eth/backend.go
浏览文件 @
d9966d61
...
...
@@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/blockpool"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
...
...
@@ -61,6 +62,10 @@ type Config struct {
MinerThreads
int
AccountManager
*
accounts
.
Manager
// NewDB is used to create databases.
// If nil, the default is to create leveldb databases on disk.
NewDB
func
(
path
string
)
(
ethutil
.
Database
,
error
)
}
func
(
cfg
*
Config
)
parseBootNodes
()
[]
*
discover
.
Node
{
...
...
@@ -120,6 +125,7 @@ type Ethereum struct {
blockPool
*
blockpool
.
BlockPool
accountManager
*
accounts
.
Manager
whisper
*
whisper
.
Whisper
pow
*
ethash
.
Ethash
net
*
p2p
.
Server
eventMux
*
event
.
TypeMux
...
...
@@ -138,11 +144,15 @@ func New(config *Config) (*Ethereum, error) {
// Boostrap database
servlogger
:=
logger
.
New
(
config
.
DataDir
,
config
.
LogFile
,
config
.
LogLevel
,
config
.
LogFormat
)
blockDb
,
err
:=
ethdb
.
NewLDBDatabase
(
path
.
Join
(
config
.
DataDir
,
"blockchain"
))
newdb
:=
config
.
NewDB
if
newdb
==
nil
{
newdb
=
func
(
path
string
)
(
ethutil
.
Database
,
error
)
{
return
ethdb
.
NewLDBDatabase
(
path
)
}
}
blockDb
,
err
:=
newdb
(
path
.
Join
(
config
.
DataDir
,
"blockchain"
))
if
err
!=
nil
{
return
nil
,
err
}
stateDb
,
err
:=
ethdb
.
NewLDBDatabase
(
path
.
Join
(
config
.
DataDir
,
"state"
))
stateDb
,
err
:=
newdb
(
path
.
Join
(
config
.
DataDir
,
"state"
))
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -170,16 +180,16 @@ func New(config *Config) (*Ethereum, error) {
}
eth
.
chainManager
=
core
.
NewChainManager
(
blockDb
,
stateDb
,
eth
.
EventMux
())
pow
:
=
ethash
.
New
(
eth
.
chainManager
)
eth
.
pow
=
ethash
.
New
(
eth
.
chainManager
)
eth
.
txPool
=
core
.
NewTxPool
(
eth
.
EventMux
())
eth
.
blockProcessor
=
core
.
NewBlockProcessor
(
stateDb
,
extraDb
,
pow
,
eth
.
txPool
,
eth
.
chainManager
,
eth
.
EventMux
())
eth
.
blockProcessor
=
core
.
NewBlockProcessor
(
stateDb
,
extraDb
,
eth
.
pow
,
eth
.
txPool
,
eth
.
chainManager
,
eth
.
EventMux
())
eth
.
chainManager
.
SetProcessor
(
eth
.
blockProcessor
)
eth
.
whisper
=
whisper
.
New
()
eth
.
miner
=
miner
.
New
(
eth
,
pow
,
config
.
MinerThreads
)
eth
.
miner
=
miner
.
New
(
eth
,
eth
.
pow
,
config
.
MinerThreads
)
hasBlock
:=
eth
.
chainManager
.
HasBlock
insertChain
:=
eth
.
chainManager
.
InsertChain
eth
.
blockPool
=
blockpool
.
New
(
hasBlock
,
insertChain
,
pow
.
Verify
)
eth
.
blockPool
=
blockpool
.
New
(
hasBlock
,
insertChain
,
eth
.
pow
.
Verify
)
netprv
,
err
:=
config
.
nodeKey
()
if
err
!=
nil
{
...
...
@@ -209,6 +219,11 @@ func New(config *Config) (*Ethereum, error) {
return
eth
,
nil
}
func
(
s
*
Ethereum
)
ResetWithGenesisBlock
(
gb
*
types
.
Block
)
{
s
.
chainManager
.
ResetWithGenesisBlock
(
gb
)
s
.
pow
.
UpdateCache
(
true
)
}
func
(
s
*
Ethereum
)
StartMining
()
error
{
cb
,
err
:=
s
.
accountManager
.
Coinbase
()
if
err
!=
nil
{
...
...
tests/blocktest.go
0 → 100644
浏览文件 @
d9966d61
package
tests
import
(
"bytes"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"math/big"
"runtime"
"strconv"
"strings"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/state"
)
// Block Test JSON Format
type
btJSON
struct
{
Blocks
[]
btBlock
GenesisBlockHeader
btHeader
Pre
map
[
string
]
btAccount
}
type
btAccount
struct
{
Balance
string
Code
string
Nonce
string
Storage
map
[
string
]
string
}
type
btHeader
struct
{
Bloom
string
Coinbase
string
MixHash
string
Nonce
string
Number
string
ParentHash
string
ReceiptTrie
string
SeedHash
string
StateRoot
string
TransactionsTrie
string
UncleHash
string
ExtraData
string
Difficulty
string
GasLimit
string
GasUsed
string
Timestamp
string
}
type
btTransaction
struct
{
Data
string
GasLimit
string
GasPrice
string
Nonce
string
R
string
S
string
To
string
V
string
Value
string
}
type
btBlock
struct
{
BlockHeader
*
btHeader
Rlp
string
Transactions
[]
btTransaction
UncleHeaders
[]
string
}
type
BlockTest
struct
{
Genesis
*
types
.
Block
Blocks
[]
*
types
.
Block
preAccounts
map
[
string
]
btAccount
}
// LoadBlockTests loads a block test JSON file.
func
LoadBlockTests
(
file
string
)
(
map
[
string
]
*
BlockTest
,
error
)
{
bt
:=
make
(
map
[
string
]
*
btJSON
)
if
err
:=
loadJSON
(
file
,
&
bt
);
err
!=
nil
{
return
nil
,
err
}
out
:=
make
(
map
[
string
]
*
BlockTest
)
for
name
,
in
:=
range
bt
{
var
err
error
if
out
[
name
],
err
=
convertTest
(
in
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"bad test %q: %v"
,
err
)
}
}
return
out
,
nil
}
// InsertPreState populates the given database with the genesis
// accounts defined by the test.
func
(
t
*
BlockTest
)
InsertPreState
(
db
ethutil
.
Database
)
error
{
statedb
:=
state
.
New
(
nil
,
db
)
for
addrString
,
acct
:=
range
t
.
preAccounts
{
// XXX: is is worth it checking for errors here?
addr
,
_
:=
hex
.
DecodeString
(
addrString
)
code
,
_
:=
hex
.
DecodeString
(
strings
.
TrimPrefix
(
acct
.
Code
,
"0x"
))
balance
,
_
:=
new
(
big
.
Int
)
.
SetString
(
acct
.
Balance
,
0
)
nonce
,
_
:=
strconv
.
ParseUint
(
acct
.
Nonce
,
16
,
64
)
obj
:=
statedb
.
NewStateObject
(
addr
)
obj
.
SetCode
(
code
)
obj
.
SetBalance
(
balance
)
obj
.
SetNonce
(
nonce
)
// for k, v := range acct.Storage {
// obj.SetState(k, v)
// }
}
// sync objects to trie
statedb
.
Update
(
nil
)
// sync trie to disk
statedb
.
Sync
()
if
!
bytes
.
Equal
(
t
.
Genesis
.
Root
(),
statedb
.
Root
())
{
return
errors
.
New
(
"computed state root does not match genesis block"
)
}
return
nil
}
func
convertTest
(
in
*
btJSON
)
(
out
*
BlockTest
,
err
error
)
{
// the conversion handles errors by catching panics.
// you might consider this ugly, but the alternative (passing errors)
// would be much harder to read.
defer
func
()
{
if
recovered
:=
recover
();
recovered
!=
nil
{
buf
:=
make
([]
byte
,
64
<<
10
)
buf
=
buf
[
:
runtime
.
Stack
(
buf
,
false
)]
err
=
fmt
.
Errorf
(
"%v
\n
%s"
,
recovered
,
buf
)
}
}()
out
=
&
BlockTest
{
preAccounts
:
in
.
Pre
}
out
.
Genesis
=
mustConvertGenesis
(
in
.
GenesisBlockHeader
)
out
.
Blocks
=
mustConvertBlocks
(
in
.
Blocks
)
return
out
,
err
}
func
mustConvertGenesis
(
testGenesis
btHeader
)
*
types
.
Block
{
hdr
:=
mustConvertHeader
(
testGenesis
)
hdr
.
Number
=
big
.
NewInt
(
0
)
b
:=
types
.
NewBlockWithHeader
(
hdr
)
b
.
Td
=
new
(
big
.
Int
)
b
.
Reward
=
new
(
big
.
Int
)
return
b
}
func
mustConvertHeader
(
in
btHeader
)
*
types
.
Header
{
// hex decode these fields
return
&
types
.
Header
{
//SeedHash: mustConvertBytes(in.SeedHash),
MixDigest
:
mustConvertBytes
(
in
.
MixHash
),
Bloom
:
mustConvertBytes
(
in
.
Bloom
),
ReceiptHash
:
mustConvertBytes
(
in
.
ReceiptTrie
),
TxHash
:
mustConvertBytes
(
in
.
TransactionsTrie
),
Root
:
mustConvertBytes
(
in
.
StateRoot
),
Coinbase
:
mustConvertBytes
(
in
.
Coinbase
),
UncleHash
:
mustConvertBytes
(
in
.
UncleHash
),
ParentHash
:
mustConvertBytes
(
in
.
ParentHash
),
Nonce
:
mustConvertBytes
(
in
.
Nonce
),
Extra
:
string
(
mustConvertBytes
(
in
.
ExtraData
)),
GasUsed
:
mustConvertBigInt10
(
in
.
GasUsed
),
GasLimit
:
mustConvertBigInt10
(
in
.
GasLimit
),
Difficulty
:
mustConvertBigInt10
(
in
.
Difficulty
),
Time
:
mustConvertUint
(
in
.
Timestamp
),
}
}
func
mustConvertBlocks
(
testBlocks
[]
btBlock
)
[]
*
types
.
Block
{
var
out
[]
*
types
.
Block
for
i
,
inb
:=
range
testBlocks
{
var
b
types
.
Block
r
:=
bytes
.
NewReader
(
mustConvertBytes
(
inb
.
Rlp
))
if
err
:=
rlp
.
Decode
(
r
,
&
b
);
err
!=
nil
{
panic
(
fmt
.
Errorf
(
"invalid block %d: %q"
,
i
,
inb
.
Rlp
))
}
out
=
append
(
out
,
&
b
)
}
return
out
}
func
mustConvertBytes
(
in
string
)
[]
byte
{
out
,
err
:=
hex
.
DecodeString
(
strings
.
TrimPrefix
(
in
,
"0x"
))
if
err
!=
nil
{
panic
(
fmt
.
Errorf
(
"invalid hex: %q"
,
in
))
}
return
out
}
func
mustConvertBigInt10
(
in
string
)
*
big
.
Int
{
out
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
in
,
10
)
if
!
ok
{
panic
(
fmt
.
Errorf
(
"invalid integer: %q"
,
in
))
}
return
out
}
func
mustConvertUint
(
in
string
)
uint64
{
out
,
err
:=
strconv
.
ParseUint
(
in
,
0
,
64
)
if
err
!=
nil
{
panic
(
fmt
.
Errorf
(
"invalid integer: %q"
,
in
))
}
return
out
}
// loadJSON reads the given file and unmarshals its content.
func
loadJSON
(
file
string
,
val
interface
{})
error
{
content
,
err
:=
ioutil
.
ReadFile
(
file
)
if
err
!=
nil
{
return
err
}
if
err
:=
json
.
Unmarshal
(
content
,
val
);
err
!=
nil
{
if
syntaxerr
,
ok
:=
err
.
(
*
json
.
SyntaxError
);
ok
{
line
:=
findLine
(
content
,
syntaxerr
.
Offset
)
return
fmt
.
Errorf
(
"JSON syntax error at %v:%v: %v"
,
file
,
line
,
err
)
}
return
fmt
.
Errorf
(
"JSON unmarshal error in %v: %v"
,
file
,
err
)
}
return
nil
}
// findLine returns the line number for the given offset into data.
func
findLine
(
data
[]
byte
,
offset
int64
)
(
line
int
)
{
line
=
1
for
i
,
r
:=
range
string
(
data
)
{
if
int64
(
i
)
>=
offset
{
return
}
if
r
==
'\n'
{
line
++
}
}
return
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录