|
|
@ -2,6 +2,7 @@ package eth |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
import ( |
|
|
|
"container/list" |
|
|
|
"container/list" |
|
|
|
|
|
|
|
"fmt" |
|
|
|
"github.com/ethereum/eth-go/ethchain" |
|
|
|
"github.com/ethereum/eth-go/ethchain" |
|
|
|
"github.com/ethereum/eth-go/ethdb" |
|
|
|
"github.com/ethereum/eth-go/ethdb" |
|
|
|
"github.com/ethereum/eth-go/ethrpc" |
|
|
|
"github.com/ethereum/eth-go/ethrpc" |
|
|
@ -9,9 +10,11 @@ import ( |
|
|
|
"github.com/ethereum/eth-go/ethwire" |
|
|
|
"github.com/ethereum/eth-go/ethwire" |
|
|
|
"io/ioutil" |
|
|
|
"io/ioutil" |
|
|
|
"log" |
|
|
|
"log" |
|
|
|
|
|
|
|
"math/rand" |
|
|
|
"net" |
|
|
|
"net" |
|
|
|
"net/http" |
|
|
|
"net/http" |
|
|
|
"strconv" |
|
|
|
"strconv" |
|
|
|
|
|
|
|
"strings" |
|
|
|
"sync" |
|
|
|
"sync" |
|
|
|
"sync/atomic" |
|
|
|
"sync/atomic" |
|
|
|
"time" |
|
|
|
"time" |
|
|
@ -122,12 +125,20 @@ func (s *Ethereum) TxPool() *ethchain.TxPool { |
|
|
|
return s.txPool |
|
|
|
return s.txPool |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (s *Ethereum) ServerCaps() Caps { |
|
|
|
|
|
|
|
return s.serverCaps |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (s *Ethereum) AddPeer(conn net.Conn) { |
|
|
|
func (s *Ethereum) AddPeer(conn net.Conn) { |
|
|
|
peer := NewPeer(conn, s, true) |
|
|
|
peer := NewPeer(conn, s, true) |
|
|
|
|
|
|
|
|
|
|
|
if peer != nil && s.peers.Len() < s.MaxPeers { |
|
|
|
if peer != nil { |
|
|
|
s.peers.PushBack(peer) |
|
|
|
if s.peers.Len() < s.MaxPeers { |
|
|
|
peer.Start() |
|
|
|
s.peers.PushBack(peer) |
|
|
|
|
|
|
|
peer.Start() |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
ethutil.Config.Log.Debugf("[SERV] Max connected peers reached. Not adding incoming peer.") |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -142,15 +153,51 @@ func (s *Ethereum) ConnectToPeer(addr string) error { |
|
|
|
if s.peers.Len() < s.MaxPeers { |
|
|
|
if s.peers.Len() < s.MaxPeers { |
|
|
|
var alreadyConnected bool |
|
|
|
var alreadyConnected bool |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ahost, _, _ := net.SplitHostPort(addr) |
|
|
|
|
|
|
|
var chost string |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ips, err := net.LookupIP(ahost) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// If more then one ip is available try stripping away the ipv6 ones
|
|
|
|
|
|
|
|
if len(ips) > 1 { |
|
|
|
|
|
|
|
var ipsv4 []net.IP |
|
|
|
|
|
|
|
// For now remove the ipv6 addresses
|
|
|
|
|
|
|
|
for _, ip := range ips { |
|
|
|
|
|
|
|
if strings.Contains(ip.String(), "::") { |
|
|
|
|
|
|
|
continue |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
ipsv4 = append(ipsv4, ip) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if len(ipsv4) == 0 { |
|
|
|
|
|
|
|
return fmt.Errorf("[SERV] No IPV4 addresses available for hostname") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Pick a random ipv4 address, simulating round-robin DNS.
|
|
|
|
|
|
|
|
rand.Seed(time.Now().UTC().UnixNano()) |
|
|
|
|
|
|
|
i := rand.Intn(len(ipsv4)) |
|
|
|
|
|
|
|
chost = ipsv4[i].String() |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
if len(ips) == 0 { |
|
|
|
|
|
|
|
return fmt.Errorf("[SERV] No IPs resolved for the given hostname") |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
chost = ips[0].String() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
eachPeer(s.peers, func(p *Peer, v *list.Element) { |
|
|
|
eachPeer(s.peers, func(p *Peer, v *list.Element) { |
|
|
|
if p.conn == nil { |
|
|
|
if p.conn == nil { |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
phost, _, _ := net.SplitHostPort(p.conn.RemoteAddr().String()) |
|
|
|
phost, _, _ := net.SplitHostPort(p.conn.RemoteAddr().String()) |
|
|
|
ahost, _, _ := net.SplitHostPort(addr) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if phost == ahost { |
|
|
|
if phost == chost { |
|
|
|
alreadyConnected = true |
|
|
|
alreadyConnected = true |
|
|
|
|
|
|
|
ethutil.Config.Log.Debugf("[SERV] Peer %s already added.\n", chost) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
}) |
|
|
@ -278,8 +325,21 @@ func (s *Ethereum) Start(seed bool) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (s *Ethereum) Seed() { |
|
|
|
func (s *Ethereum) Seed() { |
|
|
|
ethutil.Config.Log.Debugln("Seeding") |
|
|
|
ethutil.Config.Log.Debugln("[SERV] Retrieving seed nodes") |
|
|
|
// DNS Bootstrapping
|
|
|
|
|
|
|
|
|
|
|
|
// Eth-Go Bootstrapping
|
|
|
|
|
|
|
|
ips, er := net.LookupIP("seed.bysh.me") |
|
|
|
|
|
|
|
if er == nil { |
|
|
|
|
|
|
|
peers := []string{} |
|
|
|
|
|
|
|
for _, ip := range ips { |
|
|
|
|
|
|
|
node := fmt.Sprintf("%s:%d", ip.String(), 30303) |
|
|
|
|
|
|
|
ethutil.Config.Log.Debugln("[SERV] Found DNS Go Peer:", node) |
|
|
|
|
|
|
|
peers = append(peers, node) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
s.ProcessPeerList(peers) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Official DNS Bootstrapping
|
|
|
|
_, nodes, err := net.LookupSRV("eth", "tcp", "ethereum.org") |
|
|
|
_, nodes, err := net.LookupSRV("eth", "tcp", "ethereum.org") |
|
|
|
if err == nil { |
|
|
|
if err == nil { |
|
|
|
peers := []string{} |
|
|
|
peers := []string{} |
|
|
@ -293,11 +353,11 @@ func (s *Ethereum) Seed() { |
|
|
|
for _, a := range addr { |
|
|
|
for _, a := range addr { |
|
|
|
// Build string out of SRV port and Resolved IP
|
|
|
|
// Build string out of SRV port and Resolved IP
|
|
|
|
peer := net.JoinHostPort(a, port) |
|
|
|
peer := net.JoinHostPort(a, port) |
|
|
|
log.Println("Found DNS Bootstrap Peer:", peer) |
|
|
|
ethutil.Config.Log.Debugln("[SERV] Found DNS Bootstrap Peer:", peer) |
|
|
|
peers = append(peers, peer) |
|
|
|
peers = append(peers, peer) |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
log.Println("Couldn't resolve :", target) |
|
|
|
ethutil.Config.Log.Debugln("[SERV} Couldn't resolve :", target) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// Connect to Peer list
|
|
|
|
// Connect to Peer list
|
|
|
|