add grant-datacap support for lotus fountain
This commit is contained in:
parent
d1d4b35adf
commit
0ec3d44276
@ -3,6 +3,8 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
verifregtypes9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"html/template"
|
"html/template"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -18,6 +20,7 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/lotus/api/v0api"
|
"github.com/filecoin-project/lotus/api/v0api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
lcli "github.com/filecoin-project/lotus/cli"
|
lcli "github.com/filecoin-project/lotus/cli"
|
||||||
)
|
)
|
||||||
@ -70,6 +73,11 @@ var runCmd = &cli.Command{
|
|||||||
EnvVars: []string{"LOTUS_FOUNTAIN_AMOUNT"},
|
EnvVars: []string{"LOTUS_FOUNTAIN_AMOUNT"},
|
||||||
Value: "50",
|
Value: "50",
|
||||||
},
|
},
|
||||||
|
&cli.Uint64Flag{
|
||||||
|
Name: "data-cap",
|
||||||
|
EnvVars: []string{"LOTUS_DATACAP_AMOUNT"},
|
||||||
|
Value: 10240,
|
||||||
|
},
|
||||||
&cli.Float64Flag{
|
&cli.Float64Flag{
|
||||||
Name: "captcha-threshold",
|
Name: "captcha-threshold",
|
||||||
Value: 0.5,
|
Value: 0.5,
|
||||||
@ -108,6 +116,7 @@ var runCmd = &cli.Command{
|
|||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
api: nodeApi,
|
api: nodeApi,
|
||||||
from: from,
|
from: from,
|
||||||
|
allowance: types.NewInt(cctx.Uint64("data-cap")),
|
||||||
sendPerRequest: sendPerRequest,
|
sendPerRequest: sendPerRequest,
|
||||||
limiter: NewLimiter(LimiterConfig{
|
limiter: NewLimiter(LimiterConfig{
|
||||||
TotalRate: 500 * time.Millisecond,
|
TotalRate: 500 * time.Millisecond,
|
||||||
@ -124,6 +133,8 @@ var runCmd = &cli.Command{
|
|||||||
http.Handle("/", http.FileServer(box.HTTPBox()))
|
http.Handle("/", http.FileServer(box.HTTPBox()))
|
||||||
http.HandleFunc("/funds.html", prepFundsHtml(box))
|
http.HandleFunc("/funds.html", prepFundsHtml(box))
|
||||||
http.Handle("/send", h)
|
http.Handle("/send", h)
|
||||||
|
http.HandleFunc("/datacap.html", prepDataCapHtml(box))
|
||||||
|
http.Handle("/datacap", h)
|
||||||
fmt.Printf("Open http://%s\n", cctx.String("front"))
|
fmt.Printf("Open http://%s\n", cctx.String("front"))
|
||||||
|
|
||||||
go func() {
|
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 {
|
type handler struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
api v0api.FullNode
|
api v0api.FullNode
|
||||||
|
|
||||||
from address.Address
|
from address.Address
|
||||||
sendPerRequest types.FIL
|
sendPerRequest types.FIL
|
||||||
|
allowance types.BigInt
|
||||||
|
|
||||||
limiter *Limiter
|
limiter *Limiter
|
||||||
recapThreshold float64
|
recapThreshold float64
|
||||||
@ -187,6 +210,7 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.Error(w, err.Error(), http.StatusBadGateway)
|
http.Error(w, err.Error(), http.StatusBadGateway)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !capResp.Success || capResp.Score < h.recapThreshold {
|
if !capResp.Success || capResp.Score < h.recapThreshold {
|
||||||
log.Infow("spam", "capResp", capResp)
|
log.Infow("spam", "capResp", capResp)
|
||||||
http.Error(w, "spam protection", http.StatusUnprocessableEntity)
|
http.Error(w, "spam protection", http.StatusUnprocessableEntity)
|
||||||
@ -227,11 +251,37 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
smsg, err := h.api.MpoolPushMessage(h.ctx, &types.Message{
|
var smsg *types.SignedMessage
|
||||||
|
if r.RequestURI == "/send" {
|
||||||
|
smsg, err = h.api.MpoolPushMessage(
|
||||||
|
h.ctx, &types.Message{
|
||||||
Value: types.BigInt(h.sendPerRequest),
|
Value: types.BigInt(h.sendPerRequest),
|
||||||
From: h.from,
|
From: h.from,
|
||||||
To: to,
|
To: to,
|
||||||
}, nil)
|
}, 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 {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
|
40
cmd/lotus-fountain/site/datacap.html
Normal file
40
cmd/lotus-fountain/site/datacap.html
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Grant DataCap - Lotus Fountain</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="main.css">
|
||||||
|
<script src="https://www.google.com/recaptcha/api.js"></script>
|
||||||
|
<script>
|
||||||
|
function onSubmit(token) {
|
||||||
|
document.getElementById("funds-form").submit();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="Index">
|
||||||
|
<div class="Index-nodes">
|
||||||
|
<div class="Index-node">
|
||||||
|
[GRANT DATACAP]
|
||||||
|
</div>
|
||||||
|
<div class="Index-node">
|
||||||
|
<form action='/datacap' method='post' id='datacap-form'>
|
||||||
|
<span>Enter destination address:</span>
|
||||||
|
<input type='text' name='address' style="width: 300px">
|
||||||
|
<button class="g-recaptcha"
|
||||||
|
data-sitekey="{{ . }}"
|
||||||
|
data-callback='onSubmit'
|
||||||
|
data-action='submit'>Grant Datacap</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Index-footer">
|
||||||
|
<div>
|
||||||
|
<a href="index.html">[Back]</a>
|
||||||
|
<span style="float: right">Not dispensing real Filecoin tokens</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -13,6 +13,12 @@
|
|||||||
<div class="Index-node">
|
<div class="Index-node">
|
||||||
<a href="funds.html">[Send Funds]</a>
|
<a href="funds.html">[Send Funds]</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="Index-node">
|
||||||
|
[LOTUS DEVNET GRANT DATACAP]
|
||||||
|
</div>
|
||||||
|
<div class="Index-node">
|
||||||
|
<a href="datacap.html">[Grant DataCap]</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="Index-footer">
|
<div class="Index-footer">
|
||||||
<div>
|
<div>
|
||||||
|
Loading…
Reference in New Issue
Block a user