main.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /*
  2. This file is part of go-ethereum
  3. go-ethereum is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Lesser General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. go-ethereum is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /**
  15. * @authors
  16. * Gustav Simonsson <gustav.simonsson@gmail.com>
  17. * @date 2015
  18. *
  19. */
  20. package main
  21. import (
  22. "bytes"
  23. "crypto/ecdsa"
  24. "encoding/hex"
  25. "encoding/json"
  26. "fmt"
  27. "io/ioutil"
  28. "log"
  29. "math/big"
  30. "path"
  31. "runtime"
  32. "strconv"
  33. "strings"
  34. "time"
  35. "github.com/ethereum/go-ethereum/cmd/utils"
  36. types "github.com/ethereum/go-ethereum/core/types"
  37. "github.com/ethereum/go-ethereum/eth"
  38. "github.com/ethereum/go-ethereum/ethutil"
  39. "github.com/ethereum/go-ethereum/logger"
  40. "github.com/ethereum/go-ethereum/p2p"
  41. "github.com/ethereum/go-ethereum/p2p/nat"
  42. "github.com/ethereum/go-ethereum/rlp"
  43. )
  44. const (
  45. ClientIdentifier = "Ethereum(G)"
  46. Version = "0.8.6"
  47. )
  48. type Account struct {
  49. Balance string
  50. Code string
  51. Nonce string
  52. Storage map[string]string
  53. }
  54. type BlockHeader struct {
  55. Bloom string
  56. Coinbase string
  57. Difficulty string
  58. ExtraData string
  59. GasLimit string
  60. GasUsed string
  61. MixHash string
  62. Nonce string
  63. Number string
  64. ParentHash string
  65. ReceiptTrie string
  66. SeedHash string
  67. StateRoot string
  68. Timestamp string
  69. TransactionsTrie string
  70. UncleHash string
  71. }
  72. type Tx struct {
  73. Data string
  74. GasLimit string
  75. GasPrice string
  76. Nonce string
  77. R string
  78. S string
  79. To string
  80. V string
  81. Value string
  82. }
  83. type Block struct {
  84. BlockHeader BlockHeader
  85. Rlp string
  86. Transactions []Tx
  87. UncleHeaders []string
  88. }
  89. type Test struct {
  90. Blocks []Block
  91. GenesisBlockHeader BlockHeader
  92. Pre map[string]Account
  93. }
  94. var (
  95. Identifier string
  96. KeyRing string
  97. DiffTool bool
  98. DiffType string
  99. KeyStore string
  100. StartRpc bool
  101. StartWebSockets bool
  102. RpcListenAddress string
  103. RpcPort int
  104. WsPort int
  105. OutboundPort string
  106. ShowGenesis bool
  107. AddPeer string
  108. MaxPeer int
  109. GenAddr bool
  110. BootNodes string
  111. NodeKey *ecdsa.PrivateKey
  112. NAT nat.Interface
  113. SecretFile string
  114. ExportDir string
  115. NonInteractive bool
  116. Datadir string
  117. LogFile string
  118. ConfigFile string
  119. DebugFile string
  120. LogLevel int
  121. LogFormat string
  122. Dump bool
  123. DumpHash string
  124. DumpNumber int
  125. VmType int
  126. ImportChain string
  127. SHH bool
  128. Dial bool
  129. PrintVersion bool
  130. MinerThreads int
  131. )
  132. // flags specific to cli client
  133. var (
  134. StartMining bool
  135. StartJsConsole bool
  136. InputFile string
  137. )
  138. func main() {
  139. init_vars()
  140. Init()
  141. if len(TestFile) < 1 {
  142. log.Fatal("Please specify test file")
  143. }
  144. blocks, err := loadBlocksFromTestFile(TestFile)
  145. if err != nil {
  146. panic(err)
  147. }
  148. runtime.GOMAXPROCS(runtime.NumCPU())
  149. defer func() {
  150. logger.Flush()
  151. }()
  152. //utils.HandleInterrupt()
  153. utils.InitConfig(VmType, ConfigFile, Datadir, "ethblocktest")
  154. ethereum, err := eth.New(&eth.Config{
  155. Name: p2p.MakeName(ClientIdentifier, Version),
  156. KeyStore: KeyStore,
  157. DataDir: Datadir,
  158. LogFile: LogFile,
  159. LogLevel: LogLevel,
  160. LogFormat: LogFormat,
  161. MaxPeers: MaxPeer,
  162. Port: OutboundPort,
  163. NAT: NAT,
  164. KeyRing: KeyRing,
  165. Shh: true,
  166. Dial: Dial,
  167. BootNodes: BootNodes,
  168. NodeKey: NodeKey,
  169. MinerThreads: MinerThreads,
  170. })
  171. utils.StartEthereumForTest(ethereum)
  172. utils.StartRpc(ethereum, RpcListenAddress, RpcPort)
  173. ethereum.ChainManager().ResetWithGenesisBlock(blocks[0])
  174. // bph := ethereum.ChainManager().GetBlock(blocks[1].Header().ParentHash)
  175. // fmt.Println("bph: ", bph)
  176. //fmt.Println("b0: ", hex.EncodeToString(ethutil.Encode(blocks[0].RlpData())))
  177. //fmt.Println("b0: ", hex.EncodeToString(blocks[0].Hash()))
  178. //fmt.Println("b1: ", hex.EncodeToString(ethutil.Encode(blocks[1].RlpData())))
  179. //fmt.Println("b1: ", hex.EncodeToString(blocks[1].Hash()))
  180. go ethereum.ChainManager().InsertChain(types.Blocks{blocks[1]})
  181. fmt.Println("OK! ")
  182. ethereum.WaitForShutdown()
  183. }
  184. func loadBlocksFromTestFile(filePath string) (blocks types.Blocks, err error) {
  185. fileContent, err := ioutil.ReadFile(filePath)
  186. if err != nil {
  187. return
  188. }
  189. bt := *new(map[string]Test)
  190. err = json.Unmarshal(fileContent, &bt)
  191. if err != nil {
  192. return
  193. }
  194. // TODO: support multiple blocks; loop over all blocks
  195. gbh := new(types.Header)
  196. // Let's use slighlty different namings for the same things, because that's awesome.
  197. gbh.ParentHash, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.ParentHash)
  198. gbh.UncleHash, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.UncleHash)
  199. gbh.Coinbase, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.Coinbase)
  200. gbh.Root, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.StateRoot)
  201. gbh.TxHash, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.TransactionsTrie)
  202. gbh.ReceiptHash, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.ReceiptTrie)
  203. gbh.Bloom, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.Bloom)
  204. gbh.MixDigest, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.MixHash)
  205. gbh.SeedHash, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.SeedHash)
  206. d, _ := new(big.Int).SetString(bt["SimpleTx"].GenesisBlockHeader.Difficulty, 10)
  207. gbh.Difficulty = d
  208. n, _ := new(big.Int).SetString(bt["SimpleTx"].GenesisBlockHeader.Number, 10)
  209. gbh.Number = n
  210. gl, _ := new(big.Int).SetString(bt["SimpleTx"].GenesisBlockHeader.GasLimit, 10)
  211. gbh.GasLimit = gl
  212. gu, _ := new(big.Int).SetString(bt["SimpleTx"].GenesisBlockHeader.GasUsed, 10)
  213. gbh.GasUsed = gu
  214. ts, _ := new(big.Int).SetString(bt["SimpleTx"].GenesisBlockHeader.Timestamp, 0)
  215. gbh.Time = ts.Uint64()
  216. extra, err := hex_decode(bt["SimpleTx"].GenesisBlockHeader.ExtraData)
  217. gbh.Extra = string(extra) // TODO: change ExtraData to byte array
  218. nonce, _ := hex_decode(bt["SimpleTx"].GenesisBlockHeader.Nonce)
  219. gbh.Nonce = nonce
  220. if err != nil {
  221. return
  222. }
  223. gb := types.NewBlockWithHeader(gbh)
  224. //gb.uncles = *new([]*types.Header)
  225. //gb.transactions = *new(types.Transactions)
  226. gb.Td = new(big.Int)
  227. gb.Reward = new(big.Int)
  228. testBlock := new(types.Block)
  229. rlpBytes, err := hex_decode(bt["SimpleTx"].Blocks[0].Rlp)
  230. err = rlp.Decode(bytes.NewReader(rlpBytes), &testBlock)
  231. if err != nil {
  232. return
  233. }
  234. blocks = types.Blocks{
  235. gb,
  236. testBlock,
  237. }
  238. return
  239. }
  240. func init_vars() {
  241. VmType = 0
  242. Identifier = ""
  243. KeyRing = ""
  244. KeyStore = "db"
  245. RpcListenAddress = "127.0.0.1"
  246. RpcPort = 8545
  247. WsPort = 40404
  248. StartRpc = true
  249. StartWebSockets = false
  250. NonInteractive = false
  251. GenAddr = false
  252. SecretFile = ""
  253. ExportDir = ""
  254. LogFile = ""
  255. timeStr := strconv.FormatInt(time.Now().UnixNano(), 10)
  256. Datadir = path.Join(ethutil.DefaultDataDir(), timeStr)
  257. ConfigFile = path.Join(ethutil.DefaultDataDir(), timeStr, "conf.ini")
  258. DebugFile = ""
  259. LogLevel = 5
  260. LogFormat = "std"
  261. DiffTool = false
  262. DiffType = "all"
  263. ShowGenesis = false
  264. ImportChain = ""
  265. Dump = false
  266. DumpHash = ""
  267. DumpNumber = -1
  268. StartMining = false
  269. StartJsConsole = false
  270. PrintVersion = false
  271. MinerThreads = runtime.NumCPU()
  272. Dial = false
  273. OutboundPort = "30303"
  274. BootNodes = ""
  275. MaxPeer = 1
  276. }
  277. func hex_decode(s string) (res []byte, err error) {
  278. return hex.DecodeString(strings.TrimPrefix(s, "0x"))
  279. }