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.

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