You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

320 lines
8.2 KiB

  1. package rpc
  2. import (
  3. "bytes"
  4. "encoding/hex"
  5. "github.com/tendermint/tendermint/account"
  6. "github.com/tendermint/tendermint/binary"
  7. "github.com/tendermint/tendermint/config"
  8. "github.com/tendermint/tendermint/daemon"
  9. "github.com/tendermint/tendermint/logger"
  10. "github.com/tendermint/tendermint/p2p"
  11. "github.com/tendermint/tendermint/rpc"
  12. "github.com/tendermint/tendermint/rpc/core"
  13. "github.com/tendermint/tendermint/state"
  14. "github.com/tendermint/tendermint/types"
  15. "io/ioutil"
  16. "net/http"
  17. "net/url"
  18. "testing"
  19. )
  20. var (
  21. rpcAddr = "127.0.0.1:8089"
  22. requestAddr = "http://" + rpcAddr + "/"
  23. node *daemon.Node
  24. mempoolCount = 0
  25. userAddr = "D7DFF9806078899C8DA3FE3633CC0BF3C6C2B1BB"
  26. userPriv = "FDE3BD94CB327D19464027BA668194C5EFA46AE83E8419D7542CFF41F00C81972239C21C81EA7173A6C489145490C015E05D4B97448933B708A7EC5B7B4921E3"
  27. userPub = "2239C21C81EA7173A6C489145490C015E05D4B97448933B708A7EC5B7B4921E3"
  28. )
  29. func newNode(ready chan struct{}) {
  30. // Create & start node
  31. node = daemon.NewNode()
  32. l := p2p.NewDefaultListener("tcp", config.App().GetString("ListenAddr"), false)
  33. node.AddListener(l)
  34. node.Start()
  35. // Run the RPC server.
  36. node.StartRPC()
  37. ready <- struct{}{}
  38. // Sleep forever
  39. ch := make(chan struct{})
  40. <-ch
  41. }
  42. func init() {
  43. rootDir := ".tendermint"
  44. config.Init(rootDir)
  45. app := config.App()
  46. app.Set("SeedNode", "")
  47. app.Set("DB.Backend", "memdb")
  48. app.Set("RPC.HTTP.ListenAddr", rpcAddr)
  49. app.Set("GenesisFile", rootDir+"/genesis.json")
  50. app.Set("PrivValidatorFile", rootDir+"/priv_validator.json")
  51. app.Set("Log.Stdout.Level", "debug")
  52. config.SetApp(app)
  53. logger.Reset()
  54. priv := state.LoadPrivValidator(rootDir + "/priv_validator.json")
  55. priv.LastHeight = 0
  56. priv.LastRound = 0
  57. priv.LastStep = 0
  58. priv.Save()
  59. // start a node
  60. ready := make(chan struct{})
  61. go newNode(ready)
  62. <-ready
  63. }
  64. func getAccount(t *testing.T, typ string, addr []byte) *account.Account {
  65. var client rpc.Client
  66. switch typ {
  67. case "JSONRPC":
  68. client = rpc.NewClient(requestAddr, "JSONRPC")
  69. case "HTTP":
  70. client = rpc.NewClient(requestAddr, "HTTP")
  71. }
  72. ac, err := client.GetAccount(addr)
  73. if err != nil {
  74. t.Fatal(err)
  75. }
  76. return ac.Account
  77. }
  78. /*
  79. func getAccount(t *testing.T, typ string, addr []byte) *account.Account {
  80. var resp *http.Response
  81. var err error
  82. switch typ {
  83. case "JSONRPC":
  84. s := rpc.JSONRPC{
  85. JSONRPC: "2.0",
  86. Method: "get_account",
  87. Params: []interface{}{hex.EncodeToString(addr)},
  88. Id: 0,
  89. }
  90. b, err := json.Marshal(s)
  91. if err != nil {
  92. t.Fatal(err)
  93. }
  94. buf := bytes.NewBuffer(b)
  95. resp, err = http.Post(requestAddr, "text/json", buf)
  96. case "HTTP":
  97. resp, err = http.PostForm(requestAddr+"get_account",
  98. url.Values{"address": {"\"" + (hex.EncodeToString(addr)) + "\""}})
  99. }
  100. if err != nil {
  101. t.Fatal(err)
  102. }
  103. defer resp.Body.Close()
  104. body, err := ioutil.ReadAll(resp.Body)
  105. if err != nil {
  106. t.Fatal(err)
  107. }
  108. var response struct {
  109. Result core.ResponseGetAccount `json:"result"`
  110. Error string `json:"error"`
  111. Id string `json:"id"`
  112. JSONRPC string `json:"jsonrpc"`
  113. }
  114. binary.ReadJSON(&response, body, &err)
  115. if err != nil {
  116. t.Fatal(err)
  117. }
  118. return response.Result.Account
  119. }*/
  120. func makeSendTx(t *testing.T, typ string, from, to []byte, amt uint64) *types.SendTx {
  121. acc := getAccount(t, typ, from)
  122. nonce := 0
  123. if acc != nil {
  124. nonce = int(acc.Sequence) + 1
  125. }
  126. bytePub, err := hex.DecodeString(userPub)
  127. if err != nil {
  128. t.Fatal(err)
  129. }
  130. tx := &types.SendTx{
  131. Inputs: []*types.TxInput{
  132. &types.TxInput{
  133. Address: from,
  134. Amount: amt,
  135. Sequence: uint(nonce),
  136. Signature: account.SignatureEd25519{},
  137. PubKey: account.PubKeyEd25519(bytePub),
  138. },
  139. },
  140. Outputs: []*types.TxOutput{
  141. &types.TxOutput{
  142. Address: to,
  143. Amount: amt,
  144. },
  145. },
  146. }
  147. return tx
  148. }
  149. func makeCallTx(t *testing.T, typ string, from, to, data []byte, amt, gaslim, fee uint64) *types.CallTx {
  150. acc := getAccount(t, typ, from)
  151. nonce := 0
  152. if acc != nil {
  153. nonce = int(acc.Sequence) + 1
  154. }
  155. bytePub, err := hex.DecodeString(userPub)
  156. if err != nil {
  157. t.Fatal(err)
  158. }
  159. tx := &types.CallTx{
  160. Input: &types.TxInput{
  161. Address: from,
  162. Amount: amt,
  163. Sequence: uint(nonce),
  164. Signature: account.SignatureEd25519{},
  165. PubKey: account.PubKeyEd25519(bytePub),
  166. },
  167. Address: to,
  168. GasLimit: gaslim,
  169. Fee: fee,
  170. Data: data,
  171. }
  172. return tx
  173. }
  174. func requestResponse(t *testing.T, method string, values url.Values, response interface{}) {
  175. resp, err := http.PostForm(requestAddr+method, values)
  176. if err != nil {
  177. t.Fatal(err)
  178. }
  179. defer resp.Body.Close()
  180. body, err := ioutil.ReadAll(resp.Body)
  181. if err != nil {
  182. t.Fatal(err)
  183. }
  184. binary.ReadJSON(response, body, &err)
  185. if err != nil {
  186. t.Fatal(err)
  187. }
  188. }
  189. func signTx(t *testing.T, typ string, fromAddr, toAddr, data []byte, key [64]byte, amt, gaslim, fee uint64) (types.Tx, *account.PrivAccount) {
  190. var tx types.Tx
  191. if data == nil {
  192. tx = makeSendTx(t, typ, fromAddr, toAddr, amt)
  193. } else {
  194. tx = makeCallTx(t, typ, fromAddr, toAddr, data, amt, gaslim, fee)
  195. }
  196. n, w := new(int64), new(bytes.Buffer)
  197. var err error
  198. binary.WriteJSON(tx, w, n, &err)
  199. if err != nil {
  200. t.Fatal(err)
  201. }
  202. b := w.Bytes()
  203. privAcc := account.GenPrivAccountFromKey(key)
  204. if bytes.Compare(privAcc.PubKey.Address(), fromAddr) != 0 {
  205. t.Fatal("Faield to generate correct priv acc")
  206. }
  207. w = new(bytes.Buffer)
  208. binary.WriteJSON([]*account.PrivAccount{privAcc}, w, n, &err)
  209. if err != nil {
  210. t.Fatal(err)
  211. }
  212. var response struct {
  213. Result core.ResponseSignTx `json:"result"`
  214. Error string `json:"error"`
  215. Id string `json:"id"`
  216. JSONRPC string `json:"jsonrpc"`
  217. }
  218. requestResponse(t, "unsafe/sign_tx", url.Values{"tx": {string(b)}, "privAccounts": {string(w.Bytes())}}, &response)
  219. if response.Error != "" {
  220. t.Fatal(response.Error)
  221. }
  222. result := response.Result
  223. return result.Tx, privAcc
  224. }
  225. func broadcastTx(t *testing.T, typ string, fromAddr, toAddr, data []byte, key [64]byte, amt, gaslim, fee uint64) (types.Tx, core.Receipt) {
  226. tx, _ := signTx(t, typ, fromAddr, toAddr, data, key, amt, gaslim, fee)
  227. n, w := new(int64), new(bytes.Buffer)
  228. var err error
  229. binary.WriteJSON(tx, w, n, &err)
  230. if err != nil {
  231. t.Fatal(err)
  232. }
  233. b := w.Bytes()
  234. var response struct {
  235. Result core.ResponseBroadcastTx `json:"result"`
  236. Error string `json:"error"`
  237. Id string `json:"id"`
  238. JSONRPC string `json:"jsonrpc"`
  239. }
  240. requestResponse(t, "broadcast_tx", url.Values{"tx": {string(b)}}, &response)
  241. if response.Error != "" {
  242. t.Fatal(response.Error)
  243. }
  244. return tx, response.Result.Receipt
  245. }
  246. func dumpStorage(t *testing.T, addr []byte) core.ResponseDumpStorage {
  247. addrString := "\"" + hex.EncodeToString(addr) + "\""
  248. var response struct {
  249. Result core.ResponseDumpStorage `json:"result"`
  250. Error string `json:"error"`
  251. Id string `json:"id"`
  252. JSONRPC string `json:"jsonrpc"`
  253. }
  254. requestResponse(t, "dump_storage", url.Values{"address": {addrString}}, &response)
  255. if response.Error != "" {
  256. t.Fatal(response.Error)
  257. }
  258. return response.Result
  259. }
  260. func getStorage(t *testing.T, addr, slot []byte) []byte {
  261. addrString := "\"" + hex.EncodeToString(addr) + "\""
  262. slotString := "\"" + hex.EncodeToString(slot) + "\""
  263. var response struct {
  264. Result core.ResponseGetStorage `json:"result"`
  265. Error string `json:"error"`
  266. Id string `json:"id"`
  267. JSONRPC string `json:"jsonrpc"`
  268. }
  269. requestResponse(t, "get_storage", url.Values{"address": {addrString}, "storage": {slotString}}, &response)
  270. if response.Error != "" {
  271. t.Fatal(response.Error)
  272. }
  273. return response.Result.Value
  274. }
  275. func checkTx(t *testing.T, fromAddr []byte, priv *account.PrivAccount, tx *types.SendTx) {
  276. if bytes.Compare(tx.Inputs[0].Address, fromAddr) != 0 {
  277. t.Fatal("Tx input addresses don't match!")
  278. }
  279. signBytes := account.SignBytes(tx)
  280. in := tx.Inputs[0] //(*types.SendTx).Inputs[0]
  281. if err := in.ValidateBasic(); err != nil {
  282. t.Fatal(err)
  283. }
  284. // Check signatures
  285. // acc := getAccount(t, byteAddr)
  286. // NOTE: using the acc here instead of the in fails; its PubKeyNil ... ?
  287. if !in.PubKey.VerifyBytes(signBytes, in.Signature) {
  288. t.Fatal(types.ErrTxInvalidSignature)
  289. }
  290. }