Skip to content

Commit

Permalink
cmd/faucet: merge ipfaucet2 branch to develop (ethereum#1361)
Browse files Browse the repository at this point in the history
* add ip ratelimit

* update

* update

* update explorer adddress

* updae recapcha

* remove binance

* cmd/faucet: fix conn to wrapped wsconn

* cmd/faucet: keystore updated to save and load one same addres once

* clean: remove btcd v0.20.1-beta and avoid to ambiguous import (ethereum#1)

* ci: fix truffle test (ethereum#1384)

---------

Co-authored-by: fudongbai <[email protected]>
Co-authored-by: Nathan <[email protected]>
  • Loading branch information
3 people authored Apr 6, 2023
1 parent 221ef7d commit f9f5cc2
Show file tree
Hide file tree
Showing 5 changed files with 281 additions and 249 deletions.
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

0 comments on commit f9f5cc2

Please sign in to comment.