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.

283 lines
8.3 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package rpctest
  2. import (
  3. "bytes"
  4. "strconv"
  5. "testing"
  6. "github.com/tendermint/tendermint/account"
  7. . "github.com/tendermint/tendermint/common"
  8. nm "github.com/tendermint/tendermint/node"
  9. "github.com/tendermint/tendermint/p2p"
  10. ctypes "github.com/tendermint/tendermint/rpc/core/types"
  11. cclient "github.com/tendermint/tendermint/rpc/core_client"
  12. "github.com/tendermint/tendermint/state"
  13. "github.com/tendermint/tendermint/types"
  14. )
  15. // global variables for use across all tests
  16. var (
  17. rpcAddr = "127.0.0.1:36657" // Not 46657
  18. requestAddr = "http://" + rpcAddr + "/"
  19. websocketAddr = "ws://" + rpcAddr + "/events"
  20. node *nm.Node
  21. mempoolCount = 0
  22. // make keys
  23. user = makeUsers(5)
  24. chainID string
  25. clients = map[string]cclient.Client{
  26. "JSONRPC": cclient.NewClient(requestAddr, "JSONRPC"),
  27. "HTTP": cclient.NewClient(requestAddr, "HTTP"),
  28. }
  29. )
  30. // deterministic account generation, synced with genesis file in config/tendermint_test/config.go
  31. func makeUsers(n int) []*account.PrivAccount {
  32. accounts := []*account.PrivAccount{}
  33. for i := 0; i < n; i++ {
  34. secret := []byte("mysecret" + strconv.Itoa(i))
  35. user := account.GenPrivAccountFromSecret(secret)
  36. accounts = append(accounts, user)
  37. }
  38. return accounts
  39. }
  40. // create a new node and sleep forever
  41. func newNode(ready chan struct{}) {
  42. // Create & start node
  43. node = nm.NewNode()
  44. l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), false)
  45. node.AddListener(l)
  46. node.Start()
  47. // Run the RPC server.
  48. node.StartRPC()
  49. ready <- struct{}{}
  50. // Sleep forever
  51. ch := make(chan struct{})
  52. <-ch
  53. }
  54. // initialize config and create new node
  55. func init() {
  56. chainID = config.GetString("chain_id")
  57. // Save new priv_validator file.
  58. priv := &state.PrivValidator{
  59. Address: user[0].Address,
  60. PubKey: account.PubKeyEd25519(user[0].PubKey.(account.PubKeyEd25519)),
  61. PrivKey: account.PrivKeyEd25519(user[0].PrivKey.(account.PrivKeyEd25519)),
  62. }
  63. priv.SetFile(config.GetString("priv_validator_file"))
  64. priv.Save()
  65. // TODO: change consensus/state.go timeouts to be shorter
  66. // start a node
  67. ready := make(chan struct{})
  68. go newNode(ready)
  69. <-ready
  70. }
  71. //-------------------------------------------------------------------------------
  72. // some default transaction functions
  73. func makeDefaultSendTx(t *testing.T, typ string, addr []byte, amt int64) *types.SendTx {
  74. nonce := getNonce(t, typ, user[0].Address)
  75. tx := types.NewSendTx()
  76. tx.AddInputWithNonce(user[0].PubKey, amt, nonce+1)
  77. tx.AddOutput(addr, amt)
  78. return tx
  79. }
  80. func makeDefaultSendTxSigned(t *testing.T, typ string, addr []byte, amt int64) *types.SendTx {
  81. tx := makeDefaultSendTx(t, typ, addr, amt)
  82. tx.SignInput(chainID, 0, user[0])
  83. return tx
  84. }
  85. func makeDefaultCallTx(t *testing.T, typ string, addr, code []byte, amt, gasLim, fee int64) *types.CallTx {
  86. nonce := getNonce(t, typ, user[0].Address)
  87. tx := types.NewCallTxWithNonce(user[0].PubKey, addr, code, amt, gasLim, fee, nonce+1)
  88. tx.Sign(chainID, user[0])
  89. return tx
  90. }
  91. func makeDefaultNameTx(t *testing.T, typ string, name, value string, amt, fee int64) *types.NameTx {
  92. nonce := getNonce(t, typ, user[0].Address)
  93. tx := types.NewNameTxWithNonce(user[0].PubKey, name, value, amt, fee, nonce+1)
  94. tx.Sign(chainID, user[0])
  95. return tx
  96. }
  97. //-------------------------------------------------------------------------------
  98. // rpc call wrappers (fail on err)
  99. // get an account's nonce
  100. func getNonce(t *testing.T, typ string, addr []byte) int {
  101. client := clients[typ]
  102. ac, err := client.GetAccount(addr)
  103. if err != nil {
  104. t.Fatal(err)
  105. }
  106. if ac == nil {
  107. return 0
  108. }
  109. return ac.Sequence
  110. }
  111. // get the account
  112. func getAccount(t *testing.T, typ string, addr []byte) *account.Account {
  113. client := clients[typ]
  114. ac, err := client.GetAccount(addr)
  115. if err != nil {
  116. t.Fatal(err)
  117. }
  118. return ac
  119. }
  120. // sign transaction
  121. func signTx(t *testing.T, typ string, tx types.Tx, privAcc *account.PrivAccount) types.Tx {
  122. client := clients[typ]
  123. signedTx, err := client.SignTx(tx, []*account.PrivAccount{privAcc})
  124. if err != nil {
  125. t.Fatal(err)
  126. }
  127. return signedTx
  128. }
  129. // broadcast transaction
  130. func broadcastTx(t *testing.T, typ string, tx types.Tx) *ctypes.Receipt {
  131. client := clients[typ]
  132. rec, err := client.BroadcastTx(tx)
  133. if err != nil {
  134. t.Fatal(err)
  135. }
  136. mempoolCount += 1
  137. return rec
  138. }
  139. // dump all storage for an account. currently unused
  140. func dumpStorage(t *testing.T, addr []byte) ctypes.ResponseDumpStorage {
  141. client := clients["HTTP"]
  142. resp, err := client.DumpStorage(addr)
  143. if err != nil {
  144. t.Fatal(err)
  145. }
  146. return *resp
  147. }
  148. func getStorage(t *testing.T, typ string, addr, key []byte) []byte {
  149. client := clients[typ]
  150. resp, err := client.GetStorage(addr, key)
  151. if err != nil {
  152. t.Fatal(err)
  153. }
  154. return resp.Value
  155. }
  156. func callCode(t *testing.T, client cclient.Client, code, data, expected []byte) {
  157. resp, err := client.CallCode(code, data)
  158. if err != nil {
  159. t.Fatal(err)
  160. }
  161. ret := resp.Return
  162. // NOTE: we don't flip memory when it comes out of RETURN (?!)
  163. if bytes.Compare(ret, LeftPadWord256(expected).Bytes()) != 0 {
  164. t.Fatalf("Conflicting return value. Got %x, expected %x", ret, expected)
  165. }
  166. }
  167. func callContract(t *testing.T, client cclient.Client, address, data, expected []byte) {
  168. resp, err := client.Call(address, data)
  169. if err != nil {
  170. t.Fatal(err)
  171. }
  172. ret := resp.Return
  173. // NOTE: we don't flip memory when it comes out of RETURN (?!)
  174. if bytes.Compare(ret, LeftPadWord256(expected).Bytes()) != 0 {
  175. t.Fatalf("Conflicting return value. Got %x, expected %x", ret, expected)
  176. }
  177. }
  178. // get the namereg entry
  179. func getNameRegEntry(t *testing.T, typ string, name string) *types.NameRegEntry {
  180. client := clients[typ]
  181. entry, err := client.GetName(name)
  182. if err != nil {
  183. t.Fatal(err)
  184. }
  185. return entry
  186. }
  187. //--------------------------------------------------------------------------------
  188. // utility verification function
  189. func checkTx(t *testing.T, fromAddr []byte, priv *account.PrivAccount, tx *types.SendTx) {
  190. if bytes.Compare(tx.Inputs[0].Address, fromAddr) != 0 {
  191. t.Fatal("Tx input addresses don't match!")
  192. }
  193. signBytes := account.SignBytes(chainID, tx)
  194. in := tx.Inputs[0] //(*types.SendTx).Inputs[0]
  195. if err := in.ValidateBasic(); err != nil {
  196. t.Fatal(err)
  197. }
  198. // Check signatures
  199. // acc := getAccount(t, byteAddr)
  200. // NOTE: using the acc here instead of the in fails; it is nil.
  201. if !in.PubKey.VerifyBytes(signBytes, in.Signature) {
  202. t.Fatal(types.ErrTxInvalidSignature)
  203. }
  204. }
  205. // simple contract returns 5 + 6 = 0xb
  206. func simpleContract() ([]byte, []byte, []byte) {
  207. // this is the code we want to run when the contract is called
  208. contractCode := []byte{0x60, 0x5, 0x60, 0x6, 0x1, 0x60, 0x0, 0x52, 0x60, 0x20, 0x60, 0x0, 0xf3}
  209. // the is the code we need to return the contractCode when the contract is initialized
  210. lenCode := len(contractCode)
  211. // push code to the stack
  212. //code := append([]byte{byte(0x60 + lenCode - 1)}, RightPadWord256(contractCode).Bytes()...)
  213. code := append([]byte{0x7f}, RightPadWord256(contractCode).Bytes()...)
  214. // store it in memory
  215. code = append(code, []byte{0x60, 0x0, 0x52}...)
  216. // return whats in memory
  217. //code = append(code, []byte{0x60, byte(32 - lenCode), 0x60, byte(lenCode), 0xf3}...)
  218. code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...)
  219. // return init code, contract code, expected return
  220. return code, contractCode, LeftPadBytes([]byte{0xb}, 32)
  221. }
  222. // simple call contract calls another contract
  223. func simpleCallContract(addr []byte) ([]byte, []byte, []byte) {
  224. gas1, gas2 := byte(0x1), byte(0x1)
  225. value := byte(0x1)
  226. inOff, inSize := byte(0x0), byte(0x0) // no call data
  227. retOff, retSize := byte(0x0), byte(0x20)
  228. // this is the code we want to run (call a contract and return)
  229. contractCode := []byte{0x60, retSize, 0x60, retOff, 0x60, inSize, 0x60, inOff, 0x60, value, 0x73}
  230. contractCode = append(contractCode, addr...)
  231. contractCode = append(contractCode, []byte{0x61, gas1, gas2, 0xf1, 0x60, 0x20, 0x60, 0x0, 0xf3}...)
  232. // the is the code we need to return; the contractCode when the contract is initialized
  233. // it should copy the code from the input into memory
  234. lenCode := len(contractCode)
  235. memOff := byte(0x0)
  236. inOff = byte(0xc) // length of code before codeContract
  237. length := byte(lenCode)
  238. code := []byte{0x60, length, 0x60, inOff, 0x60, memOff, 0x37}
  239. // return whats in memory
  240. code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...)
  241. code = append(code, contractCode...)
  242. // return init code, contract code, expected return
  243. return code, contractCode, LeftPadBytes([]byte{0xb}, 32)
  244. }