diff --git a/cmd/tbcd/tbcd.go b/cmd/tbcd/tbcd.go
index 033023e8..6aa50d5d 100644
--- a/cmd/tbcd/tbcd.go
+++ b/cmd/tbcd/tbcd.go
@@ -93,6 +93,12 @@ var (
Help: "address and port tbcd pprof listens on (open
/debug/pprof to see available profiles)",
Print: config.PrintAll,
},
+ "TBC_SEEDS": config.Config{
+ Value: &cfg.Seeds,
+ DefaultValue: []string{},
+ Help: "list of seed domains for Bitcoin P2P, in the format ':' (for localnet, must be a single host:port)",
+ Print: config.PrintAll,
+ },
}
)
@@ -139,6 +145,7 @@ func _main() error {
if err != nil {
return fmt.Errorf("create tbc server: %w", err)
}
+
// XXX remove, this is an illustration of calling the direct API of server
// go func() {
// for {
diff --git a/config/config.go b/config/config.go
index 04c2dcdd..2f71ab9d 100644
--- a/config/config.go
+++ b/config/config.go
@@ -12,6 +12,7 @@ import (
"reflect"
"sort"
"strconv"
+ "strings"
)
type PrintMode int
@@ -88,6 +89,9 @@ func Parse(c CfgMap) error {
}
reflect.ValueOf(v.Value).Elem().SetBool(val)
+ case reflect.Slice:
+ value := reflect.ValueOf(v.Value).Elem()
+ value.Set(reflect.AppendSlice(value, reflect.ValueOf(strings.Split(envValue, ","))))
default:
return fmt.Errorf("unsuported type for %v: %v",
diff --git a/service/tbc/tbc.go b/service/tbc/tbc.go
index 131cc936..da8f9222 100644
--- a/service/tbc/tbc.go
+++ b/service/tbc/tbc.go
@@ -48,10 +48,6 @@ const (
promSubsystem = "tbc_service" // Prometheus
- mainnetPort = "8333"
- testnetPort = "18333"
- localnetPort = "18444"
-
defaultPeersWanted = 64
defaultPendingBlocks = 128 // 128 * ~4MB max memory use
@@ -67,19 +63,22 @@ const (
var (
zeroHash = new(chainhash.Hash) // used to check if a hash is invalid
+ localnetSeeds = []string{
+ "127.0.0.1:18444",
+ }
testnetSeeds = []string{
- "testnet-seed.bitcoin.jonasschnelli.ch",
- "seed.tbtc.petertodd.org",
- "seed.testnet.bitcoin.sprovoost.nl",
- "testnet-seed.bluematt.me",
+ "testnet-seed.bitcoin.jonasschnelli.ch:18333",
+ "seed.tbtc.petertodd.org:18333",
+ "seed.testnet.bitcoin.sprovoost.nl:18333",
+ "testnet-seed.bluematt.me:18333",
}
mainnetSeeds = []string{
- "seed.bitcoin.sipa.be",
- "dnsseed.bluematt.me",
- "dnsseed.bitcoin.dashjr.org",
- "seed.bitcoinstats.com",
- "seed.bitnodes.io",
- "seed.bitcoin.jonasschnelli.ch",
+ "seed.bitcoin.sipa.be:8333",
+ "dnsseed.bluematt.me:8333",
+ "dnsseed.bitcoin.dashjr.org:8333",
+ "seed.bitcoinstats.com:8333",
+ "seed.bitnodes.io:8333",
+ "seed.bitcoin.jonasschnelli.ch:8333",
}
)
@@ -157,6 +156,7 @@ type Config struct {
PeersWanted int
PrometheusListenAddress string
PprofListenAddress string
+ Seeds []string
}
func NewDefaultConfig() *Config {
@@ -184,7 +184,6 @@ type Server struct {
wireNet wire.BitcoinNet
chainParams *chaincfg.Params
timeSource blockchain.MedianTimeSource
- port string
seeds []string
peers map[string]*peer // active but not necessarily connected
@@ -247,23 +246,25 @@ func NewServer(cfg *Config) (*Server, error) {
switch cfg.Network {
case "mainnet":
- s.port = mainnetPort
s.wireNet = wire.MainNet
s.chainParams = &chaincfg.MainNetParams
s.seeds = mainnetSeeds
case "testnet3":
- s.port = testnetPort
s.wireNet = wire.TestNet3
s.chainParams = &chaincfg.TestNet3Params
s.seeds = testnetSeeds
case networkLocalnet:
- s.port = localnetPort
s.wireNet = wire.TestNet
s.chainParams = &chaincfg.RegressionNetParams
+ s.seeds = localnetSeeds
default:
return nil, fmt.Errorf("invalid network: %v", cfg.Network)
}
+ if len(cfg.Seeds) > 0 {
+ s.seeds = cfg.Seeds
+ }
+
return s, nil
}
@@ -306,26 +307,36 @@ func (s *Server) seed(pctx context.Context, peersWanted int) ([]tbcd.Peer, error
defer cancel()
errorsSeen := 0
- var addrs []net.IP
- for k := range s.seeds {
- ips, err := resolver.LookupIP(ctx, "ip", s.seeds[k])
+ var moreSeeds []tbcd.Peer
+ for _, v := range s.seeds {
+ host, port, err := net.SplitHostPort(v)
+ if err != nil {
+ log.Errorf("Failed to parse host/port: %v", err)
+ errorsSeen++
+ continue
+ }
+ ips, err := resolver.LookupIP(ctx, "ip", host)
if err != nil {
log.Errorf("lookup: %v", err)
errorsSeen++
continue
}
- addrs = append(addrs, ips...)
+
+ for _, ip := range ips {
+ moreSeeds = append(moreSeeds, tbcd.Peer{
+ Host: ip.String(),
+ Port: port,
+ })
+ }
}
+
if errorsSeen == len(s.seeds) {
return nil, errors.New("could not seed")
}
// insert into peers table
- for k := range addrs {
- peers = append(peers, tbcd.Peer{
- Host: addrs[k].String(),
- Port: s.port,
- })
+ for _, ms := range moreSeeds {
+ peers = append(peers, ms)
}
// return fake peers but don't save them to the database
@@ -471,10 +482,14 @@ func (s *Server) localPeerManager(ctx context.Context) error {
log.Tracef("localPeerManager")
defer log.Tracef("localPeerManager exit")
+ if len(s.seeds) != 1 {
+ return fmt.Errorf("expecting 1 seed, received %d", len(s.seeds))
+ }
+
peersWanted := 1
peerC := make(chan string, peersWanted)
- address := net.JoinHostPort("127.0.0.1", s.port)
- peer, err := NewPeer(s.wireNet, address)
+
+ peer, err := NewPeer(s.wireNet, s.seeds[0])
if err != nil {
return fmt.Errorf("new peer: %w", err)
}
diff --git a/service/tbc/tbc_test.go b/service/tbc/tbc_test.go
index c814d487..d4f143c8 100644
--- a/service/tbc/tbc_test.go
+++ b/service/tbc/tbc_test.go
@@ -1032,5 +1032,5 @@ func createBitcoindWithInitialBlocks(ctx context.Context, t *testing.T, blocks u
t.Fatal(err)
}
- return bitcoindContainer, nat.Port(localnetPort)
+ return bitcoindContainer, nat.Port("18444")
}