responses_test.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. package rpc
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "math/big"
  6. "regexp"
  7. "testing"
  8. "github.com/ethereum/go-ethereum/common"
  9. "github.com/ethereum/go-ethereum/core/state"
  10. "github.com/ethereum/go-ethereum/core/types"
  11. )
  12. const (
  13. reHash = `"0x[0-9a-f]{64}"` // 32 bytes
  14. reHashOpt = `"(0x[0-9a-f]{64})"|null` // 32 bytes or null
  15. reAddress = `"0x[0-9a-f]{40}"` // 20 bytes
  16. reAddressOpt = `"0x[0-9a-f]{40}"|null` // 20 bytes or null
  17. reNum = `"0x([1-9a-f][0-9a-f]{0,15})|0"` // must not have left-padded zeros
  18. reNumNonZero = `"0x([1-9a-f][0-9a-f]{0,15})"` // non-zero required must not have left-padded zeros
  19. reNumOpt = `"0x([1-9a-f][0-9a-f]{0,15})|0"|null` // must not have left-padded zeros or null
  20. reData = `"0x[0-9a-f]*"` // can be "empty"
  21. // reListHash = `[("\w":"0x[0-9a-f]{64}",?)*]`
  22. // reListObj = `[("\w":(".+"|null),?)*]`
  23. )
  24. func TestNewBlockRes(t *testing.T) {
  25. tests := map[string]string{
  26. "number": reNum,
  27. "hash": reHash,
  28. "parentHash": reHash,
  29. "nonce": reData,
  30. "sha3Uncles": reHash,
  31. "logsBloom": reData,
  32. "transactionsRoot": reHash,
  33. "stateRoot": reHash,
  34. "miner": reAddress,
  35. "difficulty": `"0x1"`,
  36. "totalDifficulty": reNum,
  37. "size": reNumNonZero,
  38. "extraData": reData,
  39. "gasLimit": reNum,
  40. // "minGasPrice": "0x",
  41. "gasUsed": reNum,
  42. "timestamp": reNum,
  43. // "transactions": reListHash,
  44. // "uncles": reListHash,
  45. }
  46. block := makeBlock()
  47. v := NewBlockRes(block, false)
  48. j, _ := json.Marshal(v)
  49. for k, re := range tests {
  50. match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j))
  51. if !match {
  52. t.Error(fmt.Sprintf("%s output json does not match format %s. Got %s", k, re, j))
  53. }
  54. }
  55. }
  56. func TestNewBlockResTxFull(t *testing.T) {
  57. tests := map[string]string{
  58. "number": reNum,
  59. "hash": reHash,
  60. "parentHash": reHash,
  61. "nonce": reData,
  62. "sha3Uncles": reHash,
  63. "logsBloom": reData,
  64. "transactionsRoot": reHash,
  65. "stateRoot": reHash,
  66. "miner": reAddress,
  67. "difficulty": `"0x1"`,
  68. "totalDifficulty": reNum,
  69. "size": reNumNonZero,
  70. "extraData": reData,
  71. "gasLimit": reNum,
  72. // "minGasPrice": "0x",
  73. "gasUsed": reNum,
  74. "timestamp": reNum,
  75. // "transactions": reListHash,
  76. // "uncles": reListHash,
  77. }
  78. block := makeBlock()
  79. v := NewBlockRes(block, true)
  80. j, _ := json.Marshal(v)
  81. for k, re := range tests {
  82. match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j))
  83. if !match {
  84. t.Error(fmt.Sprintf("%s output json does not match format %s. Got %s", k, re, j))
  85. }
  86. }
  87. }
  88. func TestBlockNil(t *testing.T) {
  89. var block *types.Block
  90. block = nil
  91. u := NewBlockRes(block, false)
  92. j, _ := json.Marshal(u)
  93. if string(j) != "null" {
  94. t.Errorf("Expected null but got %v", string(j))
  95. }
  96. }
  97. func TestNewTransactionRes(t *testing.T) {
  98. to := common.HexToAddress("0x02")
  99. amount := big.NewInt(1)
  100. gasAmount := big.NewInt(1)
  101. gasPrice := big.NewInt(1)
  102. data := []byte{1, 2, 3}
  103. tx := types.NewTransactionMessage(to, amount, gasAmount, gasPrice, data)
  104. tests := map[string]string{
  105. "hash": reHash,
  106. "nonce": reNum,
  107. "blockHash": reHashOpt,
  108. "blockNum": reNumOpt,
  109. "transactionIndex": reNumOpt,
  110. "from": reAddress,
  111. "to": reAddressOpt,
  112. "value": reNum,
  113. "gas": reNum,
  114. "gasPrice": reNum,
  115. "input": reData,
  116. }
  117. v := NewTransactionRes(tx)
  118. v.BlockHash = newHexData(common.HexToHash("0x030201"))
  119. v.BlockNumber = newHexNum(5)
  120. v.TxIndex = newHexNum(0)
  121. j, _ := json.Marshal(v)
  122. for k, re := range tests {
  123. match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j))
  124. if !match {
  125. t.Error(fmt.Sprintf("`%s` output json does not match format %s. Source %s", k, re, j))
  126. }
  127. }
  128. }
  129. func TestTransactionNil(t *testing.T) {
  130. var tx *types.Transaction
  131. tx = nil
  132. u := NewTransactionRes(tx)
  133. j, _ := json.Marshal(u)
  134. if string(j) != "null" {
  135. t.Errorf("Expected null but got %v", string(j))
  136. }
  137. }
  138. func TestNewUncleRes(t *testing.T) {
  139. header := makeHeader()
  140. u := NewUncleRes(header)
  141. tests := map[string]string{
  142. "number": reNum,
  143. "hash": reHash,
  144. "parentHash": reHash,
  145. "nonce": reData,
  146. "sha3Uncles": reHash,
  147. "receiptHash": reHash,
  148. "transactionsRoot": reHash,
  149. "stateRoot": reHash,
  150. "miner": reAddress,
  151. "difficulty": reNum,
  152. "extraData": reData,
  153. "gasLimit": reNum,
  154. "gasUsed": reNum,
  155. "timestamp": reNum,
  156. }
  157. j, _ := json.Marshal(u)
  158. for k, re := range tests {
  159. match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j))
  160. if !match {
  161. t.Error(fmt.Sprintf("`%s` output json does not match format %s. Source %s", k, re, j))
  162. }
  163. }
  164. }
  165. func TestUncleNil(t *testing.T) {
  166. var header *types.Header
  167. header = nil
  168. u := NewUncleRes(header)
  169. j, _ := json.Marshal(u)
  170. if string(j) != "null" {
  171. t.Errorf("Expected null but got %v", string(j))
  172. }
  173. }
  174. func TestNewLogRes(t *testing.T) {
  175. log := makeStateLog(0)
  176. tests := map[string]string{
  177. "address": reAddress,
  178. // "topics": "[.*]"
  179. "data": reData,
  180. "blockNumber": reNum,
  181. // "hash": reHash,
  182. // "logIndex": reNum,
  183. // "blockHash": reHash,
  184. // "transactionHash": reHash,
  185. "transactionIndex": reNum,
  186. }
  187. v := NewLogRes(log)
  188. j, _ := json.Marshal(v)
  189. for k, re := range tests {
  190. match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j))
  191. if !match {
  192. t.Error(fmt.Sprintf("`%s` output json does not match format %s. Got %s", k, re, j))
  193. }
  194. }
  195. }
  196. func TestNewLogsRes(t *testing.T) {
  197. logs := make([]*state.Log, 3)
  198. logs[0] = makeStateLog(1)
  199. logs[1] = makeStateLog(2)
  200. logs[2] = makeStateLog(3)
  201. tests := map[string]string{}
  202. v := NewLogsRes(logs)
  203. j, _ := json.Marshal(v)
  204. for k, re := range tests {
  205. match, _ := regexp.MatchString(fmt.Sprintf(`[{.*"%s":%s.*}]`, k, re), string(j))
  206. if !match {
  207. t.Error(fmt.Sprintf("%s output json does not match format %s. Got %s", k, re, j))
  208. }
  209. }
  210. }
  211. func makeStateLog(num int) *state.Log {
  212. address := common.HexToAddress("0x0")
  213. data := []byte{1, 2, 3}
  214. number := uint64(num)
  215. topics := make([]common.Hash, 3)
  216. topics = append(topics, common.HexToHash("0x00"))
  217. topics = append(topics, common.HexToHash("0x10"))
  218. topics = append(topics, common.HexToHash("0x20"))
  219. log := state.NewLog(address, topics, data, number)
  220. return log
  221. }
  222. func makeHeader() *types.Header {
  223. header := &types.Header{
  224. ParentHash: common.StringToHash("0x00"),
  225. UncleHash: common.StringToHash("0x00"),
  226. Coinbase: common.StringToAddress("0x00"),
  227. Root: common.StringToHash("0x00"),
  228. TxHash: common.StringToHash("0x00"),
  229. ReceiptHash: common.StringToHash("0x00"),
  230. // Bloom:
  231. Difficulty: big.NewInt(88888888),
  232. Number: big.NewInt(16),
  233. GasLimit: big.NewInt(70000),
  234. GasUsed: big.NewInt(25000),
  235. Time: 124356789,
  236. Extra: nil,
  237. MixDigest: common.StringToHash("0x00"),
  238. Nonce: [8]byte{0, 1, 2, 3, 4, 5, 6, 7},
  239. }
  240. return header
  241. }
  242. func makeBlock() *types.Block {
  243. parentHash := common.HexToHash("0x01")
  244. coinbase := common.HexToAddress("0x01")
  245. root := common.HexToHash("0x01")
  246. difficulty := common.Big1
  247. nonce := uint64(1)
  248. block := types.NewBlock(parentHash, coinbase, root, difficulty, nonce, nil)
  249. txto := common.HexToAddress("0x02")
  250. txamount := big.NewInt(1)
  251. txgasAmount := big.NewInt(1)
  252. txgasPrice := big.NewInt(1)
  253. txdata := []byte{1, 2, 3}
  254. tx := types.NewTransactionMessage(txto, txamount, txgasAmount, txgasPrice, txdata)
  255. txs := make([]*types.Transaction, 1)
  256. txs[0] = tx
  257. block.SetTransactions(txs)
  258. uncles := make([]*types.Header, 1)
  259. uncles[0] = makeHeader()
  260. block.SetUncles(uncles)
  261. return block
  262. }