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.

265 lines
6.9 KiB

  1. package rpc
  2. import (
  3. "bytes"
  4. "encoding/hex"
  5. "github.com/tendermint/tendermint/account"
  6. . "github.com/tendermint/tendermint/common"
  7. "github.com/tendermint/tendermint/config"
  8. "github.com/tendermint/tendermint/logger"
  9. nm "github.com/tendermint/tendermint/node"
  10. "github.com/tendermint/tendermint/p2p"
  11. ctypes "github.com/tendermint/tendermint/rpc/core/types"
  12. cclient "github.com/tendermint/tendermint/rpc/core_client"
  13. "github.com/tendermint/tendermint/state"
  14. "github.com/tendermint/tendermint/types"
  15. "testing"
  16. )
  17. // global variables for use across all tests
  18. var (
  19. rpcAddr = "127.0.0.1:8089"
  20. requestAddr = "http://" + rpcAddr + "/"
  21. node *nm.Node
  22. mempoolCount = 0
  23. userAddr = "D7DFF9806078899C8DA3FE3633CC0BF3C6C2B1BB"
  24. userPriv = "FDE3BD94CB327D19464027BA668194C5EFA46AE83E8419D7542CFF41F00C81972239C21C81EA7173A6C489145490C015E05D4B97448933B708A7EC5B7B4921E3"
  25. userPub = "2239C21C81EA7173A6C489145490C015E05D4B97448933B708A7EC5B7B4921E3"
  26. clients = map[string]cclient.Client{
  27. "JSONRPC": cclient.NewClient(requestAddr, "JSONRPC"),
  28. "HTTP": cclient.NewClient(requestAddr, "HTTP"),
  29. }
  30. )
  31. func decodeHex(hexStr string) []byte {
  32. bytes, err := hex.DecodeString(hexStr)
  33. if err != nil {
  34. panic(err)
  35. }
  36. return bytes
  37. }
  38. // create a new node and sleep forever
  39. func newNode(ready chan struct{}) {
  40. // Create & start node
  41. node = nm.NewNode()
  42. l := p2p.NewDefaultListener("tcp", config.App().GetString("ListenAddr"), false)
  43. node.AddListener(l)
  44. node.Start()
  45. // Run the RPC server.
  46. node.StartRPC()
  47. ready <- struct{}{}
  48. // Sleep forever
  49. ch := make(chan struct{})
  50. <-ch
  51. }
  52. // initialize config and create new node
  53. func init() {
  54. rootDir := ".tendermint"
  55. config.Init(rootDir)
  56. app := config.App()
  57. app.Set("SeedNode", "")
  58. app.Set("DB.Backend", "memdb")
  59. app.Set("RPC.HTTP.ListenAddr", rpcAddr)
  60. app.Set("GenesisFile", rootDir+"/genesis.json")
  61. app.Set("PrivValidatorFile", rootDir+"/priv_validator.json")
  62. app.Set("Log.Stdout.Level", "debug")
  63. config.SetApp(app)
  64. logger.Reset()
  65. // Save new priv_validator file.
  66. priv := &state.PrivValidator{
  67. Address: decodeHex(userAddr),
  68. PubKey: account.PubKeyEd25519(decodeHex(userPub)),
  69. PrivKey: account.PrivKeyEd25519(decodeHex(userPriv)),
  70. }
  71. priv.SetFile(rootDir + "/priv_validator.json")
  72. priv.Save()
  73. // start a node
  74. ready := make(chan struct{})
  75. go newNode(ready)
  76. <-ready
  77. }
  78. //-------------------------------------------------------------------------------
  79. // make transactions
  80. // make a send tx (uses get account to figure out the nonce)
  81. func makeSendTx(t *testing.T, typ string, from, to []byte, amt uint64) *types.SendTx {
  82. acc := getAccount(t, typ, from)
  83. nonce := 0
  84. if acc != nil {
  85. nonce = int(acc.Sequence) + 1
  86. }
  87. bytePub, err := hex.DecodeString(userPub)
  88. if err != nil {
  89. t.Fatal(err)
  90. }
  91. tx := &types.SendTx{
  92. Inputs: []*types.TxInput{
  93. &types.TxInput{
  94. Address: from,
  95. Amount: amt,
  96. Sequence: uint(nonce),
  97. Signature: account.SignatureEd25519{},
  98. PubKey: account.PubKeyEd25519(bytePub),
  99. },
  100. },
  101. Outputs: []*types.TxOutput{
  102. &types.TxOutput{
  103. Address: to,
  104. Amount: amt,
  105. },
  106. },
  107. }
  108. return tx
  109. }
  110. // make a call tx (uses get account to figure out the nonce)
  111. func makeCallTx(t *testing.T, typ string, from, to, data []byte, amt, gaslim, fee uint64) *types.CallTx {
  112. acc := getAccount(t, typ, from)
  113. nonce := 0
  114. if acc != nil {
  115. nonce = int(acc.Sequence) + 1
  116. }
  117. bytePub, err := hex.DecodeString(userPub)
  118. if err != nil {
  119. t.Fatal(err)
  120. }
  121. tx := &types.CallTx{
  122. Input: &types.TxInput{
  123. Address: from,
  124. Amount: amt,
  125. Sequence: uint(nonce),
  126. Signature: account.SignatureEd25519{},
  127. PubKey: account.PubKeyEd25519(bytePub),
  128. },
  129. Address: to,
  130. GasLimit: gaslim,
  131. Fee: fee,
  132. Data: data,
  133. }
  134. return tx
  135. }
  136. // make transactions
  137. //-------------------------------------------------------------------------------
  138. // rpc call wrappers
  139. // get the account
  140. func getAccount(t *testing.T, typ string, addr []byte) *account.Account {
  141. client := clients[typ]
  142. ac, err := client.GetAccount(addr)
  143. if err != nil {
  144. t.Fatal(err)
  145. }
  146. return ac.Account
  147. }
  148. // make and sign transaction
  149. func signTx(t *testing.T, typ string, fromAddr, toAddr, data []byte, key [64]byte, amt, gaslim, fee uint64) (types.Tx, *account.PrivAccount) {
  150. var tx types.Tx
  151. if data == nil {
  152. tx = makeSendTx(t, typ, fromAddr, toAddr, amt)
  153. } else {
  154. tx = makeCallTx(t, typ, fromAddr, toAddr, data, amt, gaslim, fee)
  155. }
  156. privAcc := account.GenPrivAccountFromKey(key)
  157. if bytes.Compare(privAcc.PubKey.Address(), fromAddr) != 0 {
  158. t.Fatal("Faield to generate correct priv acc")
  159. }
  160. client := clients[typ]
  161. resp, err := client.SignTx(tx, []*account.PrivAccount{privAcc})
  162. if err != nil {
  163. t.Fatal(err)
  164. }
  165. return resp.Tx, privAcc
  166. }
  167. // create, sign, and broadcast a transaction
  168. func broadcastTx(t *testing.T, typ string, fromAddr, toAddr, data []byte, key [64]byte, amt, gaslim, fee uint64) (types.Tx, ctypes.Receipt) {
  169. tx, _ := signTx(t, typ, fromAddr, toAddr, data, key, amt, gaslim, fee)
  170. client := clients[typ]
  171. resp, err := client.BroadcastTx(tx)
  172. if err != nil {
  173. t.Fatal(err)
  174. }
  175. mempoolCount += 1
  176. return tx, resp.Receipt
  177. }
  178. // dump all storage for an account. currently unused
  179. func dumpStorage(t *testing.T, addr []byte) ctypes.ResponseDumpStorage {
  180. client := clients["HTTP"]
  181. resp, err := client.DumpStorage(addr)
  182. if err != nil {
  183. t.Fatal(err)
  184. }
  185. return *resp
  186. }
  187. func getStorage(t *testing.T, typ string, addr, key []byte) []byte {
  188. client := clients[typ]
  189. resp, err := client.GetStorage(addr, key)
  190. if err != nil {
  191. t.Fatal(err)
  192. }
  193. return resp.Value
  194. }
  195. func callCode(t *testing.T, client cclient.Client, code, data, expected []byte) {
  196. resp, err := client.CallCode(code, data)
  197. if err != nil {
  198. t.Fatal(err)
  199. }
  200. ret := resp.Return
  201. // NOTE: we don't flip memory when it comes out of RETURN (?!)
  202. if bytes.Compare(ret, LeftPadWord256(expected).Bytes()) != 0 {
  203. t.Fatalf("Conflicting return value. Got %x, expected %x", ret, expected)
  204. }
  205. }
  206. func callContract(t *testing.T, client cclient.Client, address, data, expected []byte) {
  207. resp, err := client.Call(address, data)
  208. if err != nil {
  209. t.Fatal(err)
  210. }
  211. ret := resp.Return
  212. // NOTE: we don't flip memory when it comes out of RETURN (?!)
  213. if bytes.Compare(ret, LeftPadWord256(expected).Bytes()) != 0 {
  214. t.Fatalf("Conflicting return value. Got %x, expected %x", ret, expected)
  215. }
  216. }
  217. //--------------------------------------------------------------------------------
  218. // utility verification function
  219. func checkTx(t *testing.T, fromAddr []byte, priv *account.PrivAccount, tx *types.SendTx) {
  220. if bytes.Compare(tx.Inputs[0].Address, fromAddr) != 0 {
  221. t.Fatal("Tx input addresses don't match!")
  222. }
  223. signBytes := account.SignBytes(tx)
  224. in := tx.Inputs[0] //(*types.SendTx).Inputs[0]
  225. if err := in.ValidateBasic(); err != nil {
  226. t.Fatal(err)
  227. }
  228. // Check signatures
  229. // acc := getAccount(t, byteAddr)
  230. // NOTE: using the acc here instead of the in fails; it is nil.
  231. if !in.PubKey.VerifyBytes(signBytes, in.Signature) {
  232. t.Fatal(types.ErrTxInvalidSignature)
  233. }
  234. }