New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Client code for ServiceRegistry with ability to set service URI in CLI #456
Changes from all commits
94d8edc
c9f5ae5
33beed1
d6b4c79
7331df4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,8 @@ import ( | |
"fmt" | ||
"io/ioutil" | ||
"math/big" | ||
"net/http" | ||
"net/url" | ||
"os" | ||
"os/signal" | ||
"os/user" | ||
|
@@ -91,7 +93,7 @@ func main() { | |
ipfsPath := flag.String("ipfsPath", fmt.Sprintf("%v/.ipfs", usr.HomeDir), "IPFS path") | ||
noIPFSLogFiles := flag.Bool("noIPFSLogFiles", false, "Set to true if log files should not be generated") | ||
offchain := flag.Bool("offchain", false, "Set to true to start the node in offchain mode") | ||
publicIP := flag.String("publicIP", "", "Explicit set node IP address so nodes that need a well-known address can advertise it to the network") | ||
publicAddr := flag.String("publicAddr", "", "Public address that broadcasters can use to contact this node; may be an IP or hostname. If used, should match the on-chain ServiceURI set via livepeer_cli") | ||
initializeRound := flag.Bool("initializeRound", false, "Set to true if running as a transcoder and the node should automatically initialize new rounds") | ||
version := flag.Bool("version", false, "Print out the version") | ||
|
||
|
@@ -191,15 +193,7 @@ func main() { | |
glog.Errorf("Error creating a new node: %v", err) | ||
return | ||
} | ||
if *transcoder && *publicIP == "" { | ||
glog.Errorf("Error - transcoder needs to specify publicIP") | ||
return | ||
} | ||
if *transcoder && *publicIP == "" { | ||
glog.Errorf("Error - transcoder needs to specify publicIP") | ||
return | ||
} | ||
nw, err := bnet.NewBasicVideoNetwork(node, *publicIP, *port) | ||
nw, err := bnet.NewBasicVideoNetwork(node, "127.0.0.1", *port) | ||
if err != nil { | ||
glog.Errorf("Cannot create network node: %v", err) | ||
return | ||
|
@@ -333,7 +327,7 @@ func main() { | |
ctx, cancel := context.WithCancel(context.Background()) | ||
defer cancel() | ||
|
||
if err := setupTranscoder(ctx, n, em, *ipfsPath, *initializeRound); err != nil { | ||
if err := setupTranscoder(ctx, n, em, *ipfsPath, *initializeRound, *publicAddr); err != nil { | ||
glog.Errorf("Error setting up transcoder: %v", err) | ||
return | ||
} | ||
|
@@ -493,7 +487,7 @@ func getLPKeys(datadir string) (crypto.PrivKey, crypto.PubKey, error) { | |
return priv, pub, nil | ||
} | ||
|
||
func setupTranscoder(ctx context.Context, n *core.LivepeerNode, em eth.EventMonitor, ipfsPath string, initializeRound bool) error { | ||
func setupTranscoder(ctx context.Context, n *core.LivepeerNode, em eth.EventMonitor, ipfsPath string, initializeRound bool, publicAddr string) error { | ||
//Check if transcoder is active | ||
active, err := n.Eth.IsActiveTranscoder() | ||
if err != nil { | ||
|
@@ -506,6 +500,35 @@ func setupTranscoder(ctx context.Context, n *core.LivepeerNode, em eth.EventMoni | |
glog.Infof("Transcoder %v is active", n.Eth.Account().Address.Hex()) | ||
} | ||
|
||
if publicAddr == "" { | ||
// TODO probably should put this (along w wizard GETs) into common code | ||
resp, err := http.Get("https://api.ipify.org?format=text") | ||
defer resp.Body.Close() | ||
body, err := ioutil.ReadAll(resp.Body) | ||
if err != nil { | ||
glog.Error("Could not look up public IP address") | ||
return err | ||
} | ||
publicAddr = strings.TrimSpace(string(body)) | ||
} | ||
uriStr, err := n.Eth.GetServiceURI(n.Eth.Account().Address) | ||
if err != nil { | ||
glog.Error("Could not get service URI") | ||
return err | ||
} | ||
uri, err := url.ParseRequestURI(uriStr) | ||
if err != nil { | ||
glog.Error("Could not parse service URI") | ||
uri, _ = url.ParseRequestURI("http://127.0.0.1") | ||
} | ||
if uri.Hostname() != publicAddr { | ||
glog.Errorf("Service address %v did not match discovered address %v; set the correct address in livepeer_cli or use -publicAddr", uri.Hostname(), publicAddr) | ||
// TODO remove '&& false' after all transcoders have set a service URI | ||
if active && false { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm so after we remove the Not really a big concern IMO since the CLI makes you pick a service URI upon transcoder registration (the scenario would really only happen if someone registered as a transcoder outside of the CLI and chose to leave out the service URI), but just thought I would note the scenario. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct, the Also correct that Since we have the fallback, we could still kill the node by default to force transcoders to make the adjustment, but I figured it's nicer to be a little less abrupt during the transition. We probably should monitor this though. The current transcoder pool is small enough that we could reach out to individual transcoders after a few weeks, if needed. |
||
return fmt.Errorf("Mismatched service address") | ||
} | ||
} | ||
|
||
// Set up IPFS | ||
ipfsApi, err := ipfs.StartIpfs(ctx, ipfsPath) | ||
if err != nil { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,16 +5,29 @@ import ( | |
"math/big" | ||
"net/url" | ||
"strconv" | ||
"strings" | ||
|
||
lpcommon "github.com/livepeer/go-livepeer/common" | ||
) | ||
|
||
const defaultRPCPort = "4433" | ||
|
||
func (w *wizard) isTranscoder() bool { | ||
isT := httpGet(fmt.Sprintf("http://%v:%v/IsTranscoder", w.host, w.httpPort)) | ||
return isT == "true" | ||
} | ||
|
||
func (w *wizard) promptTranscoderConfig() (float64, float64, *big.Int) { | ||
func myHostPort() string { | ||
// TODO Fall back to try other services if this one fails. Ask a peer? | ||
// http://myexternalip.com | ||
// http://api.ident.me | ||
// http://whatismyipaddress.com/api | ||
// http://ipinfo.io/ip | ||
ip := strings.TrimSpace(httpGet("https://api.ipify.org/?format=text")) | ||
return ip + ":" + defaultRPCPort | ||
} | ||
|
||
func (w *wizard) promptTranscoderConfig() (float64, float64, *big.Int, string) { | ||
var ( | ||
blockRewardCut float64 | ||
feeShare float64 | ||
|
@@ -30,15 +43,32 @@ func (w *wizard) promptTranscoderConfig() (float64, float64, *big.Int) { | |
fmt.Printf("Enter price per segment in Wei (default: 1) - ") | ||
pricePerSegment = w.readDefaultBigInt(big.NewInt(1)) | ||
|
||
return blockRewardCut, feeShare, pricePerSegment | ||
addr := myHostPort() | ||
fmt.Printf("Enter the public host:port of node (default: %v)", addr) | ||
serviceURI := w.readStringAndValidate(func(in string) (string, error) { | ||
if "" == in { | ||
in = addr | ||
} | ||
in = "https://" + in | ||
uri, err := url.ParseRequestURI(in) | ||
if err != nil { | ||
return "", err | ||
} | ||
if uri.Port() == "" { | ||
return "", fmt.Errorf("Missing Port") | ||
} | ||
return in, nil | ||
}) | ||
|
||
return blockRewardCut, feeShare, pricePerSegment, serviceURI | ||
} | ||
|
||
func (w *wizard) activateTranscoder() { | ||
d, err := w.getDelegatorInfo() | ||
fmt.Printf("Current token balance: %v\n", w.getTokenBalance()) | ||
fmt.Printf("Current bonded amount: %v\n", d.BondedAmount.String()) | ||
|
||
blockRewardCut, feeShare, pricePerSegment := w.promptTranscoderConfig() | ||
blockRewardCut, feeShare, pricePerSegment, serviceURI := w.promptTranscoderConfig() | ||
|
||
fmt.Printf("You must bond to yourself in order to become a transcoder\n") | ||
|
||
|
@@ -64,24 +94,30 @@ func (w *wizard) activateTranscoder() { | |
"blockRewardCut": {fmt.Sprintf("%v", blockRewardCut)}, | ||
"feeShare": {fmt.Sprintf("%v", feeShare)}, | ||
"pricePerSegment": {fmt.Sprintf("%v", pricePerSegment.String())}, | ||
"serviceURI": {fmt.Sprintf("%v", serviceURI)}, | ||
"amount": {fmt.Sprintf("%v", amount.String())}, | ||
} | ||
|
||
httpPostWithParams(fmt.Sprintf("http://%v:%v/activateTranscoder", w.host, w.httpPort), val) | ||
// TODO we should confirm if the transaction was actually sent | ||
fmt.Println("\nTransaction sent. Once confirmed, please restart your node.") | ||
} | ||
|
||
func (w *wizard) setTranscoderConfig() { | ||
fmt.Printf("Current token balance: %v\n", w.getTokenBalance()) | ||
|
||
blockRewardCut, feeShare, pricePerSegment := w.promptTranscoderConfig() | ||
blockRewardCut, feeShare, pricePerSegment, serviceURI := w.promptTranscoderConfig() | ||
|
||
val := url.Values{ | ||
"blockRewardCut": {fmt.Sprintf("%v", blockRewardCut)}, | ||
"feeShare": {fmt.Sprintf("%v", feeShare)}, | ||
"pricePerSegment": {fmt.Sprintf("%v", pricePerSegment.String())}, | ||
"serviceURI": {fmt.Sprintf("%v", serviceURI)}, | ||
} | ||
|
||
httpPostWithParams(fmt.Sprintf("http://%v:%v/setTranscoderConfig", w.host, w.httpPort), val) | ||
// TODO we should confirm if the transaction was actually sent | ||
fmt.Println("\nTransaction sent. Once confirmed, please restart your node if the ServiceURI has been reset") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reset is just to allow the node to check for you if your service URI matches your publicAddr before moving forward with any other operations? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The restart also allows the node to bind to the new port, if that has changed. |
||
} | ||
|
||
func (w *wizard) callReward() { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we default to passing in 127.0.0.1 with the expectation that with the V2 networking changes, this basicnet construct won't be used anyway so it doesn't matter that a public IP isn't set for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, the basicnet publicIP won't be used anymore with the v2 network. Technically this API could be cleaned up too, but I'm not sure how much further work the p2p layer will see; it depends what we do with the relay network (if anything).