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.

281 lines
8.3 KiB

9 years ago
9 years ago
9 years ago
10 years ago
  1. package rpctest
  2. import (
  3. "bytes"
  4. "fmt"
  5. . "github.com/tendermint/tendermint/common"
  6. "github.com/tendermint/tendermint/types"
  7. "testing"
  8. )
  9. var doNothing = func(eid string, b []byte) error { return nil }
  10. func testStatus(t *testing.T, typ string) {
  11. client := clients[typ]
  12. resp, err := client.Status()
  13. if err != nil {
  14. t.Fatal(err)
  15. }
  16. if resp.NodeInfo.ChainID != chainID {
  17. t.Fatal(fmt.Errorf("ChainID mismatch: got %s expected %s",
  18. resp.NodeInfo.ChainID, chainID))
  19. }
  20. }
  21. func testGenPriv(t *testing.T, typ string) {
  22. client := clients[typ]
  23. privAcc, err := client.GenPrivAccount()
  24. if err != nil {
  25. t.Fatal(err)
  26. }
  27. if len(privAcc.PrivAccount.Address) == 0 {
  28. t.Fatal("Failed to generate an address")
  29. }
  30. }
  31. func testGetAccount(t *testing.T, typ string) {
  32. acc := getAccount(t, typ, user[0].Address)
  33. if acc == nil {
  34. t.Fatalf("Account was nil")
  35. }
  36. if bytes.Compare(acc.Address, user[0].Address) != 0 {
  37. t.Fatalf("Failed to get correct account. Got %x, expected %x", acc.Address, user[0].Address)
  38. }
  39. }
  40. func testSignedTx(t *testing.T, typ string) {
  41. amt := int64(100)
  42. toAddr := user[1].Address
  43. testOneSignTx(t, typ, toAddr, amt)
  44. toAddr = user[2].Address
  45. testOneSignTx(t, typ, toAddr, amt)
  46. toAddr = user[3].Address
  47. testOneSignTx(t, typ, toAddr, amt)
  48. }
  49. func testOneSignTx(t *testing.T, typ string, addr []byte, amt int64) {
  50. tx := makeDefaultSendTx(t, typ, addr, amt)
  51. tx2 := signTx(t, typ, tx, user[0])
  52. tx2hash := types.TxID(chainID, tx2)
  53. tx.SignInput(chainID, 0, user[0])
  54. txhash := types.TxID(chainID, tx)
  55. if bytes.Compare(txhash, tx2hash) != 0 {
  56. t.Fatal("Got different signatures for signing via rpc vs tx_utils")
  57. }
  58. tx_ := signTx(t, typ, tx, user[0])
  59. tx = tx_.(*types.SendTx)
  60. checkTx(t, user[0].Address, user[0], tx)
  61. }
  62. func testBroadcastTx(t *testing.T, typ string) {
  63. amt := int64(100)
  64. toAddr := user[1].Address
  65. tx := makeDefaultSendTxSigned(t, typ, toAddr, amt)
  66. receipt := broadcastTx(t, typ, tx)
  67. if receipt.CreatesContract > 0 {
  68. t.Fatal("This tx does not create a contract")
  69. }
  70. if len(receipt.TxHash) == 0 {
  71. t.Fatal("Failed to compute tx hash")
  72. }
  73. pool := node.MempoolReactor().Mempool
  74. txs := pool.GetProposalTxs()
  75. if len(txs) != mempoolCount {
  76. t.Fatalf("The mem pool has %d txs. Expected %d", len(txs), mempoolCount)
  77. }
  78. tx2 := txs[mempoolCount-1].(*types.SendTx)
  79. n, err := new(int64), new(error)
  80. buf1, buf2 := new(bytes.Buffer), new(bytes.Buffer)
  81. tx.WriteSignBytes(chainID, buf1, n, err)
  82. tx2.WriteSignBytes(chainID, buf2, n, err)
  83. if bytes.Compare(buf1.Bytes(), buf2.Bytes()) != 0 {
  84. t.Fatal("inconsistent hashes for mempool tx and sent tx")
  85. }
  86. }
  87. func testGetStorage(t *testing.T, typ string) {
  88. con := newWSCon(t)
  89. eid := types.EventStringNewBlock()
  90. subscribe(t, con, eid)
  91. defer func() {
  92. unsubscribe(t, con, eid)
  93. con.Close()
  94. }()
  95. amt, gasLim, fee := int64(1100), int64(1000), int64(1000)
  96. code := []byte{0x60, 0x5, 0x60, 0x1, 0x55}
  97. tx := makeDefaultCallTx(t, typ, nil, code, amt, gasLim, fee)
  98. receipt := broadcastTx(t, typ, tx)
  99. if receipt.CreatesContract == 0 {
  100. t.Fatal("This tx creates a contract")
  101. }
  102. if len(receipt.TxHash) == 0 {
  103. t.Fatal("Failed to compute tx hash")
  104. }
  105. contractAddr := receipt.ContractAddr
  106. if len(contractAddr) == 0 {
  107. t.Fatal("Creates contract but resulting address is empty")
  108. }
  109. // allow it to get mined
  110. waitForEvent(t, con, eid, true, func() {}, doNothing)
  111. mempoolCount = 0
  112. v := getStorage(t, typ, contractAddr, []byte{0x1})
  113. got := LeftPadWord256(v)
  114. expected := LeftPadWord256([]byte{0x5})
  115. if got.Compare(expected) != 0 {
  116. t.Fatalf("Wrong storage value. Got %x, expected %x", got.Bytes(), expected.Bytes())
  117. }
  118. }
  119. func testCallCode(t *testing.T, typ string) {
  120. client := clients[typ]
  121. // add two integers and return the result
  122. code := []byte{0x60, 0x5, 0x60, 0x6, 0x1, 0x60, 0x0, 0x52, 0x60, 0x20, 0x60, 0x0, 0xf3}
  123. data := []byte{}
  124. expected := []byte{0xb}
  125. callCode(t, client, user[0].PubKey.Address(), code, data, expected)
  126. // pass two ints as calldata, add, and return the result
  127. code = []byte{0x60, 0x0, 0x35, 0x60, 0x20, 0x35, 0x1, 0x60, 0x0, 0x52, 0x60, 0x20, 0x60, 0x0, 0xf3}
  128. data = append(LeftPadWord256([]byte{0x5}).Bytes(), LeftPadWord256([]byte{0x6}).Bytes()...)
  129. expected = []byte{0xb}
  130. callCode(t, client, user[0].PubKey.Address(), code, data, expected)
  131. }
  132. func testCall(t *testing.T, typ string) {
  133. con := newWSCon(t)
  134. eid := types.EventStringNewBlock()
  135. subscribe(t, con, eid)
  136. defer func() {
  137. unsubscribe(t, con, eid)
  138. con.Close()
  139. }()
  140. client := clients[typ]
  141. // create the contract
  142. amt, gasLim, fee := int64(6969), int64(1000), int64(1000)
  143. code, _, _ := simpleContract()
  144. tx := makeDefaultCallTx(t, typ, nil, code, amt, gasLim, fee)
  145. receipt := broadcastTx(t, typ, tx)
  146. if receipt.CreatesContract == 0 {
  147. t.Fatal("This tx creates a contract")
  148. }
  149. if len(receipt.TxHash) == 0 {
  150. t.Fatal("Failed to compute tx hash")
  151. }
  152. contractAddr := receipt.ContractAddr
  153. if len(contractAddr) == 0 {
  154. t.Fatal("Creates contract but resulting address is empty")
  155. }
  156. // allow it to get mined
  157. waitForEvent(t, con, eid, true, func() {}, doNothing)
  158. mempoolCount = 0
  159. // run a call through the contract
  160. data := []byte{}
  161. expected := []byte{0xb}
  162. callContract(t, client, user[0].PubKey.Address(), contractAddr, data, expected)
  163. }
  164. func testNameReg(t *testing.T, typ string) {
  165. client := clients[typ]
  166. con := newWSCon(t)
  167. types.MinNameRegistrationPeriod = 1
  168. // register a new name, check if its there
  169. // since entries ought to be unique and these run against different clients, we append the typ
  170. name := "ye_old_domain_name_" + typ
  171. data := "if not now, when"
  172. fee := int64(1000)
  173. numDesiredBlocks := int64(2)
  174. amt := fee + numDesiredBlocks*types.NameCostPerByte*types.NameCostPerBlock*types.BaseEntryCost(name, data)
  175. eid := types.EventStringNameReg(name)
  176. subscribe(t, con, eid)
  177. tx := makeDefaultNameTx(t, typ, name, data, amt, fee)
  178. broadcastTx(t, typ, tx)
  179. // verify the name by both using the event and by checking get_name
  180. waitForEvent(t, con, eid, true, func() {}, func(eid string, b []byte) error {
  181. // TODO: unmarshal the response
  182. tx, err := unmarshalResponseNameReg(b)
  183. if err != nil {
  184. return err
  185. }
  186. if tx.Name != name {
  187. t.Fatal(fmt.Sprintf("Err on received event tx.Name: Got %s, expected %s", tx.Name, name))
  188. }
  189. if tx.Data != data {
  190. t.Fatal(fmt.Sprintf("Err on received event tx.Data: Got %s, expected %s", tx.Data, data))
  191. }
  192. return nil
  193. })
  194. mempoolCount = 0
  195. entry := getNameRegEntry(t, typ, name)
  196. if entry.Data != data {
  197. t.Fatal(fmt.Sprintf("Err on entry.Data: Got %s, expected %s", entry.Data, data))
  198. }
  199. if bytes.Compare(entry.Owner, user[0].Address) != 0 {
  200. t.Fatal(fmt.Sprintf("Err on entry.Owner: Got %s, expected %s", entry.Owner, user[0].Address))
  201. }
  202. unsubscribe(t, con, eid)
  203. // for the rest we just use new block event
  204. // since we already tested the namereg event
  205. eid = types.EventStringNewBlock()
  206. subscribe(t, con, eid)
  207. defer func() {
  208. unsubscribe(t, con, eid)
  209. con.Close()
  210. }()
  211. // update the data as the owner, make sure still there
  212. numDesiredBlocks = int64(2)
  213. data = "these are amongst the things I wish to bestow upon the youth of generations come: a safe supply of honey, and a better money. For what else shall they need"
  214. amt = fee + numDesiredBlocks*types.NameCostPerByte*types.NameCostPerBlock*types.BaseEntryCost(name, data)
  215. tx = makeDefaultNameTx(t, typ, name, data, amt, fee)
  216. broadcastTx(t, typ, tx)
  217. // commit block
  218. waitForEvent(t, con, eid, true, func() {}, doNothing)
  219. mempoolCount = 0
  220. entry = getNameRegEntry(t, typ, name)
  221. if entry.Data != data {
  222. t.Fatal(fmt.Sprintf("Err on entry.Data: Got %s, expected %s", entry.Data, data))
  223. }
  224. // try to update as non owner, should fail
  225. nonce := getNonce(t, typ, user[1].Address)
  226. data2 := "this is not my beautiful house"
  227. tx = types.NewNameTxWithNonce(user[1].PubKey, name, data2, amt, fee, nonce+1)
  228. tx.Sign(chainID, user[1])
  229. _, err := client.BroadcastTx(tx)
  230. if err == nil {
  231. t.Fatal("Expected error on NameTx")
  232. }
  233. // commit block
  234. waitForEvent(t, con, eid, true, func() {}, doNothing)
  235. // now the entry should be expired, so we can update as non owner
  236. _, err = client.BroadcastTx(tx)
  237. waitForEvent(t, con, eid, true, func() {}, doNothing)
  238. mempoolCount = 0
  239. entry = getNameRegEntry(t, typ, name)
  240. if entry.Data != data2 {
  241. t.Fatal(fmt.Sprintf("Error on entry.Data: Got %s, expected %s", entry.Data, data2))
  242. }
  243. if bytes.Compare(entry.Owner, user[1].Address) != 0 {
  244. t.Fatal(fmt.Sprintf("Err on entry.Owner: Got %s, expected %s", entry.Owner, user[1].Address))
  245. }
  246. }