| 
									
										
										
										
											2015-03-25 16:50:30 +01:00
										 |  |  | package rpc | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-04-01 11:38:06 +02:00
										 |  |  | 	"encoding/json" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2015-04-01 09:11:23 +02:00
										 |  |  | 	"math/big" | 
					
						
							| 
									
										
										
										
											2015-04-01 11:38:06 +02:00
										 |  |  | 	"regexp" | 
					
						
							| 
									
										
										
										
											2015-04-01 09:11:23 +02:00
										 |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2015-03-25 16:50:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:11:23 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/core/state" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/core/types" | 
					
						
							| 
									
										
										
										
											2015-03-25 16:50:30 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 11:38:06 +02:00
										 |  |  | const ( | 
					
						
							| 
									
										
										
										
											2015-04-01 15:27:14 +02:00
										 |  |  | 	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 | 
					
						
							| 
									
										
										
										
											2015-04-01 15:44:09 +02:00
										 |  |  | 	reNumNonZero = `"0x([1-9a-f][0-9a-f]{0,15})"`        // non-zero required must not have left-padded zeros | 
					
						
							| 
									
										
										
										
											2015-04-01 15:27:14 +02:00
										 |  |  | 	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" | 
					
						
							| 
									
										
										
										
											2015-04-01 16:49:07 +02:00
										 |  |  | 	// reListHash   = `[("\w":"0x[0-9a-f]{64}",?)*]` | 
					
						
							|  |  |  | 	// reListObj    = `[("\w":(".+"|null),?)*]` | 
					
						
							| 
									
										
										
										
											2015-04-01 11:38:06 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:11:23 +02:00
										 |  |  | func TestNewBlockRes(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-04-01 11:38:06 +02:00
										 |  |  | 	tests := map[string]string{ | 
					
						
							| 
									
										
										
										
											2015-04-02 12:30:22 +02:00
										 |  |  | 		"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, | 
					
						
							| 
									
										
										
										
											2015-04-01 11:38:06 +02:00
										 |  |  | 		// "minGasPrice":  "0x", | 
					
						
							|  |  |  | 		"gasUsed":   reNum, | 
					
						
							|  |  |  | 		"timestamp": reNum, | 
					
						
							| 
									
										
										
										
											2015-04-01 16:49:07 +02:00
										 |  |  | 		// "transactions": reListHash, | 
					
						
							|  |  |  | 		// "uncles":       reListHash, | 
					
						
							| 
									
										
										
										
											2015-04-01 11:38:06 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-01 09:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-04 14:08:35 +02:00
										 |  |  | 	block := makeBlock() | 
					
						
							| 
									
										
										
										
											2015-04-01 13:18:30 +02:00
										 |  |  | 	v := NewBlockRes(block, false) | 
					
						
							| 
									
										
										
										
											2015-04-01 16:49:07 +02:00
										 |  |  | 	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)) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-04 14:08:35 +02:00
										 |  |  | func TestNewBlockResTxFull(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-04-01 16:49:07 +02:00
										 |  |  | 	tests := map[string]string{ | 
					
						
							| 
									
										
										
										
											2015-04-02 12:30:22 +02:00
										 |  |  | 		"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, | 
					
						
							| 
									
										
										
										
											2015-04-01 16:49:07 +02:00
										 |  |  | 		// "minGasPrice":  "0x", | 
					
						
							|  |  |  | 		"gasUsed":   reNum, | 
					
						
							|  |  |  | 		"timestamp": reNum, | 
					
						
							| 
									
										
										
										
											2015-04-04 14:08:35 +02:00
										 |  |  | 		// "transactions": reListHash, | 
					
						
							| 
									
										
										
										
											2015-04-01 16:49:07 +02:00
										 |  |  | 		// "uncles":       reListHash, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-04 14:08:35 +02:00
										 |  |  | 	block := makeBlock() | 
					
						
							| 
									
										
										
										
											2015-04-01 16:49:07 +02:00
										 |  |  | 	v := NewBlockRes(block, true) | 
					
						
							| 
									
										
										
										
											2015-04-01 11:38:06 +02:00
										 |  |  | 	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)) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-01 09:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-04 14:08:35 +02:00
										 |  |  | 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)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:11:23 +02:00
										 |  |  | 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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 11:38:06 +02:00
										 |  |  | 	tests := map[string]string{ | 
					
						
							|  |  |  | 		"hash":             reHash, | 
					
						
							|  |  |  | 		"nonce":            reNum, | 
					
						
							| 
									
										
										
										
											2015-04-01 15:27:37 +02:00
										 |  |  | 		"blockHash":        reHashOpt, | 
					
						
							|  |  |  | 		"blockNum":         reNumOpt, | 
					
						
							|  |  |  | 		"transactionIndex": reNumOpt, | 
					
						
							| 
									
										
										
										
											2015-04-01 11:38:06 +02:00
										 |  |  | 		"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)) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 09:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-04 14:08:35 +02:00
										 |  |  | 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)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 11:38:06 +02:00
										 |  |  | 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) { | 
					
						
							| 
									
										
										
										
											2015-04-08 20:45:39 +02:00
										 |  |  | 	logs := make([]*state.Log, 3) | 
					
						
							| 
									
										
										
										
											2015-04-01 11:38:06 +02:00
										 |  |  | 	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)) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-08 20:45:39 +02:00
										 |  |  | func makeStateLog(num int) *state.Log { | 
					
						
							| 
									
										
										
										
											2015-04-01 09:11:23 +02:00
										 |  |  | 	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 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-04-04 14:08:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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, | 
					
						
							| 
									
										
										
										
											2015-04-07 15:04:29 +02:00
										 |  |  | 		Extra:      nil, | 
					
						
							| 
									
										
										
										
											2015-04-04 14:08:35 +02:00
										 |  |  | 		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) | 
					
						
							| 
									
										
										
										
											2015-04-07 15:04:29 +02:00
										 |  |  | 	block := types.NewBlock(parentHash, coinbase, root, difficulty, nonce, nil) | 
					
						
							| 
									
										
										
										
											2015-04-04 14:08:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	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 | 
					
						
							|  |  |  | } |