aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2015-04-03 23:19:22 +0800
committerobscuren <geffobscura@gmail.com>2015-04-03 23:19:22 +0800
commitec8a6e0a2b74c5755ebab97e438b00f8765851fe (patch)
tree8c59bc962eec32b2ffb67cd7cff5fb4c93056b68
parent36452afd4e31083d748155e5e5ddd682128aa9b0 (diff)
parentf9d94c7462bbb3a0c463427baefc68555f853dee (diff)
downloaddexon-ec8a6e0a2b74c5755ebab97e438b00f8765851fe.tar.gz
dexon-ec8a6e0a2b74c5755ebab97e438b00f8765851fe.tar.zst
dexon-ec8a6e0a2b74c5755ebab97e438b00f8765851fe.zip
Merge branch 'develop' into glog
-rw-r--r--blockpool/peers.go19
-rw-r--r--common/bytes.go5
-rw-r--r--core/block_processor.go2
-rw-r--r--core/chain_manager.go3
-rw-r--r--rpc/api.go49
-rw-r--r--rpc/args.go19
-rw-r--r--rpc/args_test.go70
-rw-r--r--rpc/responses.go65
-rw-r--r--xeth/xeth.go6
9 files changed, 194 insertions, 44 deletions
diff --git a/blockpool/peers.go b/blockpool/peers.go
index 615058e26..285fa45b1 100644
--- a/blockpool/peers.go
+++ b/blockpool/peers.go
@@ -133,13 +133,10 @@ func (self *peer) addError(code int, format string, params ...interface{}) {
self.addToBlacklist(self.id)
}
+// caller must hold peer lock
func (self *peer) setChainInfo(td *big.Int, c common.Hash) {
- self.lock.Lock()
- defer self.lock.Unlock()
-
self.td = td
self.currentBlockHash = c
-
self.currentBlock = nil
self.parentHash = common.Hash{}
self.headSection = nil
@@ -171,7 +168,7 @@ func (self *peers) requestBlocks(attempts int, hashes []common.Hash) {
defer self.lock.RUnlock()
peerCount := len(self.peers)
// on first attempt use the best peer
- if attempts == 0 {
+ if attempts == 0 && self.best != nil {
plog.DebugDetailf("request %v missing blocks from best peer <%s>", len(hashes), self.best.id)
self.best.requestBlocks(hashes)
return
@@ -219,10 +216,12 @@ func (self *peers) addPeer(
return
}
self.lock.Lock()
+ defer self.lock.Unlock()
p, found := self.peers[id]
if found {
// when called on an already connected peer, it means a newBlockMsg is received
// peer head info is updated
+ p.lock.Lock()
if p.currentBlockHash != currentBlockHash {
previousBlockHash = p.currentBlockHash
plog.Debugf("addPeer: Update peer <%s> with td %v and current block %s (was %v)", id, td, hex(currentBlockHash), hex(previousBlockHash))
@@ -232,6 +231,7 @@ func (self *peers) addPeer(
self.status.values.NewBlocks++
self.status.lock.Unlock()
}
+ p.lock.Unlock()
} else {
p = self.newPeer(td, currentBlockHash, id, requestBlockHashes, requestBlocks, peerError)
@@ -243,7 +243,6 @@ func (self *peers) addPeer(
plog.Debugf("addPeer: add new peer <%v> with td %v and current block %s", id, td, hex(currentBlockHash))
}
- self.lock.Unlock()
// check if peer's current head block is known
if self.bp.hasBlock(currentBlockHash) {
@@ -269,7 +268,10 @@ func (self *peers) addPeer(
} else {
// baseline is our own TD
currentTD := self.bp.getTD()
- if self.best != nil {
+ bestpeer := self.best
+ if bestpeer != nil {
+ bestpeer.lock.Lock()
+ defer bestpeer.lock.Unlock()
currentTD = self.best.td
}
if td.Cmp(currentTD) > 0 {
@@ -277,11 +279,12 @@ func (self *peers) addPeer(
self.status.bestPeers[p.id]++
self.status.lock.Unlock()
plog.Debugf("addPeer: peer <%v> (td: %v > current td %v) promoted best peer", id, td, currentTD)
- self.bp.switchPeer(self.best, p)
+ self.bp.switchPeer(bestpeer, p)
self.best = p
best = true
}
}
+
return
}
diff --git a/common/bytes.go b/common/bytes.go
index 2d885ac74..5bdacd810 100644
--- a/common/bytes.go
+++ b/common/bytes.go
@@ -127,6 +127,11 @@ func CopyBytes(b []byte) (copiedBytes []byte) {
return
}
+func HasHexPrefix(str string) bool {
+ l := len(str)
+ return l >= 2 && str[0:2] == "0x"
+}
+
func IsHex(str string) bool {
l := len(str)
return l >= 4 && l%2 == 0 && str[0:2] == "0x"
diff --git a/core/block_processor.go b/core/block_processor.go
index 97c885536..0a98f3e32 100644
--- a/core/block_processor.go
+++ b/core/block_processor.go
@@ -342,7 +342,7 @@ func (sm *BlockProcessor) VerifyUncles(statedb *state.StateDB, block, parent *ty
return UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.ParentHash[0:4]))
}
- if err := sm.ValidateHeader(uncle, ancestorHeaders[uncle.ParentHash]); err != nil && err != BlockEqualTSErr {
+ if err := sm.ValidateHeader(uncle, ancestorHeaders[uncle.ParentHash]); err != nil {
return ValidationError(fmt.Sprintf("%v", err))
}
diff --git a/core/chain_manager.go b/core/chain_manager.go
index d97a94b06..bf5ba9b40 100644
--- a/core/chain_manager.go
+++ b/core/chain_manager.go
@@ -448,7 +448,8 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
}
if err == BlockEqualTSErr {
- queue[i] = ChainSideEvent{block, logs}
+ //queue[i] = ChainSideEvent{block, logs}
+ // XXX silently discard it?
continue
}
diff --git a/rpc/api.go b/rpc/api.go
index afd242aa3..30ba1ddc1 100644
--- a/rpc/api.go
+++ b/rpc/api.go
@@ -2,6 +2,7 @@ package rpc
import (
"encoding/json"
+ // "fmt"
"math/big"
"sync"
@@ -112,7 +113,11 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
}
block := NewBlockRes(api.xeth().EthBlockByHash(args.Hash), false)
- *reply = common.ToHex(big.NewInt(int64(len(block.Transactions))).Bytes())
+ if block == nil {
+ *reply = nil
+ } else {
+ *reply = common.ToHex(big.NewInt(int64(len(block.Transactions))).Bytes())
+ }
case "eth_getBlockTransactionCountByNumber":
args := new(BlockNumArg)
if err := json.Unmarshal(req.Params, &args); err != nil {
@@ -192,9 +197,9 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
*reply = br
case "eth_getTransactionByHash":
- // HashIndexArgs used, but only the "Hash" part we need.
- args := new(HashIndexArgs)
+ args := new(HashArgs)
if err := json.Unmarshal(req.Params, &args); err != nil {
+ return err
}
tx, bhash, bnum, txi := api.xeth().EthTransactionByHash(args.Hash)
if tx != nil {
@@ -212,11 +217,16 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
block := api.xeth().EthBlockByHash(args.Hash)
br := NewBlockRes(block, true)
+ if br == nil {
+ *reply = nil
+ }
if args.Index >= int64(len(br.Transactions)) || args.Index < 0 {
- return NewValidationError("Index", "does not exist")
+ // return NewValidationError("Index", "does not exist")
+ *reply = nil
+ } else {
+ *reply = br.Transactions[args.Index]
}
- *reply = br.Transactions[args.Index]
case "eth_getTransactionByBlockNumberAndIndex":
args := new(BlockNumIndexArgs)
if err := json.Unmarshal(req.Params, &args); err != nil {
@@ -225,11 +235,16 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
block := api.xeth().EthBlockByNumber(args.BlockNumber)
v := NewBlockRes(block, true)
+ if v == nil {
+ *reply = nil
+ }
if args.Index >= int64(len(v.Transactions)) || args.Index < 0 {
- return NewValidationError("Index", "does not exist")
+ // return NewValidationError("Index", "does not exist")
+ *reply = nil
+ } else {
+ *reply = v.Transactions[args.Index]
}
- *reply = v.Transactions[args.Index]
case "eth_getUncleByBlockHashAndIndex":
args := new(HashIndexArgs)
if err := json.Unmarshal(req.Params, &args); err != nil {
@@ -243,13 +258,11 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
}
if args.Index >= int64(len(br.Uncles)) || args.Index < 0 {
- return NewValidationError("Index", "does not exist")
+ // return NewValidationError("Index", "does not exist")
+ *reply = nil
+ } else {
+ *reply = br.Uncles[args.Index]
}
-
- uhash := br.Uncles[args.Index]
- uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash.String()), false)
-
- *reply = uncle
case "eth_getUncleByBlockNumberAndIndex":
args := new(BlockNumIndexArgs)
if err := json.Unmarshal(req.Params, &args); err != nil {
@@ -265,13 +278,11 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
}
if args.Index >= int64(len(v.Uncles)) || args.Index < 0 {
- return NewValidationError("Index", "does not exist")
+ // return NewValidationError("Index", "does not exist")
+ *reply = nil
+ } else {
+ *reply = v.Uncles[args.Index]
}
-
- uhash := v.Uncles[args.Index]
- uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash.String()), false)
-
- *reply = uncle
case "eth_getCompilers":
c := []string{""}
*reply = c
diff --git a/rpc/args.go b/rpc/args.go
index 70618a01a..cebabf4ba 100644
--- a/rpc/args.go
+++ b/rpc/args.go
@@ -41,7 +41,11 @@ func blockHeight(raw interface{}, number *int64) error {
case "pending":
*number = -2
default:
- *number = common.String2Big(str).Int64()
+ if common.HasHexPrefix(str) {
+ *number = common.String2Big(str).Int64()
+ } else {
+ return NewInvalidTypeError("blockNumber", "is not a valid string")
+ }
}
return nil
@@ -1021,12 +1025,15 @@ func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) {
return NewInsufficientParamsError(len(obj), 1)
}
- var argstr string
- argstr, ok := obj[0].To.(string)
- if !ok {
- return NewInvalidTypeError("to", "is not a string")
+ if obj[0].To == nil {
+ args.To = ""
+ } else {
+ argstr, ok := obj[0].To.(string)
+ if !ok {
+ return NewInvalidTypeError("to", "is not a string")
+ }
+ args.To = argstr
}
- args.To = argstr
t := make([]string, len(obj[0].Topics))
for i, j := range obj[0].Topics {
diff --git a/rpc/args_test.go b/rpc/args_test.go
index 902f8013e..b88bab280 100644
--- a/rpc/args_test.go
+++ b/rpc/args_test.go
@@ -1805,6 +1805,16 @@ func TestWhisperFilterArgsEmpty(t *testing.T) {
}
}
+func TestWhisperFilterArgsToInt(t *testing.T) {
+ input := `[{"to": 2}]`
+
+ args := new(WhisperFilterArgs)
+ str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args))
+ if len(str) > 0 {
+ t.Error(str)
+ }
+}
+
func TestWhisperFilterArgsToBool(t *testing.T) {
input := `[{"topics": ["0x68656c6c6f20776f726c64"], "to": false}]`
@@ -1815,6 +1825,21 @@ func TestWhisperFilterArgsToBool(t *testing.T) {
}
}
+func TestWhisperFilterArgsToMissing(t *testing.T) {
+ input := `[{"topics": ["0x68656c6c6f20776f726c64"]}]`
+ expected := new(WhisperFilterArgs)
+ expected.To = ""
+
+ args := new(WhisperFilterArgs)
+ if err := json.Unmarshal([]byte(input), &args); err != nil {
+ t.Error(err)
+ }
+
+ if args.To != expected.To {
+ t.Errorf("To shoud be %v but is %v", expected.To, args.To)
+ }
+}
+
func TestWhisperFilterArgsTopicInt(t *testing.T) {
input := `[{"topics": [6], "to": "0x34ag445g3455b34"}]`
@@ -2090,6 +2115,51 @@ func TestHashIndexArgsInvalidIndex(t *testing.T) {
}
}
+func TestHashArgs(t *testing.T) {
+ input := `["0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b"]`
+ expected := new(HashIndexArgs)
+ expected.Hash = "0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b"
+
+ args := new(HashArgs)
+ if err := json.Unmarshal([]byte(input), &args); err != nil {
+ t.Error(err)
+ }
+
+ if expected.Hash != args.Hash {
+ t.Errorf("Hash shoud be %#v but is %#v", expected.Hash, args.Hash)
+ }
+}
+
+func TestHashArgsEmpty(t *testing.T) {
+ input := `[]`
+
+ args := new(HashArgs)
+ str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args))
+ if len(str) > 0 {
+ t.Error(str)
+ }
+}
+
+func TestHashArgsInvalid(t *testing.T) {
+ input := `{}`
+
+ args := new(HashArgs)
+ str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args))
+ if len(str) > 0 {
+ t.Error(str)
+ }
+}
+
+func TestHashArgsInvalidHash(t *testing.T) {
+ input := `[7]`
+
+ args := new(HashArgs)
+ str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args))
+ if len(str) > 0 {
+ t.Error(str)
+ }
+}
+
func TestSubmitWorkArgs(t *testing.T) {
input := `["0x0000000000000001", "0x1234567890abcdef1234567890abcdef", "0xD1GE5700000000000000000000000000"]`
expected := new(SubmitWorkArgs)
diff --git a/rpc/responses.go b/rpc/responses.go
index 3d1687cb6..52a2f714c 100644
--- a/rpc/responses.go
+++ b/rpc/responses.go
@@ -28,7 +28,7 @@ type BlockRes struct {
GasUsed *hexnum `json:"gasUsed"`
UnixTimestamp *hexnum `json:"timestamp"`
Transactions []*TransactionRes `json:"transactions"`
- Uncles []*hexdata `json:"uncles"`
+ Uncles []*UncleRes `json:"uncles"`
}
func (b *BlockRes) MarshalJSON() ([]byte, error) {
@@ -73,7 +73,10 @@ func (b *BlockRes) MarshalJSON() ([]byte, error) {
ext.GasUsed = b.GasUsed
ext.UnixTimestamp = b.UnixTimestamp
ext.Transactions = b.Transactions
- ext.Uncles = b.Uncles
+ ext.Uncles = make([]*hexdata, len(b.Uncles))
+ for i, u := range b.Uncles {
+ ext.Uncles[i] = u.BlockHash
+ }
return json.Marshal(ext)
} else {
var ext struct {
@@ -119,14 +122,15 @@ func (b *BlockRes) MarshalJSON() ([]byte, error) {
for i, tx := range b.Transactions {
ext.Transactions[i] = tx.Hash
}
- ext.Uncles = b.Uncles
+ ext.Uncles = make([]*hexdata, len(b.Uncles))
+ for i, u := range b.Uncles {
+ ext.Uncles[i] = u.BlockHash
+ }
return json.Marshal(ext)
}
}
func NewBlockRes(block *types.Block, fullTx bool) *BlockRes {
- // TODO respect fullTx flag
-
if block == nil {
return nil
}
@@ -159,9 +163,9 @@ func NewBlockRes(block *types.Block, fullTx bool) *BlockRes {
res.Transactions[i].TxIndex = newHexNum(i)
}
- res.Uncles = make([]*hexdata, len(block.Uncles()))
+ res.Uncles = make([]*UncleRes, len(block.Uncles()))
for i, uncle := range block.Uncles() {
- res.Uncles[i] = newHexData(uncle.Hash())
+ res.Uncles[i] = NewUncleRes(uncle)
}
return res
@@ -182,6 +186,10 @@ type TransactionRes struct {
}
func NewTransactionRes(tx *types.Transaction) *TransactionRes {
+ if tx == nil {
+ return nil
+ }
+
var v = new(TransactionRes)
v.Hash = newHexData(tx.Hash())
v.Nonce = newHexNum(tx.Nonce())
@@ -198,6 +206,49 @@ func NewTransactionRes(tx *types.Transaction) *TransactionRes {
return v
}
+type UncleRes struct {
+ BlockNumber *hexnum `json:"number"`
+ BlockHash *hexdata `json:"hash"`
+ ParentHash *hexdata `json:"parentHash"`
+ Nonce *hexdata `json:"nonce"`
+ Sha3Uncles *hexdata `json:"sha3Uncles"`
+ ReceiptHash *hexdata `json:"receiptHash"`
+ LogsBloom *hexdata `json:"logsBloom"`
+ TransactionRoot *hexdata `json:"transactionsRoot"`
+ StateRoot *hexdata `json:"stateRoot"`
+ Miner *hexdata `json:"miner"`
+ Difficulty *hexnum `json:"difficulty"`
+ ExtraData *hexdata `json:"extraData"`
+ GasLimit *hexnum `json:"gasLimit"`
+ GasUsed *hexnum `json:"gasUsed"`
+ UnixTimestamp *hexnum `json:"timestamp"`
+}
+
+func NewUncleRes(h *types.Header) *UncleRes {
+ if h == nil {
+ return nil
+ }
+
+ var v = new(UncleRes)
+ v.BlockNumber = newHexNum(h.Number)
+ v.BlockHash = newHexData(h.Hash())
+ v.ParentHash = newHexData(h.ParentHash)
+ v.Sha3Uncles = newHexData(h.UncleHash)
+ v.Nonce = newHexData(h.Nonce[:])
+ v.LogsBloom = newHexData(h.Bloom)
+ v.TransactionRoot = newHexData(h.TxHash)
+ v.StateRoot = newHexData(h.Root)
+ v.Miner = newHexData(h.Coinbase)
+ v.Difficulty = newHexNum(h.Difficulty)
+ v.ExtraData = newHexData(h.Extra)
+ v.GasLimit = newHexNum(h.GasLimit)
+ v.GasUsed = newHexNum(h.GasUsed)
+ v.UnixTimestamp = newHexNum(h.Time)
+ v.ReceiptHash = newHexData(h.ReceiptHash)
+
+ return v
+}
+
// type FilterLogRes struct {
// Hash string `json:"hash"`
// Address string `json:"address"`
diff --git a/xeth/xeth.go b/xeth/xeth.go
index b203e45de..825f26017 100644
--- a/xeth/xeth.go
+++ b/xeth/xeth.go
@@ -196,7 +196,7 @@ func (self *XEth) EthTransactionByHash(hash string) (tx *types.Transaction, blha
// meta
var txExtra struct {
BlockHash common.Hash
- BlockIndex int64
+ BlockIndex uint64
Index uint64
}
@@ -205,8 +205,10 @@ func (self *XEth) EthTransactionByHash(hash string) (tx *types.Transaction, blha
err := rlp.Decode(r, &txExtra)
if err == nil {
blhash = txExtra.BlockHash
- blnum = big.NewInt(txExtra.BlockIndex)
+ blnum = big.NewInt(int64(txExtra.BlockIndex))
txi = txExtra.Index
+ } else {
+ pipelogger.Errorln(err)
}
return