packages.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  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 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 General Public License
  12. along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /*
  15. For each request type, define the following:
  16. 1. RpcRequest "To" method [message.go], which does basic validation and conversion to "Args" type via json.Decoder()
  17. 2. json.Decoder() calls "UnmarshalON" defined on each "Args" struct
  18. 3. EthereumApi method, taking the "Args" type and replying with an interface to be marshalled to ON
  19. */
  20. package rpc
  21. import (
  22. "fmt"
  23. "math/big"
  24. "strings"
  25. "sync"
  26. "github.com/ethereum/go-ethereum/core"
  27. "github.com/ethereum/go-ethereum/crypto"
  28. "github.com/ethereum/go-ethereum/ethdb"
  29. "github.com/ethereum/go-ethereum/ethutil"
  30. "github.com/ethereum/go-ethereum/event/filter"
  31. "github.com/ethereum/go-ethereum/state"
  32. "github.com/ethereum/go-ethereum/xeth"
  33. )
  34. type EthereumApi struct {
  35. xeth *xeth.XEth
  36. filterManager *filter.FilterManager
  37. mut sync.RWMutex
  38. logs map[int]state.Logs
  39. db ethutil.Database
  40. }
  41. func NewEthereumApi(xeth *xeth.XEth) *EthereumApi {
  42. db, _ := ethdb.NewLDBDatabase("dapps")
  43. api := &EthereumApi{
  44. xeth: xeth,
  45. filterManager: filter.NewFilterManager(xeth.Backend().EventMux()),
  46. logs: make(map[int]state.Logs),
  47. db: db,
  48. }
  49. go api.filterManager.Start()
  50. return api
  51. }
  52. func (self *EthereumApi) NewFilter(args *FilterOptions, reply *interface{}) error {
  53. var id int
  54. filter := core.NewFilter(self.xeth.Backend())
  55. filter.LogsCallback = func(logs state.Logs) {
  56. self.mut.Lock()
  57. defer self.mut.Unlock()
  58. self.logs[id] = append(self.logs[id], logs...)
  59. }
  60. id = self.filterManager.InstallFilter(filter)
  61. *reply = id
  62. return nil
  63. }
  64. func (self *EthereumApi) FilterChanged(id int, reply *interface{}) error {
  65. self.mut.RLock()
  66. defer self.mut.RUnlock()
  67. *reply = toLogs(self.logs[id])
  68. self.logs[id] = nil // empty the logs
  69. return nil
  70. }
  71. func (self *EthereumApi) Logs(id int, reply *interface{}) error {
  72. filter := self.filterManager.GetFilter(id)
  73. *reply = toLogs(filter.Find())
  74. return nil
  75. }
  76. func (p *EthereumApi) GetBlock(args *GetBlockArgs, reply *interface{}) error {
  77. err := args.requirements()
  78. if err != nil {
  79. return err
  80. }
  81. if args.BlockNumber > 0 {
  82. *reply = p.xeth.BlockByNumber(args.BlockNumber)
  83. } else {
  84. *reply = p.xeth.BlockByHash(args.Hash)
  85. }
  86. return nil
  87. }
  88. func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) error {
  89. err := args.requirements()
  90. if err != nil {
  91. return err
  92. }
  93. result, _ := p.xeth.Transact( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data)
  94. *reply = result
  95. return nil
  96. }
  97. func (p *EthereumApi) Call(args *NewTxArgs, reply *interface{}) error {
  98. result, err := p.xeth.Call( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data)
  99. if err != nil {
  100. return err
  101. }
  102. *reply = result
  103. return nil
  104. }
  105. func (p *EthereumApi) PushTx(args *PushTxArgs, reply *interface{}) error {
  106. err := args.requirementsPushTx()
  107. if err != nil {
  108. return err
  109. }
  110. result, _ := p.xeth.PushTx(args.Tx)
  111. *reply = result
  112. return nil
  113. }
  114. func (p *EthereumApi) GetStateAt(args *GetStateArgs, reply *interface{}) error {
  115. err := args.requirements()
  116. if err != nil {
  117. return err
  118. }
  119. state := p.xeth.State().SafeGet(args.Address)
  120. value := state.StorageString(args.Key)
  121. var hx string
  122. if strings.Index(args.Key, "0x") == 0 {
  123. hx = string([]byte(args.Key)[2:])
  124. } else {
  125. // Convert the incoming string (which is a bigint) into hex
  126. i, _ := new(big.Int).SetString(args.Key, 10)
  127. hx = ethutil.Bytes2Hex(i.Bytes())
  128. }
  129. rpclogger.Debugf("GetStateAt(%s, %s)\n", args.Address, hx)
  130. *reply = map[string]string{args.Key: value.Str()}
  131. return nil
  132. }
  133. func (p *EthereumApi) GetStorageAt(args *GetStorageArgs, reply *interface{}) error {
  134. err := args.requirements()
  135. if err != nil {
  136. return err
  137. }
  138. *reply = p.xeth.State().SafeGet(args.Address).Storage()
  139. return nil
  140. }
  141. func (p *EthereumApi) GetPeerCount(reply *interface{}) error {
  142. *reply = p.xeth.PeerCount()
  143. return nil
  144. }
  145. func (p *EthereumApi) GetIsListening(reply *interface{}) error {
  146. *reply = p.xeth.IsListening()
  147. return nil
  148. }
  149. func (p *EthereumApi) GetCoinbase(reply *interface{}) error {
  150. *reply = p.xeth.Coinbase()
  151. return nil
  152. }
  153. func (p *EthereumApi) Accounts(reply *interface{}) error {
  154. *reply = p.xeth.Accounts()
  155. return nil
  156. }
  157. func (p *EthereumApi) GetIsMining(reply *interface{}) error {
  158. *reply = p.xeth.IsMining()
  159. return nil
  160. }
  161. func (p *EthereumApi) BlockNumber(reply *interface{}) error {
  162. *reply = p.xeth.Backend().ChainManager().CurrentBlock().Number()
  163. return nil
  164. }
  165. func (p *EthereumApi) GetTxCountAt(args *GetTxCountArgs, reply *interface{}) error {
  166. err := args.requirements()
  167. if err != nil {
  168. return err
  169. }
  170. *reply = p.xeth.TxCountAt(args.Address)
  171. return nil
  172. }
  173. func (p *EthereumApi) GetBalanceAt(args *GetBalanceArgs, reply *interface{}) error {
  174. err := args.requirements()
  175. if err != nil {
  176. return err
  177. }
  178. state := p.xeth.State().SafeGet(args.Address)
  179. *reply = toHex(state.Balance().Bytes())
  180. return nil
  181. }
  182. func (p *EthereumApi) GetCodeAt(args *GetCodeAtArgs, reply *interface{}) error {
  183. err := args.requirements()
  184. if err != nil {
  185. return err
  186. }
  187. *reply = p.xeth.CodeAt(args.Address)
  188. return nil
  189. }
  190. func (p *EthereumApi) Sha3(args *Sha3Args, reply *interface{}) error {
  191. *reply = toHex(crypto.Sha3(fromHex(args.Data)))
  192. return nil
  193. }
  194. func (p *EthereumApi) DbPut(args *DbArgs, reply *interface{}) error {
  195. err := args.requirements()
  196. if err != nil {
  197. return err
  198. }
  199. p.db.Put([]byte(args.Database+args.Key), []byte(args.Value))
  200. *reply = true
  201. return nil
  202. }
  203. func (p *EthereumApi) DbGet(args *DbArgs, reply *interface{}) error {
  204. err := args.requirements()
  205. if err != nil {
  206. return err
  207. }
  208. res, _ := p.db.Get([]byte(args.Database + args.Key))
  209. *reply = string(res)
  210. return nil
  211. }
  212. func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error {
  213. // Spec at https://github.com/ethereum/wiki/wiki/Generic-ON-RPC
  214. rpclogger.DebugDetailf("%T %s", req.Params, req.Params)
  215. switch req.Method {
  216. case "eth_coinbase":
  217. return p.GetCoinbase(reply)
  218. case "eth_listening":
  219. return p.GetIsListening(reply)
  220. case "eth_mining":
  221. return p.GetIsMining(reply)
  222. case "eth_peerCount":
  223. return p.GetPeerCount(reply)
  224. case "eth_number":
  225. return p.BlockNumber(reply)
  226. case "eth_accounts":
  227. return p.Accounts(reply)
  228. case "eth_countAt":
  229. args, err := req.ToGetTxCountArgs()
  230. if err != nil {
  231. return err
  232. }
  233. return p.GetTxCountAt(args, reply)
  234. case "eth_codeAt":
  235. args, err := req.ToGetCodeAtArgs()
  236. if err != nil {
  237. return err
  238. }
  239. return p.GetCodeAt(args, reply)
  240. case "eth_balanceAt":
  241. args, err := req.ToGetBalanceArgs()
  242. if err != nil {
  243. return err
  244. }
  245. return p.GetBalanceAt(args, reply)
  246. case "eth_stateAt":
  247. args, err := req.ToGetStateArgs()
  248. if err != nil {
  249. return err
  250. }
  251. return p.GetStateAt(args, reply)
  252. case "eth_storageAt":
  253. args, err := req.ToStorageAtArgs()
  254. if err != nil {
  255. return err
  256. }
  257. return p.GetStorageAt(args, reply)
  258. case "eth_blockByNumber", "eth_blockByHash":
  259. args, err := req.ToGetBlockArgs()
  260. if err != nil {
  261. return err
  262. }
  263. return p.GetBlock(args, reply)
  264. case "eth_transact":
  265. args, err := req.ToNewTxArgs()
  266. if err != nil {
  267. return err
  268. }
  269. return p.Transact(args, reply)
  270. case "eth_call":
  271. args, err := req.ToNewTxArgs()
  272. if err != nil {
  273. return err
  274. }
  275. return p.Call(args, reply)
  276. case "eth_newFilter":
  277. args, err := req.ToFilterArgs()
  278. if err != nil {
  279. return err
  280. }
  281. return p.NewFilter(args, reply)
  282. case "eth_changed":
  283. args, err := req.ToFilterChangedArgs()
  284. if err != nil {
  285. return err
  286. }
  287. return p.FilterChanged(args, reply)
  288. case "eth_gasPrice":
  289. *reply = "10000000000000"
  290. return nil
  291. case "web3_sha3":
  292. args, err := req.ToSha3Args()
  293. if err != nil {
  294. return err
  295. }
  296. return p.Sha3(args, reply)
  297. case "db_put":
  298. args, err := req.ToDbPutArgs()
  299. if err != nil {
  300. return err
  301. }
  302. return p.DbPut(args, reply)
  303. case "db_get":
  304. args, err := req.ToDbGetArgs()
  305. if err != nil {
  306. return err
  307. }
  308. return p.DbGet(args, reply)
  309. default:
  310. return NewErrorResponse(fmt.Sprintf("%v %s", ErrorNotImplemented, req.Method))
  311. }
  312. rpclogger.DebugDetailf("Reply: %T %s", reply, reply)
  313. return nil
  314. }