commit
124e9fa1bc
|
@ -36,6 +36,7 @@ type Client struct {
|
|||
nextRequestID int
|
||||
conn net.Conn
|
||||
log *utils.Logger
|
||||
requireTls bool
|
||||
}
|
||||
|
||||
// Request models the structure of all Electrum protocol requests.
|
||||
|
@ -110,9 +111,10 @@ type ServerFeatures struct {
|
|||
type Param = interface{}
|
||||
|
||||
// NewClient creates an initialized Client instance.
|
||||
func NewClient() *Client {
|
||||
func NewClient(requireTls bool) *Client {
|
||||
return &Client{
|
||||
log: utils.NewLogger(defaultLoggerTag),
|
||||
log: utils.NewLogger(defaultLoggerTag),
|
||||
requireTls: requireTls,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,6 +336,9 @@ func (c *Client) ListUnspentBatch(indexHashes []string) ([][]UnspentRef, error)
|
|||
}
|
||||
|
||||
func (c *Client) establishConnection() error {
|
||||
// We first try to connect over TCP+TLS
|
||||
// If we fail and requireTls is false, we try over TCP
|
||||
|
||||
// TODO: check if insecure is necessary
|
||||
config := &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
|
@ -343,12 +348,22 @@ func (c *Client) establishConnection() error {
|
|||
Timeout: connectionTimeout,
|
||||
}
|
||||
|
||||
conn, err := tls.DialWithDialer(dialer, "tcp", c.Server, config)
|
||||
tlsConn, err := tls.DialWithDialer(dialer, "tcp", c.Server, config)
|
||||
if err == nil {
|
||||
c.conn = tlsConn
|
||||
return nil
|
||||
}
|
||||
if c.requireTls {
|
||||
return err
|
||||
}
|
||||
|
||||
conn, err := net.DialTimeout("tcp", c.Server, connectionTimeout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.conn = conn
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -7,11 +7,11 @@ type Pool struct {
|
|||
}
|
||||
|
||||
// NewPool creates an initialized Pool with a `size` number of clients.
|
||||
func NewPool(size int) *Pool {
|
||||
func NewPool(size int, requireTls bool) *Pool {
|
||||
nextClient := make(chan *Client, size)
|
||||
|
||||
for i := 0; i < size; i++ {
|
||||
nextClient <- NewClient()
|
||||
nextClient <- NewClient(requireTls)
|
||||
}
|
||||
|
||||
return &Pool{nextClient}
|
||||
|
|
|
@ -5,17 +5,21 @@ import "sync/atomic"
|
|||
// ServerProvider manages a rotating server list, from which callers can pull server addresses.
|
||||
type ServerProvider struct {
|
||||
nextIndex int32
|
||||
servers []string
|
||||
}
|
||||
|
||||
// NewServerProvider returns an initialized ServerProvider.
|
||||
func NewServerProvider() *ServerProvider {
|
||||
return &ServerProvider{-1}
|
||||
func NewServerProvider(servers []string) *ServerProvider {
|
||||
return &ServerProvider{
|
||||
nextIndex: -1,
|
||||
servers: servers,
|
||||
}
|
||||
}
|
||||
|
||||
// NextServer returns an address from the rotating list. It's thread-safe.
|
||||
func (p *ServerProvider) NextServer() string {
|
||||
index := int(atomic.AddInt32(&p.nextIndex, 1))
|
||||
return PublicServers[index%len(PublicServers)]
|
||||
return p.servers[index%len(p.servers)]
|
||||
}
|
||||
|
||||
// PublicServers list.
|
||||
|
@ -29,72 +33,73 @@ func (p *ServerProvider) NextServer() string {
|
|||
// See `cmd/survey/main.go`
|
||||
var PublicServers = []string{
|
||||
// Fast servers with batching
|
||||
"blackie.c3-soft.com:57002", // impl: Fulcrum 1.6.0, batching: true, ttc: 0.72, speed: 97, from: fortress.qtornado.com:443
|
||||
"fullnode.titanconnect.ca:50002", // impl: Fulcrum 1.6.0, batching: true, ttc: 0.66, speed: 86, from: fortress.qtornado.com:443
|
||||
"de.poiuty.com:50002", // impl: Fulcrum 1.6.0, batching: true, ttc: 0.76, speed: 78, from: fortress.qtornado.com:443
|
||||
"2ex.digitaleveryware.com:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.68, speed: 68, from: fortress.qtornado.com:443
|
||||
"fortress.qtornado.com:443", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.77, speed: 67, from:
|
||||
"hodlers.beer:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.74, speed: 64, from: fortress.qtornado.com:443
|
||||
"f.keff.org:50002", // impl: Fulcrum 1.6.0, batching: true, ttc: 0.76, speed: 60, from: fortress.qtornado.com:443
|
||||
"e2.keff.org:50002", // impl: Fulcrum 1.6.0, batching: true, ttc: 0.75, speed: 58, from:
|
||||
"electrum.stippy.com:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.75, speed: 56, from: fortress.qtornado.com:443
|
||||
"electrum.privateservers.network:50002", // impl: ElectrumX 1.15.0, batching: true, ttc: 0.83, speed: 52, from: fortress.qtornado.com:443
|
||||
"fulcrum.grey.pw:51002", // impl: Fulcrum 1.6.0, batching: true, ttc: 0.79, speed: 49, from: fortress.qtornado.com:443
|
||||
"btc.electroncash.dk:60002", // impl: Fulcrum 1.6.0, batching: true, ttc: 0.79, speed: 49, from: fortress.qtornado.com:443
|
||||
"node.degga.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.59, speed: 46, from: fortress.qtornado.com:443
|
||||
"e.keff.org:50002", // impl: ElectrumX 1.10.0, batching: true, ttc: 0.76, speed: 45, from:
|
||||
"bitcoin.aranguren.org:50002", // impl: Fulcrum 1.6.0, batching: true, ttc: 1.25, speed: 41, from:
|
||||
"electrum.helali.me:50002", // impl: Fulcrum 1.6.0, batching: true, ttc: 1.20, speed: 38, from: fortress.qtornado.com:443
|
||||
"node1.btccuracao.com:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.79, speed: 33, from: fortress.qtornado.com:443
|
||||
"ASSUREDLY.not.fyi:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.66, speed: 20, from: electrumx.erbium.eu:50002
|
||||
"assuredly.not.fyi:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.74, speed: 20, from: fortress.qtornado.com:443
|
||||
"electrum.coinext.com.br:50002", // impl: ElectrumX 1.14.0, batching: true, ttc: 0.15, speed: 113, from:
|
||||
"fulcrum.sethforprivacy.com:50002", // impl: Fulcrum 1.9.0, batching: true, ttc: 0.55, speed: 96, from:
|
||||
"mainnet.foundationdevices.com:50002", // impl: Fulcrum 1.8.2, batching: true, ttc: 0.54, speed: 88, from:
|
||||
"btc.lastingcoin.net:50002", // impl: Fulcrum 1.7.0, batching: true, ttc: 0.74, speed: 73, from:
|
||||
"vmd71287.contaboserver.net:50002", // impl: Fulcrum 1.9.0, batching: true, ttc: 0.60, speed: 70, from:
|
||||
"de.poiuty.com:50002", // impl: Fulcrum 1.8.2, batching: true, ttc: 0.87, speed: 70, from:
|
||||
"electrum.jochen-hoenicke.de:50006", // impl: Fulcrum 1.8.2, batching: true, ttc: 0.83, speed: 69, from:
|
||||
"btc.cr.ypto.tech:50002", // impl: Fulcrum 1.9.0, batching: true, ttc: 0.81, speed: 65, from:
|
||||
"e.keff.org:50002", // impl: Fulcrum 1.8.2, batching: true, ttc: 0.82, speed: 65, from:
|
||||
"vmd104014.contaboserver.net:50002", // impl: Fulcrum 1.9.0, batching: true, ttc: 0.58, speed: 64, from:
|
||||
"e2.keff.org:50002", // impl: Fulcrum 1.8.2, batching: true, ttc: 0.83, speed: 64, from:
|
||||
"fulcrum.grey.pw:51002", // impl: Fulcrum 1.9.0, batching: true, ttc: 0.81, speed: 63, from:
|
||||
"fortress.qtornado.com:443", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.84, speed: 62, from:
|
||||
"f.keff.org:50002", // impl: Fulcrum 1.8.2, batching: true, ttc: 0.89, speed: 62, from:
|
||||
"2ex.digitaleveryware.com:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.71, speed: 61, from:
|
||||
"electrum.petrkr.net:50002", // impl: Fulcrum 1.9.0, batching: true, ttc: 0.84, speed: 58, from:
|
||||
"electrum.stippy.com:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.80, speed: 57, from:
|
||||
"electrum0.snel.it:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.80, speed: 56, from:
|
||||
"ru.poiuty.com:50002", // impl: Fulcrum 1.8.2, batching: true, ttc: 0.99, speed: 56, from:
|
||||
"electrum.privateservers.network:50002", // impl: ElectrumX 1.15.0, batching: true, ttc: 0.85, speed: 49, from:
|
||||
"btc.electroncash.dk:60002", // impl: Fulcrum 1.9.0, batching: true, ttc: 0.92, speed: 48, from:
|
||||
"bitcoin.aranguren.org:50002", // impl: Fulcrum 1.8.2, batching: true, ttc: 1.19, speed: 48, from:
|
||||
"electrum.bitcoinserver.nl:50514", // impl: Fulcrum 1.8.1, batching: true, ttc: 0.85, speed: 44, from:
|
||||
"btc.prompt.cash:61002", // impl: Fulcrum 1.8.1, batching: true, ttc: 1.22, speed: 44, from:
|
||||
"fulc.bot.nu:50002", // impl: Fulcrum 1.7.0, batching: true, ttc: 1.04, speed: 35, from:
|
||||
"bolt.schulzemic.net:50002", // impl: Fulcrum 1.8.2, batching: true, ttc: 0.96, speed: 33, from:
|
||||
"node1.btccuracao.com:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.90, speed: 25, from:
|
||||
|
||||
// Other servers
|
||||
"smmalis37.ddns.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.56, speed: 19, from: fortress.qtornado.com:443
|
||||
"electrumx.papabyte.com:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.95, speed: 19, from: fortress.qtornado.com:443
|
||||
"electrum.bitaroo.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.98, speed: 19, from: fortress.qtornado.com:443
|
||||
"electrum.exan.tech:443", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.08, speed: 19, from: fortress.qtornado.com:443
|
||||
"electrum-fulcrum.toggen.net:50002", // impl: Fulcrum 1.6.0, batching: true, ttc: 1.47, speed: 16, from: fortress.qtornado.com:443
|
||||
"vmd84592.contaboserver.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.79, speed: 14, from: fortress.qtornado.com:443
|
||||
"gd42.org:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.50, speed: 12, from: fortress.qtornado.com:443
|
||||
"vmd63185.contaboserver.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.75, speed: 12, from: fortress.qtornado.com:443
|
||||
"alfa.cryptotrek.online:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.75, speed: 12, from: fortress.qtornado.com:443
|
||||
"electrumx.ultracloud.tk:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.76, speed: 12, from: fortress.qtornado.com:443
|
||||
"electrum.brainshome.de:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.89, speed: 12, from: fortress.qtornado.com:443
|
||||
"ragtor.duckdns.org:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.91, speed: 12, from: bitcoin.aranguren.org:50002
|
||||
"94.23.247.135:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 6.80, speed: 12, from: fortress.qtornado.com:443
|
||||
"eai.coincited.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.12, speed: 11, from: electrumx.erbium.eu:50002
|
||||
"142.93.6.38:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.56, speed: 11, from: fortress.qtornado.com:443
|
||||
"157.245.172.236:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.62, speed: 11, from: fortress.qtornado.com:443
|
||||
"electrum.kendigisland.xyz:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.68, speed: 11, from: fortress.qtornado.com:443
|
||||
"btc.lastingcoin.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.74, speed: 11, from: fortress.qtornado.com:443
|
||||
"xtrum.com:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.75, speed: 11, from: electrumx.erbium.eu:50002
|
||||
"blkhub.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.76, speed: 11, from: fortress.qtornado.com:443
|
||||
"electrumx.erbium.eu:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.78, speed: 11, from:
|
||||
"185.64.116.15:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.79, speed: 11, from: bitcoin.aranguren.org:50002
|
||||
"188.165.206.215:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.81, speed: 11, from: fortress.qtornado.com:443
|
||||
"ex03.axalgo.com:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.92, speed: 11, from: fortress.qtornado.com:443
|
||||
"electrum.bitcoinlizard.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.98, speed: 11, from: fortress.qtornado.com:443
|
||||
"btce.iiiiiii.biz:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.02, speed: 11, from: fortress.qtornado.com:443
|
||||
"btc.ocf.sh:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.15, speed: 11, from: fortress.qtornado.com:443
|
||||
"68.183.188.105:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.36, speed: 11, from: fortress.qtornado.com:443
|
||||
"vmd71287.contaboserver.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.60, speed: 10, from: fortress.qtornado.com:443
|
||||
"2electrumx.hopto.me:56022", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.89, speed: 10, from: fortress.qtornado.com:443
|
||||
"electrum.emzy.de:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.15, speed: 10, from:
|
||||
"electrumx.electricnewyear.net:50002", // impl: ElectrumX 1.15.0, batching: true, ttc: 0.66, speed: 9, from:
|
||||
"walle.dedyn.io:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.76, speed: 8, from: fortress.qtornado.com:443
|
||||
"caleb.vegas:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.80, speed: 8, from: fortress.qtornado.com:443
|
||||
"electrum.neocrypto.io:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.69, speed: 7, from: fortress.qtornado.com:443
|
||||
"guichet.centure.cc:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.71, speed: 7, from: fortress.qtornado.com:443
|
||||
"167.172.42.31:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.75, speed: 7, from: fortress.qtornado.com:443
|
||||
"2AZZARITA.hopto.org:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.77, speed: 7, from: fortress.qtornado.com:443
|
||||
"jonas.reptiles.se:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.95, speed: 7, from: fortress.qtornado.com:443
|
||||
"167.172.226.175:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.61, speed: 6, from: fortress.qtornado.com:443
|
||||
"electrum-btc.leblancnet.us:50002", // impl: ElectrumX 1.15.0, batching: true, ttc: 0.64, speed: 6, from: fortress.qtornado.com:443
|
||||
"104.248.139.211:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.90, speed: 6, from: fortress.qtornado.com:443
|
||||
"elx.bitske.com:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.01, speed: 6, from: fortress.qtornado.com:443
|
||||
"kareoke.qoppa.org:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.18, speed: 6, from: electrumx.erbium.eu:50002
|
||||
"ex.btcmp.com:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.12, speed: 5, from: fortress.qtornado.com:443
|
||||
"bitcoins.sk:56002", // impl: ElectrumX 1.14.0, batching: true, ttc: 0.77, speed: 3, from: fortress.qtornado.com:443
|
||||
"73.92.198.54:50002", // impl: ElectrumX 1.15.0, batching: true, ttc: 5.57, speed: 0, from: fortress.qtornado.com:443
|
||||
"xtrum.com:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.91, speed: 19, from: fulcrum.sethforprivacy.com:50002
|
||||
"electrum.bitaroo.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.04, speed: 19, from:
|
||||
"btce.iiiiiii.biz:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.07, speed: 19, from: electrum.coinext.com.br:50002
|
||||
"electrum.emzy.de:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.17, speed: 19, from:
|
||||
"alviss.coinjoined.com:50002", // impl: ElectrumX 1.15.0, batching: true, ttc: 1.15, speed: 17, from:
|
||||
"2AZZARITA.hopto.org:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.81, speed: 16, from: electrum.coinext.com.br:50002
|
||||
"vmd104012.contaboserver.net:50002", // impl: Fulcrum 1.9.0, batching: true, ttc: 1.25, speed: 16, from:
|
||||
"electrum.bitcoinlizard.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 4.99, speed: 14, from:
|
||||
"btc.ocf.sh:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.19, speed: 12, from:
|
||||
"bitcoins.sk:56002", // impl: ElectrumX 1.14.0, batching: true, ttc: 0.80, speed: 11, from:
|
||||
"electrum-btc.leblancnet.us:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.04, speed: 11, from:
|
||||
"helicarrier.bauerj.eu:50002", // impl: ElectrumX 1.10.0, batching: true, ttc: 0.96, speed: 10, from:
|
||||
"electrum.neocrypto.io:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.69, speed: 7, from:
|
||||
"caleb.vegas:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.71, speed: 7, from:
|
||||
"smmalis37.ddns.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.77, speed: 7, from:
|
||||
"2azzarita.hopto.org:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.78, speed: 7, from: fulcrum.sethforprivacy.com:50002
|
||||
"electrum.kendigisland.xyz:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.79, speed: 7, from:
|
||||
"electrum.hsmiths.com:50002", // impl: ElectrumX 1.10.0, batching: true, ttc: 0.90, speed: 7, from:
|
||||
"vmd63185.contaboserver.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.92, speed: 7, from:
|
||||
"blkhub.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.94, speed: 7, from:
|
||||
"electrum.mmitech.info:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.95, speed: 7, from:
|
||||
"elx.bitske.com:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.17, speed: 7, from:
|
||||
"bitcoin.lu.ke:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.21, speed: 7, from:
|
||||
"ex05.axalgo.com:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.21, speed: 7, from:
|
||||
"walle.dedyn.io:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.23, speed: 7, from:
|
||||
"eai.coincited.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.34, speed: 6, from:
|
||||
"2electrumx.hopto.me:56022", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.93, speed: 6, from:
|
||||
"hodlers.beer:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.03, speed: 6, from:
|
||||
"kareoke.qoppa.org:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.13, speed: 6, from:
|
||||
"ASSUREDLY.not.fyi:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.85, speed: 4, from:
|
||||
"electrumx.alexridevski.net:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.87, speed: 4, from:
|
||||
"assuredly.not.fyi:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 0.90, speed: 4, from:
|
||||
"ragtor.duckdns.org:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.07, speed: 4, from:
|
||||
"surely.not.fyi:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.20, speed: 4, from:
|
||||
"btc.electrum.bitbitnet.net:50002", // impl: ElectrumX 1.15.0, batching: true, ttc: 0.71, speed: 3, from:
|
||||
"gods-of-rock.screaminglemur.net:50002", // impl: ElectrumX 1.15.0, batching: true, ttc: 0.92, speed: 3, from:
|
||||
"SURELY.not.fyi:50002", // impl: ElectrumX 1.16.0, batching: true, ttc: 1.35, speed: 3, from:
|
||||
"horsey.cryptocowboys.net:50002", // impl: ElectrumX 1.15.0, batching: true, ttc: 0.61, speed: 2, from:
|
||||
"electrumx-btc.cryptonermal.net:50002", // impl: ElectrumX 1.15.0, batching: true, ttc: 0.83, speed: 1, from:
|
||||
"electrum.coineuskal.com:50002", // impl: ElectrumX 1.15.0, batching: true, ttc: 1.73, speed: 0, from: electrum.coinext.com.br:50002
|
||||
}
|
||||
|
|
81
main.go
81
main.go
|
@ -14,19 +14,31 @@ import (
|
|||
"github.com/muun/libwallet"
|
||||
"github.com/muun/libwallet/btcsuitew/btcutilw"
|
||||
"github.com/muun/libwallet/emergencykit"
|
||||
"github.com/muun/recovery/electrum"
|
||||
"github.com/muun/recovery/scanner"
|
||||
"github.com/muun/recovery/utils"
|
||||
)
|
||||
|
||||
const electrumPoolSize = 6
|
||||
|
||||
var debugOutputStream = bytes.NewBuffer(nil)
|
||||
|
||||
type config struct {
|
||||
generateContacts bool
|
||||
providedElectrum string
|
||||
usesProvidedElectrum bool
|
||||
onlyScan bool
|
||||
}
|
||||
|
||||
func main() {
|
||||
utils.SetOutputStream(debugOutputStream)
|
||||
|
||||
var generateContacts bool
|
||||
var config config
|
||||
|
||||
// Pick up command-line arguments:
|
||||
flag.BoolVar(&generateContacts, "generate-contacts", false, "Generate contact addresses")
|
||||
flag.BoolVar(&config.generateContacts, "generate-contacts", false, "Generate contact addresses")
|
||||
flag.StringVar(&config.providedElectrum, "electrum-server", "", "Connect to this electrum server to find funds")
|
||||
flag.BoolVar(&config.onlyScan, "only-scan", false, "Only scan for UTXOs without generating a transaction")
|
||||
flag.Usage = printUsage
|
||||
flag.Parse()
|
||||
args := flag.Args()
|
||||
|
@ -40,6 +52,11 @@ func main() {
|
|||
// Welcome!
|
||||
printWelcomeMessage()
|
||||
|
||||
config.usesProvidedElectrum = len(strings.TrimSpace(config.providedElectrum)) > 0
|
||||
if config.usesProvidedElectrum {
|
||||
validateProvidedElectrum(config.providedElectrum)
|
||||
}
|
||||
|
||||
// We're going to need a few things to move forward with the recovery process. Let's make a list
|
||||
// so we keep them in mind:
|
||||
var recoveryCode string
|
||||
|
@ -62,25 +79,41 @@ func main() {
|
|||
|
||||
decryptedKeys[0].Key.Path = "m/1'/1'" // a little adjustment for legacy users.
|
||||
|
||||
// Finally, we need the destination address to sweep the funds:
|
||||
destinationAddress = readAddress()
|
||||
if !config.onlyScan {
|
||||
// Finally, we need the destination address to sweep the funds:
|
||||
destinationAddress = readAddress()
|
||||
}
|
||||
|
||||
sayBlock(`
|
||||
Starting scan of all possible addresses. This will take a few minutes.
|
||||
`)
|
||||
|
||||
doRecovery(decryptedKeys, destinationAddress, generateContacts)
|
||||
doRecovery(decryptedKeys, destinationAddress, config)
|
||||
|
||||
sayBlock("We appreciate all kinds of feedback. If you have any, send it to {blue contact@muun.com}\n")
|
||||
}
|
||||
|
||||
// doRecovery runs the scan & sweep process, and returns the ID of the broadcasted transaction.
|
||||
func doRecovery(
|
||||
decryptedKeys []*libwallet.DecryptedPrivateKey, destinationAddress btcutil.Address, generateContacts bool,
|
||||
decryptedKeys []*libwallet.DecryptedPrivateKey,
|
||||
destinationAddress btcutil.Address,
|
||||
config config,
|
||||
) {
|
||||
|
||||
addrGen := NewAddressGenerator(decryptedKeys[0].Key, decryptedKeys[1].Key, generateContacts)
|
||||
utxoScanner := scanner.NewScanner()
|
||||
addrGen := NewAddressGenerator(decryptedKeys[0].Key, decryptedKeys[1].Key, config.generateContacts)
|
||||
|
||||
var electrumProvider *electrum.ServerProvider
|
||||
if config.usesProvidedElectrum {
|
||||
electrumProvider = electrum.NewServerProvider([]string{
|
||||
config.providedElectrum,
|
||||
})
|
||||
} else {
|
||||
electrumProvider = electrum.NewServerProvider(electrum.PublicServers)
|
||||
}
|
||||
|
||||
connectionPool := electrum.NewPool(electrumPoolSize, !config.usesProvidedElectrum)
|
||||
|
||||
utxoScanner := scanner.NewScanner(connectionPool, electrumProvider)
|
||||
|
||||
addresses := addrGen.Stream()
|
||||
|
||||
|
@ -122,6 +155,9 @@ func doRecovery(
|
|||
}
|
||||
|
||||
say("\n— {white %d} sats total\n", total)
|
||||
if config.onlyScan {
|
||||
return
|
||||
}
|
||||
|
||||
txOutputAmount, txWeightInBytes, err := sweeper.GetSweepTxAmountAndWeightInBytes(utxos)
|
||||
if err != nil {
|
||||
|
@ -145,11 +181,36 @@ func doRecovery(
|
|||
|
||||
sayBlock(`
|
||||
Transaction sent! You can check the status here: https://mempool.space/tx/%v
|
||||
(it will appear in Blockstream after a short delay)
|
||||
(it will appear in mempool.space after a short delay)
|
||||
|
||||
`, sweepTx.TxHash().String())
|
||||
}
|
||||
|
||||
func validateProvidedElectrum(providedElectrum string) {
|
||||
client := electrum.NewClient(false)
|
||||
err := client.Connect(providedElectrum)
|
||||
defer func(client *electrum.Client) {
|
||||
_ = client.Disconnect()
|
||||
}(client)
|
||||
|
||||
if err != nil {
|
||||
sayBlock(`
|
||||
{red Error!}
|
||||
The Recovery Tool couldn't connect to the provided Electrum server %v.
|
||||
|
||||
If the problem persists, contact {blue support@muun.com}.
|
||||
|
||||
――― {white error report} ―――
|
||||
%v
|
||||
――――――――――――――――――――
|
||||
|
||||
We're always there to help.
|
||||
`, providedElectrum, err)
|
||||
|
||||
os.Exit(2)
|
||||
}
|
||||
}
|
||||
|
||||
func exitWithError(err error) {
|
||||
sayBlock(`
|
||||
{red Error!}
|
||||
|
@ -351,7 +412,7 @@ func readAddress() btcutil.Address {
|
|||
func readFee(totalBalance, weight int64) int64 {
|
||||
sayBlock(`
|
||||
{yellow Enter the fee rate (sats/byte)}
|
||||
Your transaction weighs %v bytes. You can get suggestions in https://bitcoinfees.earn.com/#fees
|
||||
Your transaction weighs %v bytes. You can get suggestions in https://mempool.space/ under "Transaction fees".
|
||||
`, weight)
|
||||
|
||||
var userInput string
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/muun/recovery/utils"
|
||||
)
|
||||
|
||||
const electrumPoolSize = 6
|
||||
const taskTimeout = 15 * time.Minute
|
||||
const batchSize = 100
|
||||
|
||||
|
@ -70,10 +69,10 @@ type scanContext struct {
|
|||
}
|
||||
|
||||
// NewScanner creates an initialized Scanner.
|
||||
func NewScanner() *Scanner {
|
||||
func NewScanner(connectionPool *electrum.Pool, electrumProvider *electrum.ServerProvider) *Scanner {
|
||||
return &Scanner{
|
||||
pool: electrum.NewPool(electrumPoolSize),
|
||||
servers: electrum.NewServerProvider(),
|
||||
pool: connectionPool,
|
||||
servers: electrumProvider,
|
||||
log: utils.NewLogger("Scanner"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ type surveyTask struct {
|
|||
}
|
||||
|
||||
// Values to check whether we're in the same chain (in a previous version, SV servers snuck in)
|
||||
var mainnetSomeTx = "1712426823cc94935287a6834f7982723fbb5c808cbe00ec2cf3f582582be4c5"
|
||||
var mainnetSomeTx = "985eb411473fa1bbd73efa5e3685edc00366c86b8d4d3f5b969ad59c23f4d959"
|
||||
var mainnetGenesisHash = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
||||
|
||||
func NewSurvey(config *Config) *Survey {
|
||||
|
@ -194,7 +194,7 @@ func (s *Survey) processTask(task *surveyTask) *Result {
|
|||
|
||||
// testConnection returns the server implementation, protocol version and time to connect
|
||||
func testConnection(task *surveyTask) (string, string, time.Duration, error) {
|
||||
client := electrum.NewClient()
|
||||
client := electrum.NewClient(true)
|
||||
|
||||
start := time.Now()
|
||||
err := client.Connect(task.server)
|
||||
|
@ -207,7 +207,7 @@ func testConnection(task *surveyTask) (string, string, time.Duration, error) {
|
|||
|
||||
// testsBlockchain returns whether this server is operating on Bitcoin mainnet
|
||||
func testBitcoinMainnet(task *surveyTask) (bool, error) {
|
||||
client := electrum.NewClient()
|
||||
client := electrum.NewClient(true)
|
||||
|
||||
err := client.Connect(task.server)
|
||||
if err != nil {
|
||||
|
@ -229,7 +229,7 @@ func testBitcoinMainnet(task *surveyTask) (bool, error) {
|
|||
|
||||
// testBatchSupport returns whether the server successfully responded to a batched request
|
||||
func testBatchSupport(task *surveyTask) (bool, error) {
|
||||
client := electrum.NewClient()
|
||||
client := electrum.NewClient(true)
|
||||
|
||||
err := client.Connect(task.server)
|
||||
if err != nil {
|
||||
|
@ -247,7 +247,7 @@ func testBatchSupport(task *surveyTask) (bool, error) {
|
|||
// measureSpeed returns the amount of successful ListUnspentBatch calls in SPEED_TEST_DURATION
|
||||
// seconds. It assumes batch support was verified beforehand.
|
||||
func (s *Survey) measureSpeed(task *surveyTask) (int, error) {
|
||||
client := electrum.NewClient()
|
||||
client := electrum.NewClient(true)
|
||||
|
||||
err := client.Connect(task.server)
|
||||
if err != nil {
|
||||
|
@ -273,7 +273,7 @@ func (s *Survey) measureSpeed(task *surveyTask) (int, error) {
|
|||
|
||||
// getPeers returns the list of peers from a server, or empty if it doesn't responds to the request
|
||||
func getPeers(task *surveyTask) ([]string, error) {
|
||||
client := electrum.NewClient()
|
||||
client := electrum.NewClient(true)
|
||||
|
||||
err := client.Connect(task.server)
|
||||
if err != nil {
|
||||
|
|
|
@ -54,8 +54,8 @@ func (s *Sweeper) BuildSweepTx(utxos []*scanner.Utxo, fee int64) (*wire.MsgTx, e
|
|||
|
||||
func (s *Sweeper) BroadcastTx(tx *wire.MsgTx) error {
|
||||
// Connect to an Electurm server using a fresh client and provider pair:
|
||||
sp := electrum.NewServerProvider() // TODO create servers module, for provider and pool
|
||||
client := electrum.NewClient()
|
||||
sp := electrum.NewServerProvider(electrum.PublicServers) // TODO create servers module, for provider and pool
|
||||
client := electrum.NewClient(true)
|
||||
|
||||
for !client.IsConnected() {
|
||||
client.Connect(sp.NextServer())
|
||||
|
|
|
@ -3,4 +3,4 @@ package main
|
|||
// The OSS tool depends on this file with this content. If you need to change
|
||||
// it, change the tool too.
|
||||
|
||||
const version = "2.2.3"
|
||||
const version = "2.2.4"
|
||||
|
|
Loading…
Reference in New Issue