|
|
@ -34,6 +34,7 @@ import ( |
|
|
|
"github.com/ethereum/go-ethereum/logger" |
|
|
|
"github.com/ethereum/go-ethereum/logger" |
|
|
|
"github.com/ethereum/go-ethereum/logger/glog" |
|
|
|
"github.com/ethereum/go-ethereum/logger/glog" |
|
|
|
"github.com/ethereum/go-ethereum/p2p" |
|
|
|
"github.com/ethereum/go-ethereum/p2p" |
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/p2p/discover" |
|
|
|
"github.com/ethereum/go-ethereum/pow" |
|
|
|
"github.com/ethereum/go-ethereum/pow" |
|
|
|
"github.com/ethereum/go-ethereum/rlp" |
|
|
|
"github.com/ethereum/go-ethereum/rlp" |
|
|
|
) |
|
|
|
) |
|
|
@ -55,6 +56,8 @@ type hashFetcherFn func(common.Hash) error |
|
|
|
type blockFetcherFn func([]common.Hash) error |
|
|
|
type blockFetcherFn func([]common.Hash) error |
|
|
|
|
|
|
|
|
|
|
|
type ProtocolManager struct { |
|
|
|
type ProtocolManager struct { |
|
|
|
|
|
|
|
networkId int |
|
|
|
|
|
|
|
|
|
|
|
fastSync bool |
|
|
|
fastSync bool |
|
|
|
txpool txPool |
|
|
|
txpool txPool |
|
|
|
blockchain *core.BlockChain |
|
|
|
blockchain *core.BlockChain |
|
|
@ -91,6 +94,7 @@ func NewProtocolManager(fastSync bool, networkId int, mux *event.TypeMux, txpool |
|
|
|
} |
|
|
|
} |
|
|
|
// Create the protocol manager with the base fields
|
|
|
|
// Create the protocol manager with the base fields
|
|
|
|
manager := &ProtocolManager{ |
|
|
|
manager := &ProtocolManager{ |
|
|
|
|
|
|
|
networkId: networkId, |
|
|
|
fastSync: fastSync, |
|
|
|
fastSync: fastSync, |
|
|
|
eventMux: mux, |
|
|
|
eventMux: mux, |
|
|
|
txpool: txpool, |
|
|
|
txpool: txpool, |
|
|
@ -111,14 +115,23 @@ func NewProtocolManager(fastSync bool, networkId int, mux *event.TypeMux, txpool |
|
|
|
// Compatible; initialise the sub-protocol
|
|
|
|
// Compatible; initialise the sub-protocol
|
|
|
|
version := version // Closure for the run
|
|
|
|
version := version // Closure for the run
|
|
|
|
manager.SubProtocols = append(manager.SubProtocols, p2p.Protocol{ |
|
|
|
manager.SubProtocols = append(manager.SubProtocols, p2p.Protocol{ |
|
|
|
Name: "eth", |
|
|
|
Name: ProtocolName, |
|
|
|
Version: version, |
|
|
|
Version: version, |
|
|
|
Length: ProtocolLengths[i], |
|
|
|
Length: ProtocolLengths[i], |
|
|
|
Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { |
|
|
|
Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { |
|
|
|
peer := manager.newPeer(int(version), networkId, p, rw) |
|
|
|
peer := manager.newPeer(int(version), p, rw) |
|
|
|
manager.newPeerCh <- peer |
|
|
|
manager.newPeerCh <- peer |
|
|
|
return manager.handle(peer) |
|
|
|
return manager.handle(peer) |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
NodeInfo: func() interface{} { |
|
|
|
|
|
|
|
return manager.NodeInfo() |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
PeerInfo: func(id discover.NodeID) interface{} { |
|
|
|
|
|
|
|
if p := manager.peers.Peer(fmt.Sprintf("%x", id[:8])); p != nil { |
|
|
|
|
|
|
|
return p.Info() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
}, |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
if len(manager.SubProtocols) == 0 { |
|
|
|
if len(manager.SubProtocols) == 0 { |
|
|
@ -188,8 +201,8 @@ func (pm *ProtocolManager) Stop() { |
|
|
|
glog.V(logger.Info).Infoln("Ethereum protocol handler stopped") |
|
|
|
glog.V(logger.Info).Infoln("Ethereum protocol handler stopped") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (pm *ProtocolManager) newPeer(pv, nv int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer { |
|
|
|
func (pm *ProtocolManager) newPeer(pv int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer { |
|
|
|
return newPeer(pv, nv, p, newMeteredMsgWriter(rw)) |
|
|
|
return newPeer(pv, p, newMeteredMsgWriter(rw)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// handle is the callback invoked to manage the life cycle of an eth peer. When
|
|
|
|
// handle is the callback invoked to manage the life cycle of an eth peer. When
|
|
|
@ -199,7 +212,7 @@ func (pm *ProtocolManager) handle(p *peer) error { |
|
|
|
|
|
|
|
|
|
|
|
// Execute the Ethereum handshake
|
|
|
|
// Execute the Ethereum handshake
|
|
|
|
td, head, genesis := pm.blockchain.Status() |
|
|
|
td, head, genesis := pm.blockchain.Status() |
|
|
|
if err := p.Handshake(td, head, genesis); err != nil { |
|
|
|
if err := p.Handshake(pm.networkId, td, head, genesis); err != nil { |
|
|
|
glog.V(logger.Debug).Infof("%v: handshake failed: %v", p, err) |
|
|
|
glog.V(logger.Debug).Infof("%v: handshake failed: %v", p, err) |
|
|
|
return err |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
@ -730,3 +743,22 @@ func (self *ProtocolManager) txBroadcastLoop() { |
|
|
|
self.BroadcastTx(event.Tx.Hash(), event.Tx) |
|
|
|
self.BroadcastTx(event.Tx.Hash(), event.Tx) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// EthNodeInfo represents a short summary of the Ethereum sub-protocol metadata known
|
|
|
|
|
|
|
|
// about the host peer.
|
|
|
|
|
|
|
|
type EthNodeInfo struct { |
|
|
|
|
|
|
|
Network int `json:"network"` // Ethereum network ID (0=Olympic, 1=Frontier, 2=Morden)
|
|
|
|
|
|
|
|
Difficulty *big.Int `json:"difficulty"` // Total difficulty of the host's blockchain
|
|
|
|
|
|
|
|
Genesis string `json:"genesis"` // SHA3 hash of the host's genesis block
|
|
|
|
|
|
|
|
Head string `json:"head"` // SHA3 hash of the host's best owned block
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// NodeInfo retrieves some protocol metadata about the running host node.
|
|
|
|
|
|
|
|
func (self *ProtocolManager) NodeInfo() *EthNodeInfo { |
|
|
|
|
|
|
|
return &EthNodeInfo{ |
|
|
|
|
|
|
|
Network: self.networkId, |
|
|
|
|
|
|
|
Difficulty: self.blockchain.GetTd(self.blockchain.CurrentBlock().Hash()), |
|
|
|
|
|
|
|
Genesis: fmt.Sprintf("%x", self.blockchain.Genesis().Hash()), |
|
|
|
|
|
|
|
Head: fmt.Sprintf("%x", self.blockchain.CurrentBlock().Hash()), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|