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.

282 lines
8.3 KiB

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