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.

216 lines
5.0 KiB

  1. package rpc
  2. import (
  3. "bytes"
  4. "encoding/hex"
  5. "encoding/json"
  6. "fmt"
  7. "github.com/tendermint/tendermint/account"
  8. "github.com/tendermint/tendermint/binary"
  9. "github.com/tendermint/tendermint/config"
  10. "github.com/tendermint/tendermint/daemon"
  11. "github.com/tendermint/tendermint/logger"
  12. "github.com/tendermint/tendermint/p2p"
  13. "github.com/tendermint/tendermint/rpc"
  14. "github.com/tendermint/tendermint/rpc/core"
  15. "github.com/tendermint/tendermint/types"
  16. "io/ioutil"
  17. "net/http"
  18. "net/url"
  19. "testing"
  20. )
  21. var (
  22. rpcAddr = "127.0.0.1:8089"
  23. requestAddr = "http://" + rpcAddr + "/"
  24. chainId string
  25. node *daemon.Node
  26. mempoolCount = 0
  27. userAddr = "D7DFF9806078899C8DA3FE3633CC0BF3C6C2B1BB"
  28. userPriv = "FDE3BD94CB327D19464027BA668194C5EFA46AE83E8419D7542CFF41F00C81972239C21C81EA7173A6C489145490C015E05D4B97448933B708A7EC5B7B4921E3"
  29. userPub = "2239C21C81EA7173A6C489145490C015E05D4B97448933B708A7EC5B7B4921E3"
  30. )
  31. func newNode(ready chan struct{}) {
  32. // Create & start node
  33. node = daemon.NewNode()
  34. l := p2p.NewDefaultListener("tcp", config.App().GetString("ListenAddr"), false)
  35. node.AddListener(l)
  36. node.Start()
  37. // Run the RPC server.
  38. node.StartRpc()
  39. ready <- struct{}{}
  40. // Sleep forever
  41. ch := make(chan struct{})
  42. <-ch
  43. }
  44. func init() {
  45. rootDir := ".tendermint"
  46. config.Init(rootDir)
  47. app := config.App()
  48. app.Set("SeedNode", "")
  49. app.Set("DB.Backend", "memdb")
  50. app.Set("RPC.HTTP.ListenAddr", rpcAddr)
  51. app.Set("GenesisFile", rootDir+"/genesis.json")
  52. app.Set("PrivValidatorFile", rootDir+"/priv_validator.json")
  53. app.Set("Log.Stdout.Level", "debug")
  54. config.SetApp(app)
  55. logger.InitLog()
  56. // start a node
  57. ready := make(chan struct{})
  58. go newNode(ready)
  59. <-ready
  60. }
  61. func getAccount(t *testing.T, typ string, addr []byte) *account.Account {
  62. var resp *http.Response
  63. var err error
  64. switch typ {
  65. case "JSONRPC":
  66. s := rpc.JsonRpc{
  67. JsonRpc: "2.0",
  68. Method: "get_account",
  69. Params: []string{"0x" + hex.EncodeToString(addr)},
  70. Id: 0,
  71. }
  72. b, err := json.Marshal(s)
  73. if err != nil {
  74. t.Fatal(err)
  75. }
  76. buf := bytes.NewBuffer(b)
  77. resp, err = http.Post(requestAddr, "text/json", buf)
  78. case "HTTP":
  79. resp, err = http.PostForm(requestAddr+"get_account",
  80. url.Values{"address": {string(addr)}})
  81. }
  82. fmt.Println("RESPONSE:", resp)
  83. if err != nil {
  84. t.Fatal(err)
  85. }
  86. defer resp.Body.Close()
  87. body, err := ioutil.ReadAll(resp.Body)
  88. if err != nil {
  89. t.Fatal(err)
  90. }
  91. var status struct {
  92. Status string
  93. Data core.ResponseGetAccount
  94. Error string
  95. }
  96. fmt.Println(string(body))
  97. binary.ReadJSON(&status, body, &err)
  98. if err != nil {
  99. t.Fatal(err)
  100. }
  101. return status.Data.Account
  102. }
  103. func makeTx(t *testing.T, typ string, from, to []byte, amt uint64) *types.SendTx {
  104. acc := getAccount(t, typ, from)
  105. nonce := 0
  106. if acc != nil {
  107. nonce = int(acc.Sequence) + 1
  108. }
  109. bytePub, err := hex.DecodeString(userPub)
  110. if err != nil {
  111. t.Fatal(err)
  112. }
  113. tx := &types.SendTx{
  114. Inputs: []*types.TxInput{
  115. &types.TxInput{
  116. Address: from,
  117. Amount: amt,
  118. Sequence: uint(nonce),
  119. Signature: account.SignatureEd25519{},
  120. PubKey: account.PubKeyEd25519(bytePub),
  121. },
  122. },
  123. Outputs: []*types.TxOutput{
  124. &types.TxOutput{
  125. Address: to,
  126. Amount: amt,
  127. },
  128. },
  129. }
  130. return tx
  131. }
  132. func requestResponse(t *testing.T, method string, values url.Values, status interface{}) {
  133. resp, err := http.PostForm(requestAddr+method, values)
  134. if err != nil {
  135. t.Fatal(err)
  136. }
  137. defer resp.Body.Close()
  138. body, err := ioutil.ReadAll(resp.Body)
  139. if err != nil {
  140. t.Fatal(err)
  141. }
  142. fmt.Println(string(body))
  143. binary.ReadJSON(status, body, &err)
  144. if err != nil {
  145. t.Fatal(err)
  146. }
  147. }
  148. func signTx(t *testing.T, typ string, fromAddr, toAddr []byte, key [64]byte, amt uint64) (*types.SendTx, *account.PrivAccount) {
  149. tx := makeTx(t, typ, fromAddr, toAddr, amt)
  150. n, w := new(int64), new(bytes.Buffer)
  151. var err error
  152. binary.WriteJSON(tx, w, n, &err)
  153. if err != nil {
  154. t.Fatal(err)
  155. }
  156. b := w.Bytes()
  157. privAcc := account.GenPrivAccountFromKey(key)
  158. if bytes.Compare(privAcc.PubKey.Address(), fromAddr) != 0 {
  159. t.Fatal("Faield to generate correct priv acc")
  160. }
  161. w = new(bytes.Buffer)
  162. binary.WriteJSON([]*account.PrivAccount{privAcc}, w, n, &err)
  163. if err != nil {
  164. t.Fatal(err)
  165. }
  166. var status struct {
  167. Status string
  168. Data core.ResponseSignTx
  169. Error string
  170. }
  171. requestResponse(t, "unsafe/sign_tx", url.Values{"tx": {string(b)}, "privAccounts": {string(w.Bytes())}}, &status)
  172. if status.Status == "ERROR" {
  173. t.Fatal(status.Error)
  174. }
  175. response := status.Data
  176. tx = response.Tx.(*types.SendTx)
  177. return tx, privAcc
  178. }
  179. func checkTx(t *testing.T, fromAddr []byte, priv *account.PrivAccount, tx *types.SendTx) {
  180. if bytes.Compare(tx.Inputs[0].Address, fromAddr) != 0 {
  181. t.Fatal("Tx input addresses don't match!")
  182. }
  183. signBytes := account.SignBytes(tx)
  184. in := tx.Inputs[0] //(*types.SendTx).Inputs[0]
  185. if err := in.ValidateBasic(); err != nil {
  186. t.Fatal(err)
  187. }
  188. fmt.Println(priv.PubKey, in.PubKey)
  189. // Check signatures
  190. // acc := getAccount(t, byteAddr)
  191. // NOTE: using the acc here instead of the in fails; its PubKeyNil ... ?
  192. if !in.PubKey.VerifyBytes(signBytes, in.Signature) {
  193. t.Fatal(types.ErrTxInvalidSignature)
  194. }
  195. }