package rpc import ( "encoding/json" "fmt" "math/big" "regexp" "testing" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" ) const ( reHash = `"0x[0-9a-f]{64}"` // 32 bytes reHashOpt = `"(0x[0-9a-f]{64})"|null` // 32 bytes or null reAddress = `"0x[0-9a-f]{40}"` // 20 bytes reAddressOpt = `"0x[0-9a-f]{40}"|null` // 20 bytes or null reNum = `"0x([1-9a-f][0-9a-f]{0,15})|0"` // must not have left-padded zeros reNumNonZero = `"0x([1-9a-f][0-9a-f]{0,15})"` // non-zero required must not have left-padded zeros reNumOpt = `"0x([1-9a-f][0-9a-f]{0,15})|0"|null` // must not have left-padded zeros or null reData = `"0x[0-9a-f]*"` // can be "empty" // reListHash = `[("\w":"0x[0-9a-f]{64}",?)*]` // reListObj = `[("\w":(".+"|null),?)*]` ) func TestNewBlockRes(t *testing.T) { parentHash := common.HexToHash("0x01") coinbase := common.HexToAddress("0x01") root := common.HexToHash("0x01") difficulty := common.Big1 nonce := uint64(1) block := types.NewBlock(parentHash, coinbase, root, difficulty, nonce, nil) tests := map[string]string{ "number": reNum, "hash": reHash, "parentHash": reHash, "nonce": reData, "sha3Uncles": reHash, "logsBloom": reData, "transactionsRoot": reHash, "stateRoot": reHash, "miner": reAddress, "difficulty": `"0x1"`, "totalDifficulty": reNum, "size": reNumNonZero, "extraData": reData, "gasLimit": reNum, // "minGasPrice": "0x", "gasUsed": reNum, "timestamp": reNum, // "transactions": reListHash, // "uncles": reListHash, } to := common.HexToAddress("0x02") amount := big.NewInt(1) gasAmount := big.NewInt(1) gasPrice := big.NewInt(1) data := []byte{1, 2, 3} tx := types.NewTransactionMessage(to, amount, gasAmount, gasPrice, data) v := NewBlockRes(block, false) v.Transactions = make([]*TransactionRes, 1) v.Transactions[0] = NewTransactionRes(tx) j, _ := json.Marshal(v) for k, re := range tests { match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j)) if !match { t.Error(fmt.Sprintf("%s output json does not match format %s. Got %s", k, re, j)) } } } func TestNewBlockResWithTrans(t *testing.T) { parentHash := common.HexToHash("0x01") coinbase := common.HexToAddress("0x01") root := common.HexToHash("0x01") difficulty := common.Big1 nonce := uint64(1) block := types.NewBlock(parentHash, coinbase, root, difficulty, nonce, nil) tests := map[string]string{ "number": reNum, "hash": reHash, "parentHash": reHash, "nonce": reData, "sha3Uncles": reHash, "logsBloom": reData, "transactionsRoot": reHash, "stateRoot": reHash, "miner": reAddress, "difficulty": `"0x1"`, "totalDifficulty": reNum, "size": reNumNonZero, "extraData": reData, "gasLimit": reNum, // "minGasPrice": "0x", "gasUsed": reNum, "timestamp": reNum, // "transactions": `[{.*}]`, // "uncles": reListHash, } to := common.HexToAddress("0x02") amount := big.NewInt(1) gasAmount := big.NewInt(1) gasPrice := big.NewInt(1) data := []byte{1, 2, 3} tx := types.NewTransactionMessage(to, amount, gasAmount, gasPrice, data) v := NewBlockRes(block, true) v.Transactions = make([]*TransactionRes, 1) v.Transactions[0] = NewTransactionRes(tx) j, _ := json.Marshal(v) for k, re := range tests { match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j)) if !match { t.Error(fmt.Sprintf("%s output json does not match format %s. Got %s", k, re, j)) } } } func TestNewTransactionRes(t *testing.T) { to := common.HexToAddress("0x02") amount := big.NewInt(1) gasAmount := big.NewInt(1) gasPrice := big.NewInt(1) data := []byte{1, 2, 3} tx := types.NewTransactionMessage(to, amount, gasAmount, gasPrice, data) tests := map[string]string{ "hash": reHash, "nonce": reNum, "blockHash": reHashOpt, "blockNum": reNumOpt, "transactionIndex": reNumOpt, "from": reAddress, "to": reAddressOpt, "value": reNum, "gas": reNum, "gasPrice": reNum, "input": reData, } v := NewTransactionRes(tx) v.BlockHash = newHexData(common.HexToHash("0x030201")) v.BlockNumber = newHexNum(5) v.TxIndex = newHexNum(0) j, _ := json.Marshal(v) for k, re := range tests { match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j)) if !match { t.Error(fmt.Sprintf("`%s` output json does not match format %s. Source %s", k, re, j)) } } } func TestNewLogRes(t *testing.T) { log := makeStateLog(0) tests := map[string]string{ "address": reAddress, // "topics": "[.*]" "data": reData, "blockNumber": reNum, // "hash": reHash, // "logIndex": reNum, // "blockHash": reHash, // "transactionHash": reHash, "transactionIndex": reNum, } v := NewLogRes(log) j, _ := json.Marshal(v) for k, re := range tests { match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j)) if !match { t.Error(fmt.Sprintf("`%s` output json does not match format %s. Got %s", k, re, j)) } } } func TestNewLogsRes(t *testing.T) { logs := make([]state.Log, 3) logs[0] = makeStateLog(1) logs[1] = makeStateLog(2) logs[2] = makeStateLog(3) tests := map[string]string{} v := NewLogsRes(logs) j, _ := json.Marshal(v) for k, re := range tests { match, _ := regexp.MatchString(fmt.Sprintf(`[{.*"%s":%s.*}]`, k, re), string(j)) if !match { t.Error(fmt.Sprintf("%s output json does not match format %s. Got %s", k, re, j)) } } } func makeStateLog(num int) state.Log { address := common.HexToAddress("0x0") data := []byte{1, 2, 3} number := uint64(num) topics := make([]common.Hash, 3) topics = append(topics, common.HexToHash("0x00")) topics = append(topics, common.HexToHash("0x10")) topics = append(topics, common.HexToHash("0x20")) log := state.NewLog(address, topics, data, number) return log }