api.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. /*
  2. For each request type, define the following:
  3. 1. RpcRequest "To" method [message.go], which does basic validation and conversion to "Args" type via json.Decoder()
  4. 2. json.Decoder() calls "UnmarshalON" defined on each "Args" struct
  5. 3. EthereumApi method, taking the "Args" type and replying with an interface to be marshalled to ON
  6. */
  7. package rpc
  8. import (
  9. "math/big"
  10. "strings"
  11. "sync"
  12. "time"
  13. "github.com/ethereum/go-ethereum/core"
  14. "github.com/ethereum/go-ethereum/core/types"
  15. "github.com/ethereum/go-ethereum/crypto"
  16. "github.com/ethereum/go-ethereum/ethdb"
  17. "github.com/ethereum/go-ethereum/ethutil"
  18. "github.com/ethereum/go-ethereum/event"
  19. "github.com/ethereum/go-ethereum/event/filter"
  20. "github.com/ethereum/go-ethereum/state"
  21. "github.com/ethereum/go-ethereum/xeth"
  22. )
  23. var (
  24. defaultGasPrice = big.NewInt(10000000000000)
  25. defaultGas = big.NewInt(10000)
  26. filterTickerTime = 15 * time.Second
  27. )
  28. type EthereumApi struct {
  29. eth *xeth.XEth
  30. xethMu sync.RWMutex
  31. mux *event.TypeMux
  32. quit chan struct{}
  33. filterManager *filter.FilterManager
  34. logMut sync.RWMutex
  35. logs map[int]*logFilter
  36. messagesMut sync.RWMutex
  37. messages map[int]*whisperFilter
  38. // Register keeps a list of accounts and transaction data
  39. regmut sync.Mutex
  40. register map[string][]*NewTxArgs
  41. db ethutil.Database
  42. defaultBlockAge int64
  43. }
  44. func NewEthereumApi(eth *xeth.XEth) *EthereumApi {
  45. db, _ := ethdb.NewLDBDatabase("dapps")
  46. api := &EthereumApi{
  47. eth: eth,
  48. mux: eth.Backend().EventMux(),
  49. quit: make(chan struct{}),
  50. filterManager: filter.NewFilterManager(eth.Backend().EventMux()),
  51. logs: make(map[int]*logFilter),
  52. messages: make(map[int]*whisperFilter),
  53. db: db,
  54. defaultBlockAge: -1,
  55. }
  56. go api.filterManager.Start()
  57. go api.start()
  58. return api
  59. }
  60. func (self *EthereumApi) setStateByBlockNumber(num int64) {
  61. chain := self.xeth().Backend().ChainManager()
  62. var block *types.Block
  63. if self.defaultBlockAge < 0 {
  64. num = chain.CurrentBlock().Number().Int64() + num + 1
  65. }
  66. block = chain.GetBlockByNumber(uint64(num))
  67. if block != nil {
  68. self.useState(state.New(block.Root(), self.xeth().Backend().StateDb()))
  69. } else {
  70. self.useState(chain.State())
  71. }
  72. }
  73. func (self *EthereumApi) start() {
  74. timer := time.NewTicker(filterTickerTime)
  75. events := self.mux.Subscribe(core.ChainEvent{})
  76. done:
  77. for {
  78. select {
  79. case ev := <-events.Chan():
  80. switch ev.(type) {
  81. case core.ChainEvent:
  82. if self.defaultBlockAge < 0 {
  83. self.setStateByBlockNumber(self.defaultBlockAge)
  84. }
  85. }
  86. case <-timer.C:
  87. self.logMut.Lock()
  88. self.messagesMut.Lock()
  89. for id, filter := range self.logs {
  90. if time.Since(filter.timeout) > 20*time.Second {
  91. self.filterManager.UninstallFilter(id)
  92. delete(self.logs, id)
  93. }
  94. }
  95. for id, filter := range self.messages {
  96. if time.Since(filter.timeout) > 20*time.Second {
  97. self.xeth().Whisper().Unwatch(id)
  98. delete(self.messages, id)
  99. }
  100. }
  101. self.logMut.Unlock()
  102. self.messagesMut.Unlock()
  103. case <-self.quit:
  104. break done
  105. }
  106. }
  107. }
  108. func (self *EthereumApi) stop() {
  109. close(self.quit)
  110. }
  111. func (self *EthereumApi) Register(args string, reply *interface{}) error {
  112. self.regmut.Lock()
  113. defer self.regmut.Unlock()
  114. if _, ok := self.register[args]; ok {
  115. self.register[args] = nil // register with empty
  116. }
  117. return nil
  118. }
  119. func (self *EthereumApi) Unregister(args string, reply *interface{}) error {
  120. self.regmut.Lock()
  121. defer self.regmut.Unlock()
  122. delete(self.register, args)
  123. return nil
  124. }
  125. func (self *EthereumApi) WatchTx(args string, reply *interface{}) error {
  126. self.regmut.Lock()
  127. defer self.regmut.Unlock()
  128. txs := self.register[args]
  129. self.register[args] = nil
  130. *reply = txs
  131. return nil
  132. }
  133. func (self *EthereumApi) NewFilter(args *FilterOptions, reply *interface{}) error {
  134. var id int
  135. filter := core.NewFilter(self.xeth().Backend())
  136. filter.SetOptions(toFilterOptions(args))
  137. filter.LogsCallback = func(logs state.Logs) {
  138. self.logMut.Lock()
  139. defer self.logMut.Unlock()
  140. self.logs[id].add(logs...)
  141. }
  142. id = self.filterManager.InstallFilter(filter)
  143. self.logs[id] = &logFilter{timeout: time.Now()}
  144. *reply = id
  145. return nil
  146. }
  147. func (self *EthereumApi) UninstallFilter(id int, reply *interface{}) error {
  148. delete(self.logs, id)
  149. self.filterManager.UninstallFilter(id)
  150. *reply = true
  151. return nil
  152. }
  153. func (self *EthereumApi) NewFilterString(args string, reply *interface{}) error {
  154. var id int
  155. filter := core.NewFilter(self.xeth().Backend())
  156. callback := func(block *types.Block) {
  157. self.logMut.Lock()
  158. defer self.logMut.Unlock()
  159. self.logs[id].add(&state.StateLog{})
  160. }
  161. if args == "pending" {
  162. filter.PendingCallback = callback
  163. } else if args == "chain" {
  164. filter.BlockCallback = callback
  165. }
  166. id = self.filterManager.InstallFilter(filter)
  167. self.logs[id] = &logFilter{timeout: time.Now()}
  168. *reply = id
  169. return nil
  170. }
  171. func (self *EthereumApi) FilterChanged(id int, reply *interface{}) error {
  172. self.logMut.Lock()
  173. defer self.logMut.Unlock()
  174. if self.logs[id] != nil {
  175. *reply = toLogs(self.logs[id].get())
  176. }
  177. return nil
  178. }
  179. func (self *EthereumApi) Logs(id int, reply *interface{}) error {
  180. self.logMut.Lock()
  181. defer self.logMut.Unlock()
  182. filter := self.filterManager.GetFilter(id)
  183. if filter != nil {
  184. *reply = toLogs(filter.Find())
  185. }
  186. return nil
  187. }
  188. func (self *EthereumApi) AllLogs(args *FilterOptions, reply *interface{}) error {
  189. filter := core.NewFilter(self.xeth().Backend())
  190. filter.SetOptions(toFilterOptions(args))
  191. *reply = toLogs(filter.Find())
  192. return nil
  193. }
  194. func (p *EthereumApi) GetBlock(args *GetBlockArgs, reply *interface{}) error {
  195. // This seems a bit precarious Maybe worth splitting to discrete functions
  196. if len(args.Hash) > 0 {
  197. *reply = p.xeth().BlockByHash(args.Hash)
  198. } else {
  199. *reply = p.xeth().BlockByNumber(args.BlockNumber)
  200. }
  201. return nil
  202. }
  203. func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) error {
  204. if len(args.Gas) == 0 {
  205. args.Gas = defaultGas.String()
  206. }
  207. if len(args.GasPrice) == 0 {
  208. args.GasPrice = defaultGasPrice.String()
  209. }
  210. // TODO if no_private_key then
  211. //if _, exists := p.register[args.From]; exists {
  212. // p.register[args.From] = append(p.register[args.From], args)
  213. //} else {
  214. /*
  215. account := accounts.Get(fromHex(args.From))
  216. if account != nil {
  217. if account.Unlocked() {
  218. if !unlockAccount(account) {
  219. return
  220. }
  221. }
  222. result, _ := account.Transact(fromHex(args.To), fromHex(args.Value), fromHex(args.Gas), fromHex(args.GasPrice), fromHex(args.Data))
  223. if len(result) > 0 {
  224. *reply = toHex(result)
  225. }
  226. } else if _, exists := p.register[args.From]; exists {
  227. p.register[ags.From] = append(p.register[args.From], args)
  228. }
  229. */
  230. result, _ := p.xeth().Transact( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data)
  231. *reply = result
  232. //}
  233. return nil
  234. }
  235. func (p *EthereumApi) Call(args *NewTxArgs, reply *interface{}) error {
  236. result, err := p.xeth().Call( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data)
  237. if err != nil {
  238. return err
  239. }
  240. *reply = result
  241. return nil
  242. }
  243. func (p *EthereumApi) PushTx(args *PushTxArgs, reply *interface{}) error {
  244. err := args.requirementsPushTx()
  245. if err != nil {
  246. return err
  247. }
  248. result, _ := p.xeth().PushTx(args.Tx)
  249. *reply = result
  250. return nil
  251. }
  252. func (p *EthereumApi) GetStateAt(args *GetStateArgs, reply *interface{}) error {
  253. err := args.requirements()
  254. if err != nil {
  255. return err
  256. }
  257. state := p.xeth().State().SafeGet(args.Address)
  258. value := state.StorageString(args.Key)
  259. var hx string
  260. if strings.Index(args.Key, "0x") == 0 {
  261. hx = string([]byte(args.Key)[2:])
  262. } else {
  263. // Convert the incoming string (which is a bigint) into hex
  264. i, _ := new(big.Int).SetString(args.Key, 10)
  265. hx = ethutil.Bytes2Hex(i.Bytes())
  266. }
  267. rpclogger.Debugf("GetStateAt(%s, %s)\n", args.Address, hx)
  268. *reply = map[string]string{args.Key: value.Str()}
  269. return nil
  270. }
  271. func (p *EthereumApi) GetStorageAt(args *GetStorageArgs, reply *interface{}) error {
  272. err := args.requirements()
  273. if err != nil {
  274. return err
  275. }
  276. *reply = p.xeth().State().SafeGet(args.Address).Storage()
  277. return nil
  278. }
  279. func (p *EthereumApi) GetPeerCount(reply *interface{}) error {
  280. *reply = p.xeth().PeerCount()
  281. return nil
  282. }
  283. func (p *EthereumApi) GetIsListening(reply *interface{}) error {
  284. *reply = p.xeth().IsListening()
  285. return nil
  286. }
  287. func (p *EthereumApi) GetCoinbase(reply *interface{}) error {
  288. *reply = p.xeth().Coinbase()
  289. return nil
  290. }
  291. func (p *EthereumApi) Accounts(reply *interface{}) error {
  292. *reply = p.xeth().Accounts()
  293. return nil
  294. }
  295. func (p *EthereumApi) GetIsMining(reply *interface{}) error {
  296. *reply = p.xeth().IsMining()
  297. return nil
  298. }
  299. func (p *EthereumApi) SetMining(shouldmine bool, reply *interface{}) error {
  300. *reply = p.xeth().SetMining(shouldmine)
  301. return nil
  302. }
  303. func (p *EthereumApi) GetDefaultBlockAge(reply *interface{}) error {
  304. *reply = p.defaultBlockAge
  305. return nil
  306. }
  307. func (p *EthereumApi) SetDefaultBlockAge(defaultBlockAge int64, reply *interface{}) error {
  308. p.defaultBlockAge = defaultBlockAge
  309. p.setStateByBlockNumber(p.defaultBlockAge)
  310. *reply = true
  311. return nil
  312. }
  313. func (p *EthereumApi) BlockNumber(reply *interface{}) error {
  314. *reply = p.xeth().Backend().ChainManager().CurrentBlock().Number()
  315. return nil
  316. }
  317. func (p *EthereumApi) GetTxCountAt(args *GetTxCountArgs, reply *interface{}) error {
  318. err := args.requirements()
  319. if err != nil {
  320. return err
  321. }
  322. *reply = p.xeth().TxCountAt(args.Address)
  323. return nil
  324. }
  325. func (p *EthereumApi) GetBalanceAt(args *GetBalanceArgs, reply *interface{}) error {
  326. err := args.requirements()
  327. if err != nil {
  328. return err
  329. }
  330. state := p.xeth().State().SafeGet(args.Address)
  331. *reply = toHex(state.Balance().Bytes())
  332. return nil
  333. }
  334. func (p *EthereumApi) GetCodeAt(args *GetCodeAtArgs, reply *interface{}) error {
  335. err := args.requirements()
  336. if err != nil {
  337. return err
  338. }
  339. *reply = p.xeth().CodeAt(args.Address)
  340. return nil
  341. }
  342. func (p *EthereumApi) GetCompilers(reply *interface{}) error {
  343. c := []string{"serpent"}
  344. *reply = c
  345. return nil
  346. }
  347. func (p *EthereumApi) CompileSerpent(script string, reply *interface{}) error {
  348. res, err := ethutil.Compile(script, false)
  349. if err != nil {
  350. return err
  351. }
  352. *reply = res
  353. return nil
  354. }
  355. func (p *EthereumApi) Sha3(args *Sha3Args, reply *interface{}) error {
  356. *reply = toHex(crypto.Sha3(fromHex(args.Data)))
  357. return nil
  358. }
  359. func (p *EthereumApi) DbPut(args *DbArgs, reply *interface{}) error {
  360. err := args.requirements()
  361. if err != nil {
  362. return err
  363. }
  364. p.db.Put([]byte(args.Database+args.Key), []byte(args.Value))
  365. *reply = true
  366. return nil
  367. }
  368. func (p *EthereumApi) DbGet(args *DbArgs, reply *interface{}) error {
  369. err := args.requirements()
  370. if err != nil {
  371. return err
  372. }
  373. res, _ := p.db.Get([]byte(args.Database + args.Key))
  374. *reply = string(res)
  375. return nil
  376. }
  377. func (p *EthereumApi) NewWhisperIdentity(reply *interface{}) error {
  378. *reply = p.xeth().Whisper().NewIdentity()
  379. return nil
  380. }
  381. func (p *EthereumApi) NewWhisperFilter(args *xeth.Options, reply *interface{}) error {
  382. var id int
  383. args.Fn = func(msg xeth.WhisperMessage) {
  384. p.messagesMut.Lock()
  385. defer p.messagesMut.Unlock()
  386. p.messages[id].add(msg) // = append(p.messages[id], msg)
  387. }
  388. id = p.xeth().Whisper().Watch(args)
  389. p.messages[id] = &whisperFilter{timeout: time.Now()}
  390. *reply = id
  391. return nil
  392. }
  393. func (self *EthereumApi) MessagesChanged(id int, reply *interface{}) error {
  394. self.messagesMut.Lock()
  395. defer self.messagesMut.Unlock()
  396. if self.messages[id] != nil {
  397. *reply = self.messages[id].get()
  398. }
  399. return nil
  400. }
  401. func (p *EthereumApi) WhisperPost(args *WhisperMessageArgs, reply *interface{}) error {
  402. err := p.xeth().Whisper().Post(args.Payload, args.To, args.From, args.Topic, args.Priority, args.Ttl)
  403. if err != nil {
  404. return err
  405. }
  406. *reply = true
  407. return nil
  408. }
  409. func (p *EthereumApi) HasWhisperIdentity(args string, reply *interface{}) error {
  410. *reply = p.xeth().Whisper().HasIdentity(args)
  411. return nil
  412. }
  413. func (p *EthereumApi) WhisperMessages(id int, reply *interface{}) error {
  414. *reply = p.xeth().Whisper().Messages(id)
  415. return nil
  416. }
  417. func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error {
  418. // Spec at https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC
  419. rpclogger.DebugDetailf("%T %s", req.Params, req.Params)
  420. switch req.Method {
  421. case "eth_coinbase":
  422. return p.GetCoinbase(reply)
  423. case "eth_listening":
  424. return p.GetIsListening(reply)
  425. case "eth_mining":
  426. return p.GetIsMining(reply)
  427. case "eth_setMining":
  428. args, err := req.ToBoolArgs()
  429. if err != nil {
  430. return err
  431. }
  432. return p.SetMining(args, reply)
  433. case "eth_defaultBlock":
  434. return p.GetDefaultBlockAge(reply)
  435. case "eth_setDefaultBlock":
  436. args, err := req.ToIntArgs()
  437. if err != nil {
  438. return err
  439. }
  440. return p.SetDefaultBlockAge(int64(args), reply)
  441. case "eth_peerCount":
  442. return p.GetPeerCount(reply)
  443. case "eth_number":
  444. return p.BlockNumber(reply)
  445. case "eth_accounts":
  446. return p.Accounts(reply)
  447. case "eth_countAt":
  448. args, err := req.ToGetTxCountArgs()
  449. if err != nil {
  450. return err
  451. }
  452. return p.GetTxCountAt(args, reply)
  453. case "eth_codeAt":
  454. args, err := req.ToGetCodeAtArgs()
  455. if err != nil {
  456. return err
  457. }
  458. return p.GetCodeAt(args, reply)
  459. case "eth_balanceAt":
  460. args, err := req.ToGetBalanceArgs()
  461. if err != nil {
  462. return err
  463. }
  464. return p.GetBalanceAt(args, reply)
  465. case "eth_stateAt":
  466. args, err := req.ToGetStateArgs()
  467. if err != nil {
  468. return err
  469. }
  470. return p.GetStateAt(args, reply)
  471. case "eth_storageAt":
  472. args, err := req.ToStorageAtArgs()
  473. if err != nil {
  474. return err
  475. }
  476. return p.GetStorageAt(args, reply)
  477. case "eth_blockByNumber", "eth_blockByHash":
  478. args, err := req.ToGetBlockArgs()
  479. if err != nil {
  480. return err
  481. }
  482. return p.GetBlock(args, reply)
  483. case "eth_transact":
  484. args, err := req.ToNewTxArgs()
  485. if err != nil {
  486. return err
  487. }
  488. return p.Transact(args, reply)
  489. case "eth_call":
  490. args, err := req.ToNewTxArgs()
  491. if err != nil {
  492. return err
  493. }
  494. return p.Call(args, reply)
  495. case "eth_newFilter":
  496. args, err := req.ToFilterArgs()
  497. if err != nil {
  498. return err
  499. }
  500. return p.NewFilter(args, reply)
  501. case "eth_newFilterString":
  502. args, err := req.ToFilterStringArgs()
  503. if err != nil {
  504. return err
  505. }
  506. return p.NewFilterString(args, reply)
  507. case "eth_uninstallFilter":
  508. args, err := req.ToUninstallFilterArgs()
  509. if err != nil {
  510. return err
  511. }
  512. return p.UninstallFilter(args, reply)
  513. case "eth_changed":
  514. args, err := req.ToIdArgs()
  515. if err != nil {
  516. return err
  517. }
  518. return p.FilterChanged(args, reply)
  519. case "eth_filterLogs":
  520. args, err := req.ToIdArgs()
  521. if err != nil {
  522. return err
  523. }
  524. return p.Logs(args, reply)
  525. case "eth_logs":
  526. args, err := req.ToFilterArgs()
  527. if err != nil {
  528. return err
  529. }
  530. return p.AllLogs(args, reply)
  531. case "eth_gasPrice":
  532. *reply = toHex(defaultGasPrice.Bytes())
  533. return nil
  534. case "eth_register":
  535. args, err := req.ToRegisterArgs()
  536. if err != nil {
  537. return err
  538. }
  539. return p.Register(args, reply)
  540. case "eth_unregister":
  541. args, err := req.ToRegisterArgs()
  542. if err != nil {
  543. return err
  544. }
  545. return p.Unregister(args, reply)
  546. case "eth_watchTx":
  547. args, err := req.ToWatchTxArgs()
  548. if err != nil {
  549. return err
  550. }
  551. return p.WatchTx(args, reply)
  552. case "eth_compilers":
  553. return p.GetCompilers(reply)
  554. case "eth_serpent":
  555. args, err := req.ToCompileArgs()
  556. if err != nil {
  557. return err
  558. }
  559. return p.CompileSerpent(args, reply)
  560. case "web3_sha3":
  561. args, err := req.ToSha3Args()
  562. if err != nil {
  563. return err
  564. }
  565. return p.Sha3(args, reply)
  566. case "db_put":
  567. args, err := req.ToDbPutArgs()
  568. if err != nil {
  569. return err
  570. }
  571. return p.DbPut(args, reply)
  572. case "db_get":
  573. args, err := req.ToDbGetArgs()
  574. if err != nil {
  575. return err
  576. }
  577. return p.DbGet(args, reply)
  578. case "shh_newIdentity":
  579. return p.NewWhisperIdentity(reply)
  580. case "shh_newFilter":
  581. args, err := req.ToWhisperFilterArgs()
  582. if err != nil {
  583. return err
  584. }
  585. return p.NewWhisperFilter(args, reply)
  586. case "shh_changed":
  587. args, err := req.ToIdArgs()
  588. if err != nil {
  589. return err
  590. }
  591. return p.MessagesChanged(args, reply)
  592. case "shh_post":
  593. args, err := req.ToWhisperPostArgs()
  594. if err != nil {
  595. return err
  596. }
  597. return p.WhisperPost(args, reply)
  598. case "shh_haveIdentity":
  599. args, err := req.ToWhisperHasIdentityArgs()
  600. if err != nil {
  601. return err
  602. }
  603. return p.HasWhisperIdentity(args, reply)
  604. case "shh_getMessages":
  605. args, err := req.ToIdArgs()
  606. if err != nil {
  607. return err
  608. }
  609. return p.WhisperMessages(args, reply)
  610. default:
  611. return NewErrorWithMessage(errNotImplemented, req.Method)
  612. }
  613. rpclogger.DebugDetailf("Reply: %T %s", reply, reply)
  614. return nil
  615. }
  616. func (self *EthereumApi) xeth() *xeth.XEth {
  617. self.xethMu.RLock()
  618. defer self.xethMu.RUnlock()
  619. return self.eth
  620. }
  621. func (self *EthereumApi) useState(statedb *state.StateDB) {
  622. self.xethMu.Lock()
  623. defer self.xethMu.Unlock()
  624. self.eth = self.eth.UseState(statedb)
  625. }