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.

326 lines
9.6 KiB

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