Skip to content
This repository has been archived by the owner on Mar 2, 2023. It is now read-only.

Commit

Permalink
Fix ability to specify backend server and default server
Browse files Browse the repository at this point in the history
For electrum, the address must be HOST:tPORT or HOST:sPORT. If addr is
not specified, we default to the initial hardcoded node.

For btcd, the address must be HOST:PORT. If addr is not specifed, we
default to localhost:8334.
  • Loading branch information
alokmenghrajani committed Oct 25, 2018
1 parent f33cbb7 commit 322ca8f
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 38 deletions.
4 changes: 2 additions & 2 deletions backend/btcd_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ const (
// BtcdBackend is meants to connect to a personal Btcd node (because public nodes don't expose the
// API we need). There's no TLS support. If your node is not co-located with Beancounter, we
// recommend wrapping your connection in a ssh or other secure tunnel.
func NewBtcdBackend(hostPort, user, pass string, network utils.Network) (*BtcdBackend, error) {
func NewBtcdBackend(host, port, user, pass string, network utils.Network) (*BtcdBackend, error) {
connCfg := &rpcclient.ConnConfig{
Host: hostPort,
Host: fmt.Sprintf("%s:%s", host, port),
User: user,
Pass: pass,
HTTPPostMode: true, // Bitcoin core only supports HTTP POST mode
Expand Down
4 changes: 4 additions & 0 deletions backend/electrum/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ func NewNode(addr, port string, network utils.Network) (*Node, error) {
}

if port[0] == 't' {
// TCP
var p string
if len(port) == 1 {
p = defaultTCP
Expand All @@ -147,13 +148,16 @@ func NewNode(addr, port string, network utils.Network) (*Node, error) {
}
t, err = NewTCPTransport(fmt.Sprintf("%s:%s", a, p))
} else if port[0] == 's' {
// TLS
var p string
if len(port) == 1 {
p = defaultSSL
} else {
p = port[1:]
}
t, err = NewSSLTransport(fmt.Sprintf("%s:%s", a, p))
} else {
panic(fmt.Sprintf("port (%s) must start with t or s", port))
}

if err != nil {
Expand Down
46 changes: 14 additions & 32 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import (
"github.com/square/beancounter/blockfinder"
"log"
"math"
"net"
"os"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -37,7 +35,7 @@ var (
findBlock = app.Command("find-block", "Finds the block height for a given date/time.")
findBlockTimestamp = findBlock.Arg("timestamp", "Date/time to resolve. E.g. \"2006-01-02 15:04:05 MST\"").Required().String()
findBlockBackend = findBlock.Flag("backend", "electrum | btcd | electrum-recorder | btcd-recorder | fixture").Default("electrum").Enum("electrum", "btcd", "electrum-recorder", "btcd-recorder", "fixture")
findBlockAddr = findBlock.Flag("addr", "Backend to connect to initially. Defaults to a hardcoded node for Electrum and localhost for Btcd.").PlaceHolder("HOST:PORT").TCP()
findBlockAddr = findBlock.Flag("addr", "Backend to connect to initially. Defaults to a hardcoded node for Electrum and localhost for Btcd.").PlaceHolder("HOST:PORT").String()
findBlockRpcUser = findBlock.Flag("rpcuser", "RPC username").PlaceHolder("USER").String()
findBlockRpcPass = findBlock.Flag("rpcpass", "RPC password").PlaceHolder("PASSWORD").String()
findBlockFixtureFile = findBlock.Flag("fixture-file", "Fixture file to use for recording or replaying data.").PlaceHolder("FILEPATH").String()
Expand All @@ -48,7 +46,7 @@ var (
computeBalanceM = computeBalance.Flag("m", "number of signatures (quorum)").Short('m').Default("1").Int()
computeBalanceN = computeBalance.Flag("n", "number of public keys").Short('n').Default("1").Int()
computeBalanceBackend = computeBalance.Flag("backend", "electrum | btcd | electrum-recorder | btcd-recorder | fixture").Default("electrum").Enum("electrum", "btcd", "electrum-recorder", "btcd-recorder", "fixture")
computeBalanceAddr = computeBalance.Flag("addr", "Backend to connect to initially. Defaults to a hardcoded node for Electrum and localhost for Btcd.").PlaceHolder("HOST:PORT").TCP()
computeBalanceAddr = computeBalance.Flag("addr", "Backend to connect to initially. Defaults to a hardcoded node for Electrum and localhost for Btcd.").PlaceHolder("HOST:PORT").String()
computeBalanceRpcUser = computeBalance.Flag("rpcuser", "RPC username").PlaceHolder("USER").String()
computeBalanceRpcPass = computeBalance.Flag("rpcpass", "RPC password").PlaceHolder("PASSWORD").String()
computeBalanceFixtureFile = computeBalance.Flag("fixture-file", "Fixture file to use for recording or replaying data.").PlaceHolder("FILEPATH").String()
Expand Down Expand Up @@ -252,22 +250,22 @@ func findBlockBuildBackend(network Network) (backend.Backend, error) {
var err error
switch *findBlockBackend {
case "electrum":
addr, port := getServer(network, *findBlockAddr)
addr, port := GetDefaultServer(network, Electrum, *findBlockAddr)
b, err = backend.NewElectrumBackend(addr, port, network)
if err != nil {
return nil, err
}
case "btcd":
b, err = backend.NewBtcdBackend((**findBlockAddr).String(), *findBlockRpcUser,
*findBlockRpcPass, network)
addr, port := GetDefaultServer(network, Btcd, *findBlockAddr)
b, err = backend.NewBtcdBackend(addr, port, *findBlockRpcUser, *findBlockRpcPass, network)
if err != nil {
return nil, err
}
case "electrum-recorder":
if *findBlockFixtureFile == "" {
panic("electrum-recorder backend requires output --fixture-file.")
}
addr, port := getServer(network, *findBlockAddr)
addr, port := GetDefaultServer(network, Electrum, *findBlockAddr)
b, err = backend.NewElectrumBackend(addr, port, network)
if err != nil {
return nil, err
Expand All @@ -277,8 +275,8 @@ func findBlockBuildBackend(network Network) (backend.Backend, error) {
if *findBlockFixtureFile == "" {
panic("btcd-recorder backend requires output --fixture-file.")
}
b, err = backend.NewBtcdBackend((*findBlockAddr).String(), *findBlockRpcUser,
*findBlockRpcPass, network)
addr, port := GetDefaultServer(network, Btcd, *findBlockAddr)
b, err = backend.NewBtcdBackend(addr, port, *findBlockRpcUser, *findBlockRpcPass, network)
if err != nil {
return nil, err
}
Expand All @@ -303,22 +301,22 @@ func computeBalanceBuildBackend(network Network) (backend.Backend, error) {
var err error
switch *computeBalanceBackend {
case "electrum":
addr, port := getServer(network, *computeBalanceAddr)
addr, port := GetDefaultServer(network, Electrum, *computeBalanceAddr)
b, err = backend.NewElectrumBackend(addr, port, network)
if err != nil {
return nil, err
}
case "btcd":
b, err = backend.NewBtcdBackend((*computeBalanceAddr).String(), *computeBalanceRpcUser,
*computeBalanceRpcPass, network)
addr, port := GetDefaultServer(network, Btcd, *computeBalanceAddr)
b, err = backend.NewBtcdBackend(addr, port, *computeBalanceRpcUser, *computeBalanceRpcPass, network)
if err != nil {
return nil, err
}
case "electrum-recorder":
if *computeBalanceFixtureFile == "" {
panic("electrum-recorder backend requires output --fixture-file.")
}
addr, port := getServer(network, *computeBalanceAddr)
addr, port := GetDefaultServer(network, Electrum, *computeBalanceAddr)
b, err = backend.NewElectrumBackend(addr, port, network)
if err != nil {
return nil, err
Expand All @@ -328,8 +326,8 @@ func computeBalanceBuildBackend(network Network) (backend.Backend, error) {
if *computeBalanceFixtureFile == "" {
panic("btcd-recorder backend requires output --fixture-file.")
}
b, err = backend.NewBtcdBackend((*computeBalanceAddr).String(), *computeBalanceRpcUser,
*computeBalanceRpcPass, network)
addr, port := GetDefaultServer(network, Btcd, *computeBalanceAddr)
b, err = backend.NewBtcdBackend(addr, port, *computeBalanceRpcUser, *computeBalanceRpcPass, network)
if err != nil {
return nil, err
}
Expand All @@ -347,19 +345,3 @@ func computeBalanceBuildBackend(network Network) (backend.Backend, error) {
}
return b, err
}

// pick a default server for each network if none provided
// TODO: default server should be localhost for Btcd backend.
func getServer(network Network, addr *net.TCPAddr) (string, string) {
if addr != nil {
return addr.IP.String(), strconv.Itoa(addr.Port)
}
switch network {
case "mainnet":
return "electrum.petrkr.net", "s50002"
case "testnet":
return "electrum_testnet_unlimited.criptolayer.net", "s50102"
default:
panic("unreachable")
}
}
44 changes: 40 additions & 4 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package utils

import (
"fmt"
"net"

"github.com/btcsuite/btcd/chaincfg"
)
Expand All @@ -24,6 +25,14 @@ func Max(num uint32, nums ...uint32) uint32 {
}

type Network string
type Backend string

const (
Mainnet Network = "mainnet"
Testnet Network = "testnet"
Electrum Backend = "electrum"
Btcd Backend = "btcd"
)

// ChainConfig returns a given chaincfg.Params for a given Network
func (n Network) ChainConfig() *chaincfg.Params {
Expand Down Expand Up @@ -94,7 +103,34 @@ func VerifyMandN(m int, n int) error {
return nil
}

const (
Mainnet Network = "mainnet"
Testnet Network = "testnet"
)
// Picks a default server for electrum or localhost for btcd
// Returns a pair of hostname:port (or pseudo-port for electrum)
func GetDefaultServer(network Network, backend Backend, addr string) (string, string) {
if addr != "" {
host, port, err := net.SplitHostPort(addr)
PanicOnError(err)
return host, port
}
switch backend {
case Electrum:
switch network {
case "mainnet":
return "electrum.petrkr.net", "s50002"
case "testnet":
return "electrum_testnet_unlimited.criptolayer.net", "s50102"
default:
panic("unreachable")
}
case Btcd:
switch network {
case "mainnet":
return "localhost", "8334"
case "testnet":
return "localhost", "18334"
default:
panic("unreachable")
}
default:
panic("unreachable")
}
}
26 changes: 26 additions & 0 deletions utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,29 @@ func TestVerifyMandN(t *testing.T) {
assert.Nil(t, VerifyMandN(5, 20))
assert.Nil(t, VerifyMandN(20, 20))
}

func TestGetDefaultServer(t *testing.T) {
host, port := GetDefaultServer(Testnet, Electrum, "foobar:s1234")
assert.Equal(t, "foobar", host)
assert.Equal(t, "s1234", port)

host, port = GetDefaultServer(Testnet, Electrum, "192.0.2.5:s1234")
assert.Equal(t, "192.0.2.5", host)
assert.Equal(t, "s1234", port)

host, port = GetDefaultServer(Testnet, Electrum, "[2001:db8::1]:s1234")
assert.Equal(t, "2001:db8::1", host)
assert.Equal(t, "s1234", port)

host, port = GetDefaultServer(Testnet, Btcd, "foobar:1234")
assert.Equal(t, "foobar", host)
assert.Equal(t, "1234", port)

host, port = GetDefaultServer(Testnet, Electrum, "")
assert.NotEqual(t, "localhost", host)
assert.Equal(t, "s50102", port)

host, port = GetDefaultServer(Testnet, Btcd, "")
assert.Equal(t, "localhost", host)
assert.Equal(t, "18334", port)
}

0 comments on commit 322ca8f

Please sign in to comment.