packages.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  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. "fmt"
  10. "math/big"
  11. "strings"
  12. "sync"
  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/filter"
  19. "github.com/ethereum/go-ethereum/state"
  20. "github.com/ethereum/go-ethereum/xeth"
  21. )
  22. const (
  23. defaultGasPrice = "10000000000000"
  24. defaultGas = "10000"
  25. )
  26. type EthereumApi struct {
  27. xeth *xeth.XEth
  28. filterManager *filter.FilterManager
  29. logMut sync.RWMutex
  30. logs map[int]state.Logs
  31. messagesMut sync.RWMutex
  32. messages map[int][]xeth.WhisperMessage
  33. // Register keeps a list of accounts and transaction data
  34. regmut sync.Mutex
  35. register map[string][]*NewTxArgs
  36. db ethutil.Database
  37. }
  38. func NewEthereumApi(eth *xeth.XEth) *EthereumApi {
  39. db, _ := ethdb.NewLDBDatabase("dapps")
  40. api := &EthereumApi{
  41. xeth: eth,
  42. filterManager: filter.NewFilterManager(eth.Backend().EventMux()),
  43. logs: make(map[int]state.Logs),
  44. messages: make(map[int][]xeth.WhisperMessage),
  45. db: db,
  46. }
  47. go api.filterManager.Start()
  48. return api
  49. }
  50. func (self *EthereumApi) Register(args string, reply *interface{}) error {
  51. self.regmut.Lock()
  52. defer self.regmut.Unlock()
  53. if _, ok := self.register[args]; ok {
  54. self.register[args] = nil // register with empty
  55. }
  56. return nil
  57. }
  58. func (self *EthereumApi) Unregister(args string, reply *interface{}) error {
  59. self.regmut.Lock()
  60. defer self.regmut.Unlock()
  61. delete(self.register, args)
  62. return nil
  63. }
  64. func (self *EthereumApi) WatchTx(args string, reply *interface{}) error {
  65. self.regmut.Lock()
  66. defer self.regmut.Unlock()
  67. txs := self.register[args]
  68. self.register[args] = nil
  69. *reply = txs
  70. return nil
  71. }
  72. func (self *EthereumApi) NewFilter(args *FilterOptions, reply *interface{}) error {
  73. var id int
  74. filter := core.NewFilter(self.xeth.Backend())
  75. filter.SetOptions(toFilterOptions(args))
  76. filter.LogsCallback = func(logs state.Logs) {
  77. self.logMut.Lock()
  78. defer self.logMut.Unlock()
  79. self.logs[id] = append(self.logs[id], logs...)
  80. }
  81. id = self.filterManager.InstallFilter(filter)
  82. *reply = id
  83. return nil
  84. }
  85. func (self *EthereumApi) NewFilterString(args string, reply *interface{}) error {
  86. var id int
  87. filter := core.NewFilter(self.xeth.Backend())
  88. callback := func(block *types.Block) {
  89. self.logMut.Lock()
  90. defer self.logMut.Unlock()
  91. self.logs[id] = append(self.logs[id], &state.StateLog{})
  92. }
  93. if args == "pending" {
  94. filter.PendingCallback = callback
  95. } else if args == "chain" {
  96. filter.BlockCallback = callback
  97. }
  98. id = self.filterManager.InstallFilter(filter)
  99. *reply = id
  100. return nil
  101. }
  102. func (self *EthereumApi) FilterChanged(id int, reply *interface{}) error {
  103. self.logMut.Lock()
  104. defer self.logMut.Unlock()
  105. *reply = toLogs(self.logs[id])
  106. self.logs[id] = nil // empty the logs
  107. return nil
  108. }
  109. func (self *EthereumApi) Logs(id int, reply *interface{}) error {
  110. self.logMut.Lock()
  111. defer self.logMut.Unlock()
  112. filter := self.filterManager.GetFilter(id)
  113. if filter != nil {
  114. *reply = toLogs(filter.Find())
  115. }
  116. return nil
  117. }
  118. func (p *EthereumApi) GetBlock(args *GetBlockArgs, reply *interface{}) error {
  119. err := args.requirements()
  120. if err != nil {
  121. return err
  122. }
  123. if args.BlockNumber > 0 {
  124. *reply = p.xeth.BlockByNumber(args.BlockNumber)
  125. } else {
  126. *reply = p.xeth.BlockByHash(args.Hash)
  127. }
  128. return nil
  129. }
  130. func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) error {
  131. if len(args.Gas) == 0 {
  132. args.Gas = defaultGas
  133. }
  134. if len(args.GasPrice) == 0 {
  135. args.GasPrice = defaultGasPrice
  136. }
  137. // TODO if no_private_key then
  138. if _, exists := p.register[args.From]; exists {
  139. p.register[args.From] = append(p.register[args.From], args)
  140. } else {
  141. result, _ := p.xeth.Transact( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data)
  142. *reply = result
  143. }
  144. return nil
  145. }
  146. func (p *EthereumApi) Call(args *NewTxArgs, reply *interface{}) error {
  147. result, err := p.xeth.Call( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data)
  148. if err != nil {
  149. return err
  150. }
  151. *reply = result
  152. return nil
  153. }
  154. func (p *EthereumApi) PushTx(args *PushTxArgs, reply *interface{}) error {
  155. err := args.requirementsPushTx()
  156. if err != nil {
  157. return err
  158. }
  159. result, _ := p.xeth.PushTx(args.Tx)
  160. *reply = result
  161. return nil
  162. }
  163. func (p *EthereumApi) GetStateAt(args *GetStateArgs, reply *interface{}) error {
  164. err := args.requirements()
  165. if err != nil {
  166. return err
  167. }
  168. state := p.xeth.State().SafeGet(args.Address)
  169. value := state.StorageString(args.Key)
  170. var hx string
  171. if strings.Index(args.Key, "0x") == 0 {
  172. hx = string([]byte(args.Key)[2:])
  173. } else {
  174. // Convert the incoming string (which is a bigint) into hex
  175. i, _ := new(big.Int).SetString(args.Key, 10)
  176. hx = ethutil.Bytes2Hex(i.Bytes())
  177. }
  178. rpclogger.Debugf("GetStateAt(%s, %s)\n", args.Address, hx)
  179. *reply = map[string]string{args.Key: value.Str()}
  180. return nil
  181. }
  182. func (p *EthereumApi) GetStorageAt(args *GetStorageArgs, reply *interface{}) error {
  183. err := args.requirements()
  184. if err != nil {
  185. return err
  186. }
  187. *reply = p.xeth.State().SafeGet(args.Address).Storage()
  188. return nil
  189. }
  190. func (p *EthereumApi) GetPeerCount(reply *interface{}) error {
  191. *reply = p.xeth.PeerCount()
  192. return nil
  193. }
  194. func (p *EthereumApi) GetIsListening(reply *interface{}) error {
  195. *reply = p.xeth.IsListening()
  196. return nil
  197. }
  198. func (p *EthereumApi) GetCoinbase(reply *interface{}) error {
  199. *reply = p.xeth.Coinbase()
  200. return nil
  201. }
  202. func (p *EthereumApi) Accounts(reply *interface{}) error {
  203. *reply = p.xeth.Accounts()
  204. return nil
  205. }
  206. func (p *EthereumApi) GetIsMining(reply *interface{}) error {
  207. *reply = p.xeth.IsMining()
  208. return nil
  209. }
  210. func (p *EthereumApi) BlockNumber(reply *interface{}) error {
  211. *reply = p.xeth.Backend().ChainManager().CurrentBlock().Number()
  212. return nil
  213. }
  214. func (p *EthereumApi) GetTxCountAt(args *GetTxCountArgs, reply *interface{}) error {
  215. err := args.requirements()
  216. if err != nil {
  217. return err
  218. }
  219. *reply = p.xeth.TxCountAt(args.Address)
  220. return nil
  221. }
  222. func (p *EthereumApi) GetBalanceAt(args *GetBalanceArgs, reply *interface{}) error {
  223. err := args.requirements()
  224. if err != nil {
  225. return err
  226. }
  227. state := p.xeth.State().SafeGet(args.Address)
  228. *reply = toHex(state.Balance().Bytes())
  229. return nil
  230. }
  231. func (p *EthereumApi) GetCodeAt(args *GetCodeAtArgs, reply *interface{}) error {
  232. err := args.requirements()
  233. if err != nil {
  234. return err
  235. }
  236. *reply = p.xeth.CodeAt(args.Address)
  237. return nil
  238. }
  239. func (p *EthereumApi) Sha3(args *Sha3Args, reply *interface{}) error {
  240. *reply = toHex(crypto.Sha3(fromHex(args.Data)))
  241. return nil
  242. }
  243. func (p *EthereumApi) DbPut(args *DbArgs, reply *interface{}) error {
  244. err := args.requirements()
  245. if err != nil {
  246. return err
  247. }
  248. p.db.Put([]byte(args.Database+args.Key), []byte(args.Value))
  249. *reply = true
  250. return nil
  251. }
  252. func (p *EthereumApi) DbGet(args *DbArgs, reply *interface{}) error {
  253. err := args.requirements()
  254. if err != nil {
  255. return err
  256. }
  257. res, _ := p.db.Get([]byte(args.Database + args.Key))
  258. *reply = string(res)
  259. return nil
  260. }
  261. func (p *EthereumApi) NewWhisperIdentity(reply *interface{}) error {
  262. *reply = p.xeth.Whisper().NewIdentity()
  263. return nil
  264. }
  265. func (p *EthereumApi) NewWhisperFilter(args *xeth.Options, reply *interface{}) error {
  266. var id int
  267. args.Fn = func(msg xeth.WhisperMessage) {
  268. p.messagesMut.Lock()
  269. defer p.messagesMut.Unlock()
  270. p.messages[id] = append(p.messages[id], msg)
  271. }
  272. id = p.xeth.Whisper().Watch(args)
  273. *reply = id
  274. return nil
  275. }
  276. func (self *EthereumApi) MessagesChanged(id int, reply *interface{}) error {
  277. self.messagesMut.Lock()
  278. defer self.messagesMut.Unlock()
  279. *reply = self.messages[id]
  280. self.messages[id] = nil // empty the messages
  281. return nil
  282. }
  283. func (p *EthereumApi) WhisperPost(args *WhisperMessageArgs, reply *interface{}) error {
  284. err := p.xeth.Whisper().Post(args.Payload, args.To, args.From, args.Topic, args.Priority, args.Ttl)
  285. if err != nil {
  286. return err
  287. }
  288. *reply = true
  289. return nil
  290. }
  291. func (p *EthereumApi) HasWhisperIdentity(args string, reply *interface{}) error {
  292. *reply = p.xeth.Whisper().HasIdentity(args)
  293. return nil
  294. }
  295. func (p *EthereumApi) WhisperMessages(id int, reply *interface{}) error {
  296. *reply = p.xeth.Whisper().Messages(id)
  297. return nil
  298. }
  299. func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error {
  300. // Spec at https://github.com/ethereum/wiki/wiki/Generic-ON-RPC
  301. rpclogger.DebugDetailf("%T %s", req.Params, req.Params)
  302. switch req.Method {
  303. case "eth_coinbase":
  304. return p.GetCoinbase(reply)
  305. case "eth_listening":
  306. return p.GetIsListening(reply)
  307. case "eth_mining":
  308. return p.GetIsMining(reply)
  309. case "eth_peerCount":
  310. return p.GetPeerCount(reply)
  311. case "eth_number":
  312. return p.BlockNumber(reply)
  313. case "eth_accounts":
  314. return p.Accounts(reply)
  315. case "eth_countAt":
  316. args, err := req.ToGetTxCountArgs()
  317. if err != nil {
  318. return err
  319. }
  320. return p.GetTxCountAt(args, reply)
  321. case "eth_codeAt":
  322. args, err := req.ToGetCodeAtArgs()
  323. if err != nil {
  324. return err
  325. }
  326. return p.GetCodeAt(args, reply)
  327. case "eth_balanceAt":
  328. args, err := req.ToGetBalanceArgs()
  329. if err != nil {
  330. return err
  331. }
  332. return p.GetBalanceAt(args, reply)
  333. case "eth_stateAt":
  334. args, err := req.ToGetStateArgs()
  335. if err != nil {
  336. return err
  337. }
  338. return p.GetStateAt(args, reply)
  339. case "eth_storageAt":
  340. args, err := req.ToStorageAtArgs()
  341. if err != nil {
  342. return err
  343. }
  344. return p.GetStorageAt(args, reply)
  345. case "eth_blockByNumber", "eth_blockByHash":
  346. args, err := req.ToGetBlockArgs()
  347. if err != nil {
  348. return err
  349. }
  350. return p.GetBlock(args, reply)
  351. case "eth_transact":
  352. args, err := req.ToNewTxArgs()
  353. if err != nil {
  354. return err
  355. }
  356. return p.Transact(args, reply)
  357. case "eth_call":
  358. args, err := req.ToNewTxArgs()
  359. if err != nil {
  360. return err
  361. }
  362. return p.Call(args, reply)
  363. case "eth_newFilter":
  364. args, err := req.ToFilterArgs()
  365. if err != nil {
  366. return err
  367. }
  368. return p.NewFilter(args, reply)
  369. case "eth_newFilterString":
  370. args, err := req.ToFilterStringArgs()
  371. if err != nil {
  372. return err
  373. }
  374. return p.NewFilterString(args, reply)
  375. case "eth_changed":
  376. args, err := req.ToIdArgs()
  377. if err != nil {
  378. return err
  379. }
  380. return p.FilterChanged(args, reply)
  381. case "eth_filterLogs":
  382. args, err := req.ToIdArgs()
  383. if err != nil {
  384. return err
  385. }
  386. return p.Logs(args, reply)
  387. case "eth_gasPrice":
  388. *reply = defaultGasPrice
  389. return nil
  390. case "eth_register":
  391. args, err := req.ToRegisterArgs()
  392. if err != nil {
  393. return err
  394. }
  395. return p.Register(args, reply)
  396. case "eth_unregister":
  397. args, err := req.ToRegisterArgs()
  398. if err != nil {
  399. return err
  400. }
  401. return p.Unregister(args, reply)
  402. case "eth_watchTx":
  403. args, err := req.ToWatchTxArgs()
  404. if err != nil {
  405. return err
  406. }
  407. return p.WatchTx(args, reply)
  408. case "web3_sha3":
  409. args, err := req.ToSha3Args()
  410. if err != nil {
  411. return err
  412. }
  413. return p.Sha3(args, reply)
  414. case "db_put":
  415. args, err := req.ToDbPutArgs()
  416. if err != nil {
  417. return err
  418. }
  419. return p.DbPut(args, reply)
  420. case "db_get":
  421. args, err := req.ToDbGetArgs()
  422. if err != nil {
  423. return err
  424. }
  425. return p.DbGet(args, reply)
  426. case "shh_newIdentity":
  427. return p.NewWhisperIdentity(reply)
  428. case "shh_newFilter":
  429. args, err := req.ToWhisperFilterArgs()
  430. if err != nil {
  431. return err
  432. }
  433. return p.NewWhisperFilter(args, reply)
  434. case "shh_changed":
  435. args, err := req.ToIdArgs()
  436. if err != nil {
  437. return err
  438. }
  439. return p.MessagesChanged(args, reply)
  440. case "shh_post":
  441. args, err := req.ToWhisperPostArgs()
  442. if err != nil {
  443. return err
  444. }
  445. return p.WhisperPost(args, reply)
  446. case "shh_haveIdentity":
  447. args, err := req.ToWhisperHasIdentityArgs()
  448. if err != nil {
  449. return err
  450. }
  451. return p.HasWhisperIdentity(args, reply)
  452. case "shh_getMessages":
  453. args, err := req.ToIdArgs()
  454. if err != nil {
  455. return err
  456. }
  457. return p.WhisperMessages(args, reply)
  458. default:
  459. return NewErrorResponse(fmt.Sprintf("%v %s", ErrorNotImplemented, req.Method))
  460. }
  461. rpclogger.DebugDetailf("Reply: %T %s", reply, reply)
  462. return nil
  463. }