aboutsummaryrefslogtreecommitdiffstats
path: root/eth/peer.go
diff options
context:
space:
mode:
Diffstat (limited to 'eth/peer.go')
-rw-r--r--eth/peer.go47
1 files changed, 31 insertions, 16 deletions
diff --git a/eth/peer.go b/eth/peer.go
index 695e910f6..15ba22ff5 100644
--- a/eth/peer.go
+++ b/eth/peer.go
@@ -44,38 +44,51 @@ const (
handshakeTimeout = 5 * time.Second
)
+// PeerInfo represents a short summary of the Ethereum sub-protocol metadata known
+// about a connected peer.
+type PeerInfo struct {
+ Version int `json:"version"` // Ethereum protocol version negotiated
+ Difficulty *big.Int `json:"difficulty"` // Total difficulty of the peer's blockchain
+ Head string `json:"head"` // SHA3 hash of the peer's best owned block
+}
+
type peer struct {
- *p2p.Peer
+ id string
+ *p2p.Peer
rw p2p.MsgReadWriter
version int // Protocol version negotiated
- network int // Network ID being on
-
- id string
-
- head common.Hash
- td *big.Int
- lock sync.RWMutex
+ head common.Hash
+ td *big.Int
+ lock sync.RWMutex
knownTxs *set.Set // Set of transaction hashes known to be known by this peer
knownBlocks *set.Set // Set of block hashes known to be known by this peer
}
-func newPeer(version, network int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer {
+func newPeer(version int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer {
id := p.ID()
return &peer{
Peer: p,
rw: rw,
version: version,
- network: network,
id: fmt.Sprintf("%x", id[:8]),
knownTxs: set.New(),
knownBlocks: set.New(),
}
}
+// Info gathers and returns a collection of metadata known about a peer.
+func (p *peer) Info() *PeerInfo {
+ return &PeerInfo{
+ Version: p.version,
+ Difficulty: p.Td(),
+ Head: fmt.Sprintf("%x", p.Head()),
+ }
+}
+
// Head retrieves a copy of the current head (most recent) hash of the peer.
func (p *peer) Head() (hash common.Hash) {
p.lock.RLock()
@@ -268,20 +281,22 @@ func (p *peer) RequestReceipts(hashes []common.Hash) error {
// Handshake executes the eth protocol handshake, negotiating version number,
// network IDs, difficulties, head and genesis blocks.
-func (p *peer) Handshake(td *big.Int, head common.Hash, genesis common.Hash) error {
+func (p *peer) Handshake(network int, td *big.Int, head common.Hash, genesis common.Hash) error {
+ // Send out own handshake in a new thread
errc := make(chan error, 2)
var status statusData // safe to read after two values have been received from errc
+
go func() {
errc <- p2p.Send(p.rw, StatusMsg, &statusData{
ProtocolVersion: uint32(p.version),
- NetworkId: uint32(p.network),
+ NetworkId: uint32(network),
TD: td,
CurrentBlock: head,
GenesisBlock: genesis,
})
}()
go func() {
- errc <- p.readStatus(&status, genesis)
+ errc <- p.readStatus(network, &status, genesis)
}()
timeout := time.NewTimer(handshakeTimeout)
defer timeout.Stop()
@@ -299,7 +314,7 @@ func (p *peer) Handshake(td *big.Int, head common.Hash, genesis common.Hash) err
return nil
}
-func (p *peer) readStatus(status *statusData, genesis common.Hash) (err error) {
+func (p *peer) readStatus(network int, status *statusData, genesis common.Hash) (err error) {
msg, err := p.rw.ReadMsg()
if err != nil {
return err
@@ -317,8 +332,8 @@ func (p *peer) readStatus(status *statusData, genesis common.Hash) (err error) {
if status.GenesisBlock != genesis {
return errResp(ErrGenesisBlockMismatch, "%x (!= %x)", status.GenesisBlock, genesis)
}
- if int(status.NetworkId) != p.network {
- return errResp(ErrNetworkIdMismatch, "%d (!= %d)", status.NetworkId, p.network)
+ if int(status.NetworkId) != network {
+ return errResp(ErrNetworkIdMismatch, "%d (!= %d)", status.NetworkId, network)
}
if int(status.ProtocolVersion) != p.version {
return errResp(ErrProtocolVersionMismatch, "%d (!= %d)", status.ProtocolVersion, p.version)