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

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package rpctest
  2. import (
  3. "bytes"
  4. "strconv"
  5. "testing"
  6. acm "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) []*acm.PrivAccount {
  32. accounts := []*acm.PrivAccount{}
  33. for i := 0; i < n; i++ {
  34. secret := []byte("mysecret" + strconv.Itoa(i))
  35. user := acm.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: acm.PubKeyEd25519(user[0].PubKey.(acm.PubKeyEd25519)),
  61. PrivKey: acm.PrivKeyEd25519(user[0].PrivKey.(acm.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) *acm.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 *acm.PrivAccount) types.Tx {
  122. client := clients[typ]
  123. signedTx, err := client.SignTx(tx, []*acm.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 *acm.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 := acm.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. }