aboutsummaryrefslogtreecommitdiffstats
path: root/eth/handler.go
diff options
context:
space:
mode:
Diffstat (limited to 'eth/handler.go')
-rw-r--r--eth/handler.go52
1 files changed, 27 insertions, 25 deletions
diff --git a/eth/handler.go b/eth/handler.go
index f22afecb7..4aef69043 100644
--- a/eth/handler.go
+++ b/eth/handler.go
@@ -36,8 +36,10 @@ import (
"github.com/ethereum/go-ethereum/rlp"
)
-// This is the target maximum size of returned blocks, headers or node data.
-const softResponseLimit = 2 * 1024 * 1024
+const (
+ softResponseLimit = 2 * 1024 * 1024 // Target maximum size of returned blocks, headers or node data.
+ estHeaderRlpSize = 500 // Approximate size of an RLP encoded block header
+)
func errResp(code errCode, format string, v ...interface{}) error {
return fmt.Errorf("%v - %v", code, fmt.Sprintf(format, v...))
@@ -113,7 +115,7 @@ func NewProtocolManager(networkId int, mux *event.TypeMux, txpool txPool, pow po
}
}
// Construct the different synchronisation mechanisms
- manager.downloader = downloader.New(manager.eventMux, manager.chainman.HasBlock, manager.chainman.GetBlock, manager.chainman.CurrentBlock, manager.chainman.InsertChain, manager.removePeer)
+ manager.downloader = downloader.New(manager.eventMux, manager.chainman.HasBlock, manager.chainman.GetBlock, manager.chainman.CurrentBlock, manager.chainman.GetTd, manager.chainman.InsertChain, manager.removePeer)
validator := func(block *types.Block, parent *types.Block) error {
return core.ValidateHeader(pow, block.Header(), parent, true, false)
@@ -345,33 +347,33 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
if err := msg.Decode(&query); err != nil {
return errResp(ErrDecode, "%v: %v", msg, err)
}
- // Gather blocks until the fetch or network limits is reached
+ // Gather headers until the fetch or network limits is reached
var (
bytes common.StorageSize
headers []*types.Header
unknown bool
)
for !unknown && len(headers) < int(query.Amount) && bytes < softResponseLimit && len(headers) < downloader.MaxHeaderFetch {
- // Retrieve the next block satisfying the query
- var origin *types.Block
+ // Retrieve the next header satisfying the query
+ var origin *types.Header
if query.Origin.Hash != (common.Hash{}) {
- origin = pm.chainman.GetBlock(query.Origin.Hash)
+ origin = pm.chainman.GetHeader(query.Origin.Hash)
} else {
- origin = pm.chainman.GetBlockByNumber(query.Origin.Number)
+ origin = pm.chainman.GetHeaderByNumber(query.Origin.Number)
}
if origin == nil {
break
}
- headers = append(headers, origin.Header())
- bytes += origin.Size()
+ headers = append(headers, origin)
+ bytes += estHeaderRlpSize
- // Advance to the next block of the query
+ // Advance to the next header of the query
switch {
case query.Origin.Hash != (common.Hash{}) && query.Reverse:
// Hash based traversal towards the genesis block
for i := 0; i < int(query.Skip)+1; i++ {
- if block := pm.chainman.GetBlock(query.Origin.Hash); block != nil {
- query.Origin.Hash = block.ParentHash()
+ if header := pm.chainman.GetHeader(query.Origin.Hash); header != nil {
+ query.Origin.Hash = header.ParentHash
} else {
unknown = true
break
@@ -379,9 +381,9 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
}
case query.Origin.Hash != (common.Hash{}) && !query.Reverse:
// Hash based traversal towards the leaf block
- if block := pm.chainman.GetBlockByNumber(origin.NumberU64() + query.Skip + 1); block != nil {
- if pm.chainman.GetBlockHashesFromHash(block.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash {
- query.Origin.Hash = block.Hash()
+ if header := pm.chainman.GetHeaderByNumber(origin.Number.Uint64() + query.Skip + 1); header != nil {
+ if pm.chainman.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash {
+ query.Origin.Hash = header.Hash()
} else {
unknown = true
}
@@ -452,23 +454,23 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
// Gather blocks until the fetch or network limits is reached
var (
hash common.Hash
- bytes common.StorageSize
- bodies []*blockBody
+ bytes int
+ bodies []rlp.RawValue
)
for bytes < softResponseLimit && len(bodies) < downloader.MaxBlockFetch {
- //Retrieve the hash of the next block
+ // Retrieve the hash of the next block
if err := msgStream.Decode(&hash); err == rlp.EOL {
break
} else if err != nil {
return errResp(ErrDecode, "msg %v: %v", msg, err)
}
- // Retrieve the requested block, stopping if enough was found
- if block := pm.chainman.GetBlock(hash); block != nil {
- bodies = append(bodies, &blockBody{Transactions: block.Transactions(), Uncles: block.Uncles()})
- bytes += block.Size()
+ // Retrieve the requested block body, stopping if enough was found
+ if data := pm.chainman.GetBodyRLP(hash); len(data) != 0 {
+ bodies = append(bodies, data)
+ bytes += len(data)
}
}
- return p.SendBlockBodies(bodies)
+ return p.SendBlockBodiesRLP(bodies)
case p.version >= eth63 && msg.Code == GetNodeDataMsg:
// Decode the retrieval message
@@ -643,7 +645,7 @@ func (pm *ProtocolManager) BroadcastBlock(block *types.Block, propagate bool) {
// Calculate the TD of the block (it's not imported yet, so block.Td is not valid)
var td *big.Int
if parent := pm.chainman.GetBlock(block.ParentHash()); parent != nil {
- td = new(big.Int).Add(parent.Td, block.Difficulty())
+ td = new(big.Int).Add(block.Difficulty(), pm.chainman.GetTd(block.ParentHash()))
} else {
glog.V(logger.Error).Infof("propagating dangling block #%d [%x]", block.NumberU64(), hash[:4])
return