api.go 16 KB

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