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.

312 lines
9.1 KiB

  1. package rpctest
  2. import (
  3. "bytes"
  4. "encoding/hex"
  5. "github.com/tendermint/tendermint/account"
  6. . "github.com/tendermint/tendermint/common"
  7. "github.com/tendermint/tendermint/consensus"
  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. "testing"
  15. "time"
  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. userAddr = "1D7A91CB32F758A02EBB9BE1FB6F8DEE56F90D42"
  25. userPriv = "C453604BD6480D5538B4C6FD2E3E314B5BCE518D75ADE4DA3DA85AB8ADFD819606FBAC4E285285D1D91FCBC7E91C780ADA11516F67462340B3980CE2B94940E8"
  26. userPub = "06FBAC4E285285D1D91FCBC7E91C780ADA11516F67462340B3980CE2B94940E8"
  27. userByteAddr, userBytePriv = initUserBytes()
  28. clients = map[string]cclient.Client{
  29. "JSONRPC": cclient.NewClient(requestAddr, "JSONRPC"),
  30. "HTTP": cclient.NewClient(requestAddr, "HTTP"),
  31. }
  32. )
  33. // returns byte versions of address and private key
  34. // type [64]byte needed by account.GenPrivAccountFromKey
  35. func initUserBytes() ([]byte, [64]byte) {
  36. byteAddr, _ := hex.DecodeString(userAddr)
  37. var byteKey [64]byte
  38. userPrivByteSlice, _ := hex.DecodeString(userPriv)
  39. copy(byteKey[:], userPrivByteSlice)
  40. return byteAddr, byteKey
  41. }
  42. func decodeHex(hexStr string) []byte {
  43. bytes, err := hex.DecodeString(hexStr)
  44. if err != nil {
  45. panic(err)
  46. }
  47. return bytes
  48. }
  49. // create a new node and sleep forever
  50. func newNode(ready chan struct{}) {
  51. // Create & start node
  52. node = nm.NewNode()
  53. l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), false)
  54. node.AddListener(l)
  55. node.Start()
  56. // Run the RPC server.
  57. node.StartRPC()
  58. ready <- struct{}{}
  59. // Sleep forever
  60. ch := make(chan struct{})
  61. <-ch
  62. }
  63. // initialize config and create new node
  64. func init() {
  65. // Save new priv_validator file.
  66. priv := &state.PrivValidator{
  67. Address: decodeHex(userAddr),
  68. PubKey: account.PubKeyEd25519(decodeHex(userPub)),
  69. PrivKey: account.PrivKeyEd25519(decodeHex(userPriv)),
  70. }
  71. priv.SetFile(config.GetString("priv_validator_file"))
  72. priv.Save()
  73. consensus.RoundDuration0 = 3 * time.Second
  74. consensus.RoundDurationDelta = 1 * time.Second
  75. // start a node
  76. ready := make(chan struct{})
  77. go newNode(ready)
  78. <-ready
  79. }
  80. //-------------------------------------------------------------------------------
  81. // make transactions
  82. // make a send tx (uses get account to figure out the nonce)
  83. func makeSendTx(t *testing.T, typ string, from, to []byte, amt uint64) *types.SendTx {
  84. acc := getAccount(t, typ, from)
  85. nonce := 0
  86. if acc != nil {
  87. nonce = int(acc.Sequence) + 1
  88. }
  89. bytePub, err := hex.DecodeString(userPub)
  90. if err != nil {
  91. t.Fatal(err)
  92. }
  93. tx := &types.SendTx{
  94. Inputs: []*types.TxInput{
  95. &types.TxInput{
  96. Address: from,
  97. Amount: amt,
  98. Sequence: uint(nonce),
  99. Signature: account.SignatureEd25519{},
  100. PubKey: account.PubKeyEd25519(bytePub),
  101. },
  102. },
  103. Outputs: []*types.TxOutput{
  104. &types.TxOutput{
  105. Address: to,
  106. Amount: amt,
  107. },
  108. },
  109. }
  110. return tx
  111. }
  112. // make a call tx (uses get account to figure out the nonce)
  113. func makeCallTx(t *testing.T, typ string, from, to, data []byte, amt, gaslim, fee uint64) *types.CallTx {
  114. acc := getAccount(t, typ, from)
  115. nonce := 0
  116. if acc != nil {
  117. nonce = int(acc.Sequence) + 1
  118. }
  119. bytePub, err := hex.DecodeString(userPub)
  120. if err != nil {
  121. t.Fatal(err)
  122. }
  123. tx := &types.CallTx{
  124. Input: &types.TxInput{
  125. Address: from,
  126. Amount: amt,
  127. Sequence: uint(nonce),
  128. Signature: account.SignatureEd25519{},
  129. PubKey: account.PubKeyEd25519(bytePub),
  130. },
  131. Address: to,
  132. GasLimit: gaslim,
  133. Fee: fee,
  134. Data: data,
  135. }
  136. return tx
  137. }
  138. // make transactions
  139. //-------------------------------------------------------------------------------
  140. // rpc call wrappers
  141. // get the account
  142. func getAccount(t *testing.T, typ string, addr []byte) *account.Account {
  143. client := clients[typ]
  144. ac, err := client.GetAccount(addr)
  145. if err != nil {
  146. t.Fatal(err)
  147. }
  148. return ac.Account
  149. }
  150. // make and sign transaction
  151. func signTx(t *testing.T, typ string, fromAddr, toAddr, data []byte, key [64]byte, amt, gaslim, fee uint64) (types.Tx, *account.PrivAccount) {
  152. var tx types.Tx
  153. if data == nil {
  154. tx = makeSendTx(t, typ, fromAddr, toAddr, amt)
  155. } else {
  156. tx = makeCallTx(t, typ, fromAddr, toAddr, data, amt, gaslim, fee)
  157. }
  158. privAcc := account.GenPrivAccountFromKey(key)
  159. if bytes.Compare(privAcc.PubKey.Address(), fromAddr) != 0 {
  160. t.Fatal("Failed to generate correct priv acc")
  161. }
  162. client := clients[typ]
  163. resp, err := client.SignTx(tx, []*account.PrivAccount{privAcc})
  164. if err != nil {
  165. t.Fatal(err)
  166. }
  167. return resp.Tx, privAcc
  168. }
  169. // create, sign, and broadcast a transaction
  170. func broadcastTx(t *testing.T, typ string, fromAddr, toAddr, data []byte, key [64]byte, amt, gaslim, fee uint64) (types.Tx, ctypes.Receipt) {
  171. tx, _ := signTx(t, typ, fromAddr, toAddr, data, key, amt, gaslim, fee)
  172. client := clients[typ]
  173. resp, err := client.BroadcastTx(tx)
  174. if err != nil {
  175. t.Fatal(err)
  176. }
  177. mempoolCount += 1
  178. return tx, resp.Receipt
  179. }
  180. // dump all storage for an account. currently unused
  181. func dumpStorage(t *testing.T, addr []byte) ctypes.ResponseDumpStorage {
  182. client := clients["HTTP"]
  183. resp, err := client.DumpStorage(addr)
  184. if err != nil {
  185. t.Fatal(err)
  186. }
  187. return *resp
  188. }
  189. func getStorage(t *testing.T, typ string, addr, key []byte) []byte {
  190. client := clients[typ]
  191. resp, err := client.GetStorage(addr, key)
  192. if err != nil {
  193. t.Fatal(err)
  194. }
  195. return resp.Value
  196. }
  197. func callCode(t *testing.T, client cclient.Client, code, data, expected []byte) {
  198. resp, err := client.CallCode(code, data)
  199. if err != nil {
  200. t.Fatal(err)
  201. }
  202. ret := resp.Return
  203. // NOTE: we don't flip memory when it comes out of RETURN (?!)
  204. if bytes.Compare(ret, LeftPadWord256(expected).Bytes()) != 0 {
  205. t.Fatalf("Conflicting return value. Got %x, expected %x", ret, expected)
  206. }
  207. }
  208. func callContract(t *testing.T, client cclient.Client, address, data, expected []byte) {
  209. resp, err := client.Call(address, data)
  210. if err != nil {
  211. t.Fatal(err)
  212. }
  213. ret := resp.Return
  214. // NOTE: we don't flip memory when it comes out of RETURN (?!)
  215. if bytes.Compare(ret, LeftPadWord256(expected).Bytes()) != 0 {
  216. t.Fatalf("Conflicting return value. Got %x, expected %x", ret, expected)
  217. }
  218. }
  219. //--------------------------------------------------------------------------------
  220. // utility verification function
  221. func checkTx(t *testing.T, fromAddr []byte, priv *account.PrivAccount, tx *types.SendTx) {
  222. if bytes.Compare(tx.Inputs[0].Address, fromAddr) != 0 {
  223. t.Fatal("Tx input addresses don't match!")
  224. }
  225. signBytes := account.SignBytes(tx)
  226. in := tx.Inputs[0] //(*types.SendTx).Inputs[0]
  227. if err := in.ValidateBasic(); err != nil {
  228. t.Fatal(err)
  229. }
  230. // Check signatures
  231. // acc := getAccount(t, byteAddr)
  232. // NOTE: using the acc here instead of the in fails; it is nil.
  233. if !in.PubKey.VerifyBytes(signBytes, in.Signature) {
  234. t.Fatal(types.ErrTxInvalidSignature)
  235. }
  236. }
  237. // simple contract returns 5 + 6 = 0xb
  238. func simpleContract() ([]byte, []byte, []byte) {
  239. // this is the code we want to run when the contract is called
  240. contractCode := []byte{0x60, 0x5, 0x60, 0x6, 0x1, 0x60, 0x0, 0x52, 0x60, 0x20, 0x60, 0x0, 0xf3}
  241. // the is the code we need to return the contractCode when the contract is initialized
  242. lenCode := len(contractCode)
  243. // push code to the stack
  244. //code := append([]byte{byte(0x60 + lenCode - 1)}, RightPadWord256(contractCode).Bytes()...)
  245. code := append([]byte{0x7f}, RightPadWord256(contractCode).Bytes()...)
  246. // store it in memory
  247. code = append(code, []byte{0x60, 0x0, 0x52}...)
  248. // return whats in memory
  249. //code = append(code, []byte{0x60, byte(32 - lenCode), 0x60, byte(lenCode), 0xf3}...)
  250. code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...)
  251. // return init code, contract code, expected return
  252. return code, contractCode, LeftPadBytes([]byte{0xb}, 32)
  253. }
  254. // simple call contract calls another contract
  255. func simpleCallContract(addr []byte) ([]byte, []byte, []byte) {
  256. gas1, gas2 := byte(0x1), byte(0x1)
  257. value := byte(0x1)
  258. inOff, inSize := byte(0x0), byte(0x0) // no call data
  259. retOff, retSize := byte(0x0), byte(0x20)
  260. // this is the code we want to run (call a contract and return)
  261. contractCode := []byte{0x60, retSize, 0x60, retOff, 0x60, inSize, 0x60, inOff, 0x60, value, 0x73}
  262. contractCode = append(contractCode, addr...)
  263. contractCode = append(contractCode, []byte{0x61, gas1, gas2, 0xf1, 0x60, 0x20, 0x60, 0x0, 0xf3}...)
  264. // the is the code we need to return; the contractCode when the contract is initialized
  265. // it should copy the code from the input into memory
  266. lenCode := len(contractCode)
  267. memOff := byte(0x0)
  268. inOff = byte(0xc) // length of code before codeContract
  269. length := byte(lenCode)
  270. code := []byte{0x60, length, 0x60, inOff, 0x60, memOff, 0x37}
  271. // return whats in memory
  272. code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...)
  273. code = append(code, contractCode...)
  274. // return init code, contract code, expected return
  275. return code, contractCode, LeftPadBytes([]byte{0xb}, 32)
  276. }