296 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			296 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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) {
 | |
| 	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,
 | |
| 	}
 | |
| 
 | |
| 	block := makeBlock()
 | |
| 	v := NewBlockRes(block, false)
 | |
| 	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 TestNewBlockResTxFull(t *testing.T) {
 | |
| 	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,
 | |
| 	}
 | |
| 
 | |
| 	block := makeBlock()
 | |
| 	v := NewBlockRes(block, true)
 | |
| 	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 TestBlockNil(t *testing.T) {
 | |
| 	var block *types.Block
 | |
| 	block = nil
 | |
| 	u := NewBlockRes(block, false)
 | |
| 	j, _ := json.Marshal(u)
 | |
| 	if string(j) != "null" {
 | |
| 		t.Errorf("Expected null but got %v", string(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 TestTransactionNil(t *testing.T) {
 | |
| 	var tx *types.Transaction
 | |
| 	tx = nil
 | |
| 	u := NewTransactionRes(tx)
 | |
| 	j, _ := json.Marshal(u)
 | |
| 	if string(j) != "null" {
 | |
| 		t.Errorf("Expected null but got %v", string(j))
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestNewUncleRes(t *testing.T) {
 | |
| 	header := makeHeader()
 | |
| 	u := NewUncleRes(header)
 | |
| 	tests := map[string]string{
 | |
| 		"number":           reNum,
 | |
| 		"hash":             reHash,
 | |
| 		"parentHash":       reHash,
 | |
| 		"nonce":            reData,
 | |
| 		"sha3Uncles":       reHash,
 | |
| 		"receiptHash":      reHash,
 | |
| 		"transactionsRoot": reHash,
 | |
| 		"stateRoot":        reHash,
 | |
| 		"miner":            reAddress,
 | |
| 		"difficulty":       reNum,
 | |
| 		"extraData":        reData,
 | |
| 		"gasLimit":         reNum,
 | |
| 		"gasUsed":          reNum,
 | |
| 		"timestamp":        reNum,
 | |
| 	}
 | |
| 
 | |
| 	j, _ := json.Marshal(u)
 | |
| 	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 TestUncleNil(t *testing.T) {
 | |
| 	var header *types.Header
 | |
| 	header = nil
 | |
| 	u := NewUncleRes(header)
 | |
| 	j, _ := json.Marshal(u)
 | |
| 	if string(j) != "null" {
 | |
| 		t.Errorf("Expected null but got %v", string(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
 | |
| }
 | |
| 
 | |
| func makeHeader() *types.Header {
 | |
| 	header := &types.Header{
 | |
| 		ParentHash:  common.StringToHash("0x00"),
 | |
| 		UncleHash:   common.StringToHash("0x00"),
 | |
| 		Coinbase:    common.StringToAddress("0x00"),
 | |
| 		Root:        common.StringToHash("0x00"),
 | |
| 		TxHash:      common.StringToHash("0x00"),
 | |
| 		ReceiptHash: common.StringToHash("0x00"),
 | |
| 		// Bloom:
 | |
| 		Difficulty: big.NewInt(88888888),
 | |
| 		Number:     big.NewInt(16),
 | |
| 		GasLimit:   big.NewInt(70000),
 | |
| 		GasUsed:    big.NewInt(25000),
 | |
| 		Time:       124356789,
 | |
| 		Extra:      nil,
 | |
| 		MixDigest:  common.StringToHash("0x00"),
 | |
| 		Nonce:      [8]byte{0, 1, 2, 3, 4, 5, 6, 7},
 | |
| 	}
 | |
| 	return header
 | |
| }
 | |
| 
 | |
| func makeBlock() *types.Block {
 | |
| 	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)
 | |
| 
 | |
| 	txto := common.HexToAddress("0x02")
 | |
| 	txamount := big.NewInt(1)
 | |
| 	txgasAmount := big.NewInt(1)
 | |
| 	txgasPrice := big.NewInt(1)
 | |
| 	txdata := []byte{1, 2, 3}
 | |
| 
 | |
| 	tx := types.NewTransactionMessage(txto, txamount, txgasAmount, txgasPrice, txdata)
 | |
| 	txs := make([]*types.Transaction, 1)
 | |
| 	txs[0] = tx
 | |
| 	block.SetTransactions(txs)
 | |
| 
 | |
| 	uncles := make([]*types.Header, 1)
 | |
| 	uncles[0] = makeHeader()
 | |
| 	block.SetUncles(uncles)
 | |
| 
 | |
| 	return block
 | |
| }
 |