Skip to content
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

cmd/faucet: merge ipfaucet2 branch to develop #1361

Merged
merged 11 commits into from
Apr 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 42 additions & 25 deletions cmd/faucet/faucet.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,6 @@ var (
fixGasPrice = flag.Int64("faucet.fixedprice", 0, "Will use fixed gas price if specified")
twitterTokenFlag = flag.String("twitter.token", "", "Bearer token to authenticate with the v2 Twitter API")
twitterTokenV1Flag = flag.String("twitter.token.v1", "", "Bearer token to authenticate with the v1.1 Twitter API")

goerliFlag = flag.Bool("goerli", false, "Initializes the faucet with Görli network config")
rinkebyFlag = flag.Bool("rinkeby", false, "Initializes the faucet with Rinkeby network config")
)

var (
Expand All @@ -115,7 +112,7 @@ func main() {
for i := 0; i < *tiersFlag; i++ {
// Calculate the amount for the next tier and format it
amount := float64(*payoutFlag) * math.Pow(2.5, float64(i))
amounts[i] = fmt.Sprintf("%s BNBs", strconv.FormatFloat(amount, 'f', -1, 64))
amounts[i] = fmt.Sprintf("0.%s BNBs", strconv.FormatFloat(amount, 'f', -1, 64))
if amount == 1 {
amounts[i] = strings.TrimSuffix(amounts[i], "s")
}
Expand Down Expand Up @@ -170,9 +167,13 @@ func main() {
log.Crit("Failed to render the faucet template", "err", err)
}
// Load and parse the genesis block requested by the user
genesis, err := getGenesis(genesisFlag, *goerliFlag, *rinkebyFlag)
blob, err := ioutil.ReadFile(*genesisFlag)
if err != nil {
log.Crit("Failed to parse genesis config", "err", err)
log.Crit("Failed to read genesis block contents", "genesis", *genesisFlag, "err", err)
}
genesis := new(core.Genesis)
if err = json.Unmarshal(blob, genesis); err != nil {
log.Crit("Failed to parse genesis block json", "err", err)
}
// Convert the bootnodes to internal enode representations
var enodes []*enode.Node
Expand All @@ -184,13 +185,13 @@ func main() {
}
}
// Load up the account key and decrypt its password
blob, err := ioutil.ReadFile(*accPassFlag)
blob, err = ioutil.ReadFile(*accPassFlag)
if err != nil {
log.Crit("Failed to read account password contents", "file", *accPassFlag, "err", err)
}
pass := strings.TrimSuffix(string(blob), "\n")

ks := keystore.NewKeyStore(filepath.Join(os.Getenv("HOME"), ".faucet", "keys"), keystore.StandardScryptN, keystore.StandardScryptP)
ks := keystore.NewKeyStore(filepath.Join(os.Getenv("HOME"), ".faucet", "keys_2"), keystore.StandardScryptN, keystore.StandardScryptP)
if blob, err = ioutil.ReadFile(*accJSONFlag); err != nil {
log.Crit("Failed to read account key contents", "file", *accJSONFlag, "err", err)
}
Expand Down Expand Up @@ -364,6 +365,11 @@ func (f *faucet) apiHandler(w http.ResponseWriter, r *http.Request) {

// Start tracking the connection and drop at the end
defer conn.Close()
ipsStr := r.Header.Get("X-Forwarded-For")
ips := strings.Split(ipsStr, ",")
if len(ips) < 2 {
return
}

f.lock.Lock()
wsconn := &wsConn{conn: conn}
Expand Down Expand Up @@ -460,7 +466,7 @@ func (f *faucet) apiHandler(w http.ResponseWriter, r *http.Request) {
form.Add("secret", *captchaSecret)
form.Add("response", msg.Captcha)

res, err := http.PostForm("https://www.google.com/recaptcha/api/siteverify", form)
res, err := http.PostForm("https://hcaptcha.com/siteverify", form)
if err != nil {
if err = sendError(wsconn, err); err != nil {
log.Warn("Failed to send captcha post error to client", "err", err)
Expand Down Expand Up @@ -499,6 +505,19 @@ func (f *faucet) apiHandler(w http.ResponseWriter, r *http.Request) {
address common.Address
)
switch {
case strings.HasPrefix(msg.URL, "https://gist.github.com/"):
if err = sendError(wsconn, errors.New("GitHub authentication discontinued at the official request of GitHub")); err != nil {
log.Warn("Failed to send GitHub deprecation to client", "err", err)
return
}
continue
case strings.HasPrefix(msg.URL, "https://plus.google.com/"):
//lint:ignore ST1005 Google is a company name and should be capitalized.
if err = sendError(wsconn, errors.New("Google+ authentication discontinued as the service was sunset")); err != nil {
log.Warn("Failed to send Google+ deprecation to client", "err", err)
return
}
continue
case strings.HasPrefix(msg.URL, "https://twitter.com/"):
id, username, avatar, address, err = authTwitter(msg.URL, *twitterTokenV1Flag, *twitterTokenFlag)
case strings.HasPrefix(msg.URL, "https://www.facebook.com/"):
Expand Down Expand Up @@ -526,11 +545,20 @@ func (f *faucet) apiHandler(w http.ResponseWriter, r *http.Request) {
fund bool
timeout time.Time
)

if ipTimeout := f.timeouts[ips[len(ips)-2]]; time.Now().Before(ipTimeout) {
if err = sendError(wsconn, fmt.Errorf("%s left until next allowance", common.PrettyDuration(time.Until(ipTimeout)))); err != nil { // nolint: gosimple
log.Warn("Failed to send funding error to client", "err", err)
}
f.lock.Unlock()
continue
}

if timeout = f.timeouts[id]; time.Now().After(timeout) {
var tx *types.Transaction
if msg.Symbol == "BNB" {
// User wasn't funded recently, create the funding transaction
amount := new(big.Int).Mul(big.NewInt(int64(*payoutFlag)), ether)
amount := new(big.Int).Div(new(big.Int).Mul(big.NewInt(int64(*payoutFlag)), ether), big.NewInt(10))
amount = new(big.Int).Mul(amount, new(big.Int).Exp(big.NewInt(5), big.NewInt(int64(msg.Tier)), nil))
amount = new(big.Int).Div(amount, new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(msg.Tier)), nil))

Expand Down Expand Up @@ -578,6 +606,7 @@ func (f *faucet) apiHandler(w http.ResponseWriter, r *http.Request) {
grace := timeout / 288 // 24h timeout => 5m grace

f.timeouts[id] = time.Now().Add(timeout - grace)
f.timeouts[ips[len(ips)-2]] = time.Now().Add(timeout - grace)
fund = true
}
f.lock.Unlock()
Expand Down Expand Up @@ -799,7 +828,7 @@ func authTwitter(url string, tokenV1, tokenV2 string) (string, string, string, c
address := common.HexToAddress(string(regexp.MustCompile("0x[0-9a-fA-F]{40}").Find(body)))
if address == (common.Address{}) {
//lint:ignore ST1005 This error is to be displayed in the browser
return "", "", "", common.Address{}, errors.New("No Binance Smart Chain address found to fund")
return "", "", "", common.Address{}, errors.New("No BNB Smart Chain address found to fund")
}
var avatar string
if parts = regexp.MustCompile(`src="([^"]+twimg\.com/profile_images[^"]+)"`).FindStringSubmatch(string(body)); len(parts) == 2 {
Expand Down Expand Up @@ -925,7 +954,7 @@ func authFacebook(url string) (string, string, common.Address, error) {
address := common.HexToAddress(string(regexp.MustCompile("0x[0-9a-fA-F]{40}").Find(body)))
if address == (common.Address{}) {
//lint:ignore ST1005 This error is to be displayed in the browser
return "", "", common.Address{}, errors.New("No Binance Smart Chain address found to fund")
return "", "", common.Address{}, errors.New("No BNB Smart Chain address found to fund")
}
var avatar string
if parts = regexp.MustCompile(`src="([^"]+fbcdn\.net[^"]+)"`).FindStringSubmatch(string(body)); len(parts) == 2 {
Expand All @@ -941,19 +970,7 @@ func authNoAuth(url string) (string, string, common.Address, error) {
address := common.HexToAddress(regexp.MustCompile("0x[0-9a-fA-F]{40}").FindString(url))
if address == (common.Address{}) {
//lint:ignore ST1005 This error is to be displayed in the browser
return "", "", common.Address{}, errors.New("No Binance Smart Chain address found to fund")
return "", "", common.Address{}, errors.New("No BNB Smart Chain address found to fund")
}
return address.Hex() + "@noauth", "", address, nil
}

// getGenesis returns a genesis based on input args
func getGenesis(genesisFlag *string, goerliFlag bool, rinkebyFlag bool) (*core.Genesis, error) {
switch {
case genesisFlag != nil:
var genesis core.Genesis
err := common.LoadJSON(*genesisFlag, &genesis)
return &genesis, err
default:
return nil, fmt.Errorf("no genesis flag provided")
}
}
Loading