diff --git a/cmd/lotus-fountain/main.go b/cmd/lotus-fountain/main.go index 780aef916..d0e1964c4 100644 --- a/cmd/lotus-fountain/main.go +++ b/cmd/lotus-fountain/main.go @@ -3,6 +3,8 @@ package main import ( "context" "fmt" + verifregtypes9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" + "github.com/filecoin-project/lotus/chain/actors" "html/template" "net" "net/http" @@ -18,6 +20,7 @@ import ( "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" ) @@ -70,6 +73,11 @@ var runCmd = &cli.Command{ EnvVars: []string{"LOTUS_FOUNTAIN_AMOUNT"}, Value: "50", }, + &cli.Uint64Flag{ + Name: "data-cap", + EnvVars: []string{"LOTUS_DATACAP_AMOUNT"}, + Value: 10240, + }, &cli.Float64Flag{ Name: "captcha-threshold", Value: 0.5, @@ -108,6 +116,7 @@ var runCmd = &cli.Command{ ctx: ctx, api: nodeApi, from: from, + allowance: types.NewInt(cctx.Uint64("data-cap")), sendPerRequest: sendPerRequest, limiter: NewLimiter(LimiterConfig{ TotalRate: 500 * time.Millisecond, @@ -124,6 +133,8 @@ var runCmd = &cli.Command{ http.Handle("/", http.FileServer(box.HTTPBox())) http.HandleFunc("/funds.html", prepFundsHtml(box)) http.Handle("/send", h) + http.HandleFunc("/datacap.html", prepDataCapHtml(box)) + http.Handle("/datacap", h) fmt.Printf("Open http://%s\n", cctx.String("front")) go func() { @@ -156,12 +167,24 @@ func prepFundsHtml(box *rice.Box) http.HandlerFunc { } } +func prepDataCapHtml(box *rice.Box) http.HandlerFunc { + tmpl := template.Must(template.New("datacaps").Parse(box.MustString("datacap.html"))) + return func(w http.ResponseWriter, r *http.Request) { + err := tmpl.Execute(w, os.Getenv("RECAPTCHA_SITE_KEY")) + if err != nil { + http.Error(w, err.Error(), http.StatusBadGateway) + return + } + } +} + type handler struct { ctx context.Context api v0api.FullNode from address.Address sendPerRequest types.FIL + allowance types.BigInt limiter *Limiter recapThreshold float64 @@ -187,6 +210,7 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadGateway) return } + if !capResp.Success || capResp.Score < h.recapThreshold { log.Infow("spam", "capResp", capResp) http.Error(w, "spam protection", http.StatusUnprocessableEntity) @@ -227,11 +251,37 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - smsg, err := h.api.MpoolPushMessage(h.ctx, &types.Message{ - Value: types.BigInt(h.sendPerRequest), - From: h.from, - To: to, - }, nil) + var smsg *types.SignedMessage + if r.RequestURI == "/send" { + smsg, err = h.api.MpoolPushMessage( + h.ctx, &types.Message{ + Value: types.BigInt(h.sendPerRequest), + From: h.from, + To: to, + }, nil) + } else if r.RequestURI == "/datacap" { + var params []byte + params, err = actors.SerializeParams( + &verifregtypes9.AddVerifiedClientParams{ + Address: to, + Allowance: h.allowance, + }) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + smsg, err = h.api.MpoolPushMessage( + h.ctx, &types.Message{ + Params: params, + From: h.from, + To: verifreg.Address, + Method: verifreg.Methods.AddVerifiedClient, + }, nil) + } else { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return diff --git a/cmd/lotus-fountain/site/datacap.html b/cmd/lotus-fountain/site/datacap.html new file mode 100644 index 000000000..10cf1f411 --- /dev/null +++ b/cmd/lotus-fountain/site/datacap.html @@ -0,0 +1,40 @@ + + +
+