api.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. package rpc
  2. import (
  3. "encoding/json"
  4. // "fmt"
  5. "math/big"
  6. "sync"
  7. "github.com/ethereum/go-ethereum/common"
  8. "github.com/ethereum/go-ethereum/crypto"
  9. "github.com/ethereum/go-ethereum/xeth"
  10. )
  11. type EthereumApi struct {
  12. eth *xeth.XEth
  13. xethMu sync.RWMutex
  14. }
  15. func NewEthereumApi(xeth *xeth.XEth) *EthereumApi {
  16. api := &EthereumApi{
  17. eth: xeth,
  18. }
  19. return api
  20. }
  21. func (api *EthereumApi) xeth() *xeth.XEth {
  22. api.xethMu.RLock()
  23. defer api.xethMu.RUnlock()
  24. return api.eth
  25. }
  26. func (api *EthereumApi) xethAtStateNum(num int64) *xeth.XEth {
  27. return api.xeth().AtStateNum(num)
  28. }
  29. func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error {
  30. // Spec at https://github.com/ethereum/wiki/wiki/JSON-RPC
  31. rpclogger.Debugf("%s %s", req.Method, req.Params)
  32. switch req.Method {
  33. case "web3_sha3":
  34. args := new(Sha3Args)
  35. if err := json.Unmarshal(req.Params, &args); err != nil {
  36. return err
  37. }
  38. *reply = common.ToHex(crypto.Sha3(common.FromHex(args.Data)))
  39. case "web3_clientVersion":
  40. *reply = api.xeth().ClientVersion()
  41. case "net_version":
  42. *reply = api.xeth().NetworkVersion()
  43. case "net_listening":
  44. *reply = api.xeth().IsListening()
  45. case "net_peerCount":
  46. v := api.xeth().PeerCount()
  47. *reply = common.ToHex(big.NewInt(int64(v)).Bytes())
  48. case "eth_protocolVersion":
  49. *reply = api.xeth().EthVersion()
  50. case "eth_coinbase":
  51. // TODO handling of empty coinbase due to lack of accounts
  52. res := api.xeth().Coinbase()
  53. if res == "0x" || res == "0x0" {
  54. *reply = nil
  55. } else {
  56. *reply = res
  57. }
  58. case "eth_mining":
  59. *reply = api.xeth().IsMining()
  60. case "eth_gasPrice":
  61. v := xeth.DefaultGas()
  62. *reply = common.ToHex(v.Bytes())
  63. case "eth_accounts":
  64. *reply = api.xeth().Accounts()
  65. case "eth_blockNumber":
  66. v := api.xeth().CurrentBlock().Number()
  67. *reply = common.ToHex(v.Bytes())
  68. case "eth_getBalance":
  69. args := new(GetBalanceArgs)
  70. if err := json.Unmarshal(req.Params, &args); err != nil {
  71. return err
  72. }
  73. *reply = api.xethAtStateNum(args.BlockNumber).BalanceAt(args.Address)
  74. //v := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance()
  75. //*reply = common.ToHex(v.Bytes())
  76. case "eth_getStorage", "eth_storageAt":
  77. args := new(GetStorageArgs)
  78. if err := json.Unmarshal(req.Params, &args); err != nil {
  79. return err
  80. }
  81. *reply = api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage()
  82. case "eth_getStorageAt":
  83. args := new(GetStorageAtArgs)
  84. if err := json.Unmarshal(req.Params, &args); err != nil {
  85. return err
  86. }
  87. *reply = api.xethAtStateNum(args.BlockNumber).StorageAt(args.Address, args.Key)
  88. case "eth_getTransactionCount":
  89. args := new(GetTxCountArgs)
  90. if err := json.Unmarshal(req.Params, &args); err != nil {
  91. return err
  92. }
  93. count := api.xethAtStateNum(args.BlockNumber).TxCountAt(args.Address)
  94. *reply = common.ToHex(big.NewInt(int64(count)).Bytes())
  95. case "eth_getBlockTransactionCountByHash":
  96. args := new(HashArgs)
  97. if err := json.Unmarshal(req.Params, &args); err != nil {
  98. return err
  99. }
  100. block := NewBlockRes(api.xeth().EthBlockByHash(args.Hash), false)
  101. if block == nil {
  102. *reply = nil
  103. } else {
  104. *reply = common.ToHex(big.NewInt(int64(len(block.Transactions))).Bytes())
  105. }
  106. case "eth_getBlockTransactionCountByNumber":
  107. args := new(BlockNumArg)
  108. if err := json.Unmarshal(req.Params, &args); err != nil {
  109. return err
  110. }
  111. block := NewBlockRes(api.xeth().EthBlockByNumber(args.BlockNumber), false)
  112. *reply = common.ToHex(big.NewInt(int64(len(block.Transactions))).Bytes())
  113. case "eth_getUncleCountByBlockHash":
  114. args := new(HashArgs)
  115. if err := json.Unmarshal(req.Params, &args); err != nil {
  116. return err
  117. }
  118. block := api.xeth().EthBlockByHash(args.Hash)
  119. br := NewBlockRes(block, false)
  120. *reply = common.ToHex(big.NewInt(int64(len(br.Uncles))).Bytes())
  121. case "eth_getUncleCountByBlockNumber":
  122. args := new(BlockNumArg)
  123. if err := json.Unmarshal(req.Params, &args); err != nil {
  124. return err
  125. }
  126. block := api.xeth().EthBlockByNumber(args.BlockNumber)
  127. br := NewBlockRes(block, false)
  128. *reply = common.ToHex(big.NewInt(int64(len(br.Uncles))).Bytes())
  129. case "eth_getData", "eth_getCode":
  130. args := new(GetDataArgs)
  131. if err := json.Unmarshal(req.Params, &args); err != nil {
  132. return err
  133. }
  134. v := api.xethAtStateNum(args.BlockNumber).CodeAtBytes(args.Address)
  135. *reply = newHexData(v)
  136. case "eth_sendTransaction", "eth_transact":
  137. args := new(NewTxArgs)
  138. if err := json.Unmarshal(req.Params, &args); err != nil {
  139. return err
  140. }
  141. v, err := api.xeth().Transact(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data)
  142. if err != nil {
  143. return err
  144. }
  145. *reply = v
  146. case "eth_call":
  147. args := new(CallArgs)
  148. if err := json.Unmarshal(req.Params, &args); err != nil {
  149. return err
  150. }
  151. v, err := api.xethAtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data)
  152. if err != nil {
  153. return err
  154. }
  155. *reply = v
  156. case "eth_flush":
  157. return NewNotImplementedError(req.Method)
  158. case "eth_getBlockByHash":
  159. args := new(GetBlockByHashArgs)
  160. if err := json.Unmarshal(req.Params, &args); err != nil {
  161. return err
  162. }
  163. block := api.xeth().EthBlockByHash(args.BlockHash)
  164. br := NewBlockRes(block, args.IncludeTxs)
  165. *reply = br
  166. case "eth_getBlockByNumber":
  167. args := new(GetBlockByNumberArgs)
  168. if err := json.Unmarshal(req.Params, &args); err != nil {
  169. return err
  170. }
  171. block := api.xeth().EthBlockByNumber(args.BlockNumber)
  172. br := NewBlockRes(block, args.IncludeTxs)
  173. *reply = br
  174. case "eth_getTransactionByHash":
  175. args := new(HashArgs)
  176. if err := json.Unmarshal(req.Params, &args); err != nil {
  177. return err
  178. }
  179. tx, bhash, bnum, txi := api.xeth().EthTransactionByHash(args.Hash)
  180. if tx != nil {
  181. v := NewTransactionRes(tx)
  182. v.BlockHash = newHexData(bhash)
  183. v.BlockNumber = newHexNum(bnum)
  184. v.TxIndex = newHexNum(txi)
  185. *reply = v
  186. }
  187. case "eth_getTransactionByBlockHashAndIndex":
  188. args := new(HashIndexArgs)
  189. if err := json.Unmarshal(req.Params, &args); err != nil {
  190. return err
  191. }
  192. block := api.xeth().EthBlockByHash(args.Hash)
  193. br := NewBlockRes(block, true)
  194. if br == nil {
  195. *reply = nil
  196. }
  197. if args.Index >= int64(len(br.Transactions)) || args.Index < 0 {
  198. // return NewValidationError("Index", "does not exist")
  199. *reply = nil
  200. } else {
  201. *reply = br.Transactions[args.Index]
  202. }
  203. case "eth_getTransactionByBlockNumberAndIndex":
  204. args := new(BlockNumIndexArgs)
  205. if err := json.Unmarshal(req.Params, &args); err != nil {
  206. return err
  207. }
  208. block := api.xeth().EthBlockByNumber(args.BlockNumber)
  209. v := NewBlockRes(block, true)
  210. if v == nil {
  211. *reply = nil
  212. }
  213. if args.Index >= int64(len(v.Transactions)) || args.Index < 0 {
  214. // return NewValidationError("Index", "does not exist")
  215. *reply = nil
  216. } else {
  217. *reply = v.Transactions[args.Index]
  218. }
  219. case "eth_getUncleByBlockHashAndIndex":
  220. args := new(HashIndexArgs)
  221. if err := json.Unmarshal(req.Params, &args); err != nil {
  222. return err
  223. }
  224. br := NewBlockRes(api.xeth().EthBlockByHash(args.Hash), false)
  225. if br == nil {
  226. *reply = nil
  227. return nil
  228. }
  229. if args.Index >= int64(len(br.Uncles)) || args.Index < 0 {
  230. // return NewValidationError("Index", "does not exist")
  231. *reply = nil
  232. } else {
  233. *reply = br.Uncles[args.Index]
  234. }
  235. case "eth_getUncleByBlockNumberAndIndex":
  236. args := new(BlockNumIndexArgs)
  237. if err := json.Unmarshal(req.Params, &args); err != nil {
  238. return err
  239. }
  240. block := api.xeth().EthBlockByNumber(args.BlockNumber)
  241. v := NewBlockRes(block, true)
  242. if v == nil {
  243. *reply = nil
  244. return nil
  245. }
  246. if args.Index >= int64(len(v.Uncles)) || args.Index < 0 {
  247. // return NewValidationError("Index", "does not exist")
  248. *reply = nil
  249. } else {
  250. *reply = v.Uncles[args.Index]
  251. }
  252. case "eth_getCompilers":
  253. c := []string{""}
  254. *reply = c
  255. case "eth_compileSolidity", "eth_compileLLL", "eth_compileSerpent":
  256. return NewNotImplementedError(req.Method)
  257. case "eth_newFilter":
  258. args := new(BlockFilterArgs)
  259. if err := json.Unmarshal(req.Params, &args); err != nil {
  260. return err
  261. }
  262. id := api.xeth().RegisterFilter(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics)
  263. *reply = common.ToHex(big.NewInt(int64(id)).Bytes())
  264. case "eth_newBlockFilter":
  265. args := new(FilterStringArgs)
  266. if err := json.Unmarshal(req.Params, &args); err != nil {
  267. return err
  268. }
  269. id := api.xeth().NewFilterString(args.Word)
  270. *reply = common.ToHex(big.NewInt(int64(id)).Bytes())
  271. case "eth_uninstallFilter":
  272. args := new(FilterIdArgs)
  273. if err := json.Unmarshal(req.Params, &args); err != nil {
  274. return err
  275. }
  276. *reply = api.xeth().UninstallFilter(args.Id)
  277. case "eth_getFilterChanges":
  278. args := new(FilterIdArgs)
  279. if err := json.Unmarshal(req.Params, &args); err != nil {
  280. return err
  281. }
  282. *reply = NewLogsRes(api.xeth().FilterChanged(args.Id))
  283. case "eth_getFilterLogs":
  284. args := new(FilterIdArgs)
  285. if err := json.Unmarshal(req.Params, &args); err != nil {
  286. return err
  287. }
  288. *reply = NewLogsRes(api.xeth().Logs(args.Id))
  289. case "eth_getLogs":
  290. args := new(BlockFilterArgs)
  291. if err := json.Unmarshal(req.Params, &args); err != nil {
  292. return err
  293. }
  294. *reply = NewLogsRes(api.xeth().AllLogs(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics))
  295. case "eth_getWork":
  296. api.xeth().SetMining(true)
  297. *reply = api.xeth().RemoteMining().GetWork()
  298. case "eth_submitWork":
  299. args := new(SubmitWorkArgs)
  300. if err := json.Unmarshal(req.Params, &args); err != nil {
  301. return err
  302. }
  303. *reply = api.xeth().RemoteMining().SubmitWork(args.Nonce, common.HexToHash(args.Digest), common.HexToHash(args.Header))
  304. case "db_putString":
  305. args := new(DbArgs)
  306. if err := json.Unmarshal(req.Params, &args); err != nil {
  307. return err
  308. }
  309. if err := args.requirements(); err != nil {
  310. return err
  311. }
  312. api.xeth().DbPut([]byte(args.Database+args.Key), args.Value)
  313. *reply = true
  314. case "db_getString":
  315. args := new(DbArgs)
  316. if err := json.Unmarshal(req.Params, &args); err != nil {
  317. return err
  318. }
  319. if err := args.requirements(); err != nil {
  320. return err
  321. }
  322. res, _ := api.xeth().DbGet([]byte(args.Database + args.Key))
  323. *reply = string(res)
  324. case "db_putHex":
  325. args := new(DbHexArgs)
  326. if err := json.Unmarshal(req.Params, &args); err != nil {
  327. return err
  328. }
  329. if err := args.requirements(); err != nil {
  330. return err
  331. }
  332. api.xeth().DbPut([]byte(args.Database+args.Key), args.Value)
  333. *reply = true
  334. case "db_getHex":
  335. args := new(DbHexArgs)
  336. if err := json.Unmarshal(req.Params, &args); err != nil {
  337. return err
  338. }
  339. if err := args.requirements(); err != nil {
  340. return err
  341. }
  342. res, _ := api.xeth().DbGet([]byte(args.Database + args.Key))
  343. *reply = common.ToHex(res)
  344. case "shh_version":
  345. *reply = api.xeth().WhisperVersion()
  346. case "shh_post":
  347. args := new(WhisperMessageArgs)
  348. if err := json.Unmarshal(req.Params, &args); err != nil {
  349. return err
  350. }
  351. err := api.xeth().Whisper().Post(args.Payload, args.To, args.From, args.Topics, args.Priority, args.Ttl)
  352. if err != nil {
  353. return err
  354. }
  355. *reply = true
  356. case "shh_newIdentity":
  357. *reply = api.xeth().Whisper().NewIdentity()
  358. // case "shh_removeIdentity":
  359. // args := new(WhisperIdentityArgs)
  360. // if err := json.Unmarshal(req.Params, &args); err != nil {
  361. // return err
  362. // }
  363. // *reply = api.xeth().Whisper().RemoveIdentity(args.Identity)
  364. case "shh_hasIdentity":
  365. args := new(WhisperIdentityArgs)
  366. if err := json.Unmarshal(req.Params, &args); err != nil {
  367. return err
  368. }
  369. *reply = api.xeth().Whisper().HasIdentity(args.Identity)
  370. case "shh_newGroup", "shh_addToGroup":
  371. return NewNotImplementedError(req.Method)
  372. case "shh_newFilter":
  373. args := new(WhisperFilterArgs)
  374. if err := json.Unmarshal(req.Params, &args); err != nil {
  375. return err
  376. }
  377. opts := new(xeth.Options)
  378. // opts.From = args.From
  379. opts.To = args.To
  380. opts.Topics = args.Topics
  381. id := api.xeth().NewWhisperFilter(opts)
  382. *reply = common.ToHex(big.NewInt(int64(id)).Bytes())
  383. case "shh_uninstallFilter":
  384. args := new(FilterIdArgs)
  385. if err := json.Unmarshal(req.Params, &args); err != nil {
  386. return err
  387. }
  388. *reply = api.xeth().UninstallWhisperFilter(args.Id)
  389. case "shh_getFilterChanges":
  390. args := new(FilterIdArgs)
  391. if err := json.Unmarshal(req.Params, &args); err != nil {
  392. return err
  393. }
  394. *reply = api.xeth().MessagesChanged(args.Id)
  395. case "shh_getMessages":
  396. args := new(FilterIdArgs)
  397. if err := json.Unmarshal(req.Params, &args); err != nil {
  398. return err
  399. }
  400. *reply = api.xeth().Whisper().Messages(args.Id)
  401. // case "eth_register":
  402. // // Placeholder for actual type
  403. // args := new(HashIndexArgs)
  404. // if err := json.Unmarshal(req.Params, &args); err != nil {
  405. // return err
  406. // }
  407. // *reply = api.xeth().Register(args.Hash)
  408. // case "eth_unregister":
  409. // args := new(HashIndexArgs)
  410. // if err := json.Unmarshal(req.Params, &args); err != nil {
  411. // return err
  412. // }
  413. // *reply = api.xeth().Unregister(args.Hash)
  414. // case "eth_watchTx":
  415. // args := new(HashIndexArgs)
  416. // if err := json.Unmarshal(req.Params, &args); err != nil {
  417. // return err
  418. // }
  419. // *reply = api.xeth().PullWatchTx(args.Hash)
  420. default:
  421. return NewNotImplementedError(req.Method)
  422. }
  423. rpclogger.DebugDetailf("Reply: %T %s", reply, reply)
  424. return nil
  425. }