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

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. "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. }