Merge pull request #3278 from filecoin-project/remove-mkminer
lotus-fountain: remove make miner workflow
This commit is contained in:
commit
e23e3db5b5
@ -1,77 +1,28 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
rice "github.com/GeertJohan/go.rice"
|
||||
"github.com/ipfs/go-cid"
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
)
|
||||
|
||||
var log = logging.Logger("main")
|
||||
|
||||
var supportedSectors struct {
|
||||
SectorSizes []struct {
|
||||
Name string
|
||||
Value uint64
|
||||
Default bool
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
for supportedSector := range miner.SupportedProofTypes {
|
||||
sectorSize, err := supportedSector.SectorSize()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
supportedSectors.SectorSizes = append(supportedSectors.SectorSizes, struct {
|
||||
Name string
|
||||
Value uint64
|
||||
Default bool
|
||||
}{
|
||||
Name: sectorSize.ShortString(),
|
||||
Value: uint64(sectorSize),
|
||||
Default: false,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
sort.Slice(supportedSectors.SectorSizes[:], func(i, j int) bool {
|
||||
return supportedSectors.SectorSizes[i].Value < supportedSectors.SectorSizes[j].Value
|
||||
})
|
||||
|
||||
supportedSectors.SectorSizes[0].Default = true
|
||||
}
|
||||
|
||||
func main() {
|
||||
logging.SetLogLevel("*", "INFO")
|
||||
|
||||
@ -144,11 +95,6 @@ var runCmd = &cli.Command{
|
||||
return xerrors.Errorf("parsing source address (provide correct --from flag!): %w", err)
|
||||
}
|
||||
|
||||
defaultMinerPeer, err := peer.Decode("12D3KooWJpBNhwgvoZ15EB1JwRTRpxgM9D2fwq6eEktrJJG74aP6")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
h := &handler{
|
||||
ctx: ctx,
|
||||
api: nodeApi,
|
||||
@ -162,23 +108,10 @@ var runCmd = &cli.Command{
|
||||
WalletRate: 15 * time.Minute,
|
||||
WalletBurst: 2,
|
||||
}),
|
||||
minerLimiter: NewLimiter(LimiterConfig{
|
||||
TotalRate: 500 * time.Millisecond,
|
||||
TotalBurst: build.BlockMessageLimit,
|
||||
IPRate: 10 * time.Minute,
|
||||
IPBurst: 2,
|
||||
WalletRate: 1 * time.Hour,
|
||||
WalletBurst: 2,
|
||||
}),
|
||||
defaultMinerPeer: defaultMinerPeer,
|
||||
}
|
||||
|
||||
http.Handle("/", http.FileServer(rice.MustFindBox("site").HTTPBox()))
|
||||
http.HandleFunc("/miner.html", h.minerhtml)
|
||||
http.HandleFunc("/send", h.send)
|
||||
http.HandleFunc("/mkminer", h.mkminer)
|
||||
http.HandleFunc("/msgwait", h.msgwait)
|
||||
http.HandleFunc("/msgwaitaddr", h.msgwaitaddr)
|
||||
|
||||
fmt.Printf("Open http://%s\n", cctx.String("front"))
|
||||
|
||||
@ -204,37 +137,6 @@ type handler struct {
|
||||
defaultMinerPeer peer.ID
|
||||
}
|
||||
|
||||
func (h *handler) minerhtml(w http.ResponseWriter, r *http.Request) {
|
||||
f, err := rice.MustFindBox("site").Open("_miner.html")
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
tmpl, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
var executedTmpl bytes.Buffer
|
||||
|
||||
t, err := template.New("miner.html").Parse(string(tmpl))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
if err := t.Execute(&executedTmpl, supportedSectors); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := io.Copy(w, &executedTmpl); err != nil {
|
||||
log.Errorf("failed to write template to string %s", err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (h *handler) send(w http.ResponseWriter, r *http.Request) {
|
||||
to, err := address.NewFromString(r.FormValue("address"))
|
||||
if err != nil {
|
||||
@ -287,150 +189,3 @@ func (h *handler) send(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
_, _ = w.Write([]byte(smsg.Cid().String()))
|
||||
}
|
||||
|
||||
func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) {
|
||||
owner, err := address.NewFromString(r.FormValue("address"))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if owner.Protocol() != address.BLS {
|
||||
http.Error(w,
|
||||
"Miner address must use BLS. A BLS address starts with the prefix 't3'."+
|
||||
"Please create a BLS address by running \"lotus wallet new bls\" while connected to a Lotus node.",
|
||||
http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
ssize, err := strconv.ParseInt(r.FormValue("sectorSize"), 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
log.Infof("%s: create actor start", owner)
|
||||
|
||||
// Limit based on wallet address
|
||||
limiter := h.minerLimiter.GetWalletLimiter(owner.String())
|
||||
if !limiter.Allow() {
|
||||
http.Error(w, http.StatusText(http.StatusTooManyRequests)+": wallet limit", http.StatusTooManyRequests)
|
||||
return
|
||||
}
|
||||
|
||||
// Limit based on IP
|
||||
reqIP := r.Header.Get("X-Real-IP")
|
||||
if reqIP == "" {
|
||||
h, _, err := net.SplitHostPort(r.RemoteAddr)
|
||||
if err != nil {
|
||||
log.Errorf("could not get ip from: %s, err: %s", r.RemoteAddr, err)
|
||||
}
|
||||
reqIP = h
|
||||
}
|
||||
limiter = h.minerLimiter.GetIPLimiter(reqIP)
|
||||
if !limiter.Allow() {
|
||||
http.Error(w, http.StatusText(http.StatusTooManyRequests)+": IP limit", http.StatusTooManyRequests)
|
||||
return
|
||||
}
|
||||
|
||||
// General limiter owner allow throttling all messages that can make it into the mpool
|
||||
if !h.minerLimiter.Allow() {
|
||||
http.Error(w, http.StatusText(http.StatusTooManyRequests)+": global limit", http.StatusTooManyRequests)
|
||||
return
|
||||
}
|
||||
|
||||
smsg, err := h.api.MpoolPushMessage(h.ctx, &types.Message{
|
||||
Value: types.BigInt(h.sendPerRequest),
|
||||
From: h.from,
|
||||
To: owner,
|
||||
}, nil)
|
||||
if err != nil {
|
||||
http.Error(w, "pushfunds: "+err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
log.Infof("%s: push funds %s", owner, smsg.Cid())
|
||||
|
||||
spt, err := ffiwrapper.SealProofTypeFromSectorSize(abi.SectorSize(ssize))
|
||||
if err != nil {
|
||||
http.Error(w, "sealprooftype: "+err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
params, err := actors.SerializeParams(&power.CreateMinerParams{
|
||||
Owner: owner,
|
||||
Worker: owner,
|
||||
SealProofType: spt,
|
||||
Peer: abi.PeerID(h.defaultMinerPeer),
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
createStorageMinerMsg := &types.Message{
|
||||
To: builtin.StoragePowerActorAddr,
|
||||
From: h.from,
|
||||
Value: big.Zero(),
|
||||
|
||||
Method: builtin.MethodsPower.CreateMiner,
|
||||
Params: params,
|
||||
}
|
||||
|
||||
signed, err := h.api.MpoolPushMessage(r.Context(), createStorageMinerMsg, nil)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
log.Infof("%s: create miner msg: %s", owner, signed.Cid())
|
||||
|
||||
http.Redirect(w, r, fmt.Sprintf("/wait.html?f=%s&m=%s&o=%s", signed.Cid(), smsg.Cid(), owner), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func (h *handler) msgwait(w http.ResponseWriter, r *http.Request) {
|
||||
c, err := cid.Parse(r.FormValue("cid"))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
mw, err := h.api.StateWaitMsg(r.Context(), c, build.MessageConfidence)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if mw.Receipt.ExitCode != 0 {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func (h *handler) msgwaitaddr(w http.ResponseWriter, r *http.Request) {
|
||||
c, err := cid.Parse(r.FormValue("cid"))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
mw, err := h.api.StateWaitMsg(r.Context(), c, build.MessageConfidence)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if mw.Receipt.ExitCode != 0 {
|
||||
http.Error(w, xerrors.Errorf("create miner failed: exit code %d", mw.Receipt.ExitCode).Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
var ma power.CreateMinerReturn
|
||||
if err := ma.UnmarshalCBOR(bytes.NewReader(mw.Receipt.Return)); err != nil {
|
||||
log.Errorf("%w", err)
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "{\"addr\": \"%s\"}", ma.IDAddress)
|
||||
}
|
||||
|
@ -1,51 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Creating Miner - Lotus Fountain</title>
|
||||
<link rel="stylesheet" type="text/css" href="main.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="Index">
|
||||
<div class="Index-nodes">
|
||||
<div class="Index-node">
|
||||
[CREATING MINER]
|
||||
</div>
|
||||
<div class="Index-node" id="formnd">
|
||||
<form id="f" action='/mkminer' method='POST'>
|
||||
<span>Enter owner/worker address:</span>
|
||||
<input type='text' name='address' style="width: 300px" placeholder="t3...">
|
||||
<select name="sectorSize">
|
||||
{{range .SectorSizes}}
|
||||
<option {{if .Default}}selected{{end}} value="{{ .Value }}">{{ .Name }}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
<button type='submit'>Create Miner</button>
|
||||
</form>
|
||||
</div>
|
||||
<div id="plswait" style="display: none" class="Index-node">
|
||||
<b>Waiting for transaction on chain..</b>
|
||||
</div>
|
||||
<div class="Index-node">
|
||||
<span>When creating miner, DO NOT REFRESH THE PAGE, wait for it to load. This can take more than 5min.</span>
|
||||
</div>
|
||||
<div class="Index-node">
|
||||
<span>If you don't have an owner/worker address, you can create it by following <a target="_blank" href="https://lotu.sh/en+mining#get-started-22083">these instructions</a>.</span>
|
||||
</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>
|
||||
<script>
|
||||
let f = document.getElementById('f')
|
||||
f.onsubmit = ev => {
|
||||
document.getElementById('plswait').style.display = 'block'
|
||||
document.getElementById('formnd').style.display = 'none'
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -13,9 +13,6 @@
|
||||
<div class="Index-node">
|
||||
<a href="funds.html">[Send Funds]</a>
|
||||
</div>
|
||||
<div class="Index-node">
|
||||
<a href="miner.html">[Create Miner]</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="Index-footer">
|
||||
<div>
|
||||
|
@ -1,69 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Creating Miner (wait) - Lotus Fountain</title>
|
||||
<link rel="stylesheet" type="text/css" href="main.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="Index">
|
||||
<div class="Index-nodes">
|
||||
<div class="Index-node">
|
||||
[CREATING MINER]
|
||||
</div>
|
||||
<div class="Index-node">
|
||||
Gas Funds: <span id="fcid"></span> - <span id="fstate">WAIT</span>
|
||||
</div>
|
||||
<div class="Index-node">
|
||||
Miner Actor: <span id="mcid"></span> - <span id="mstate">WAIT</span>
|
||||
</div>
|
||||
<div class="Index-node" style="display: none" id="fwait">
|
||||
New miners address is: <b id="actaddr">t</b>
|
||||
</div>
|
||||
<div class="Index-node" style="display: none" id="mwait">
|
||||
<div style="padding-bottom: 1em">To initialize the miner run the following command:</div>
|
||||
<div style="overflow-x: visible; white-space: nowrap; background: #353500">
|
||||
<code>lotus-miner init --actor=<span id="actaddr2">t</span> --owner=<span id="owner">t3</span></code>
|
||||
</div>
|
||||
</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>
|
||||
<script>
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
|
||||
const fcid = document.getElementById('fcid')
|
||||
const mcid = document.getElementById('mcid')
|
||||
|
||||
fcid.innerText = params.get('f')
|
||||
mcid.innerText = params.get('m')
|
||||
|
||||
async function waitFunds() {
|
||||
await fetch('/msgwait?cid=' + params.get('f'))
|
||||
document.getElementById('fstate').innerText = "OK"
|
||||
|
||||
document.getElementById('fwait').style.display = 'block'
|
||||
}
|
||||
|
||||
async function waitMiner() {
|
||||
const resp = await fetch('/msgwaitaddr?cid=' + params.get('f'))
|
||||
document.getElementById('mstate').innerText = "OK"
|
||||
|
||||
const addr = (await resp.json()).addr
|
||||
|
||||
document.getElementById('actaddr').innerText = addr
|
||||
document.getElementById('actaddr2').innerText = addr
|
||||
document.getElementById('owner').innerText = params.get('o')
|
||||
|
||||
document.getElementById('mwait').style.display = 'block'
|
||||
}
|
||||
|
||||
waitFunds()
|
||||
waitMiner()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -33,26 +33,6 @@ With your wallet address:
|
||||
- Press the Request button.
|
||||
- Run `/lotus-miner init --owner=<blsAddress> --worker=<blsAddress>`
|
||||
|
||||
The task will be complete when you see:
|
||||
|
||||
```sh
|
||||
New miners address is: <YOUR_NEW_MINING_ADDRESS>
|
||||
```
|
||||
|
||||
## Initialize the miner
|
||||
|
||||
In a CLI window, use the following command to start your miner:
|
||||
|
||||
```sh
|
||||
lotus-miner init --actor=ACTOR_VALUE_RECEIVED --owner=OWNER_VALUE_RECEIVED
|
||||
```
|
||||
|
||||
Example
|
||||
|
||||
```sh
|
||||
lotus-miner init --actor=t01424 --owner=t3spmep2xxsl33o4gxk7yjxcobyohzgj3vejzerug25iinbznpzob6a6kexcbeix73th6vjtzfq7boakfdtd6a
|
||||
```
|
||||
|
||||
You will have to wait some time for this operation to complete.
|
||||
|
||||
## Mining
|
||||
|
Loading…
Reference in New Issue
Block a user