lotus/cmd/lotus-shed/send-csv.go
2021-12-07 17:09:07 -05:00

105 lines
2.4 KiB
Go

package main
import (
"encoding/csv"
"fmt"
"os"
"strings"
"github.com/ipfs/go-cid"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/exitcode"
lapi "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
)
var sendCsvCmd = &cli.Command{
Name: "send-csv",
Usage: "Utility for sending a batch of balance transfers",
ArgsUsage: "[sender] [csvfile]",
Action: func(cctx *cli.Context) error {
if cctx.NArg() != 2 {
return xerrors.New("must supply sender and path to csv file")
}
api, closer, err := lcli.GetFullNodeAPIV1(cctx)
if err != nil {
return err
}
defer closer()
ctx := lcli.ReqContext(cctx)
sender, err := address.NewFromString(cctx.Args().Get(0))
if err != nil {
return err
}
fileReader, err := os.Open(cctx.Args().Get(1))
if err != nil {
return xerrors.Errorf("read csv: %w", err)
}
defer fileReader.Close() //nolint:errcheck
r := csv.NewReader(fileReader)
records, err := r.ReadAll()
if err != nil {
return xerrors.Errorf("read csv: %w", err)
}
var msgCids []cid.Cid
for i, e := range records[1:] {
addr, err := address.NewFromString(e[0])
if err != nil {
return xerrors.Errorf("failed to parse address in row %d: %w", i, err)
}
value, err := types.ParseFIL(strings.TrimSpace(e[1]))
if err != nil {
return xerrors.Errorf("failed to parse value balance: %w", err)
}
smsg, err := api.MpoolPushMessage(ctx, &types.Message{
To: addr,
From: sender,
Value: abi.TokenAmount(value),
}, nil)
if err != nil {
return err
}
fmt.Printf("sending %s to %s in msg %s\n", value.String(), addr, smsg.Cid())
if i > 0 && i%100 == 0 {
fmt.Printf("catching up until latest message lands")
_, err := api.StateWaitMsg(ctx, smsg.Cid(), 1, lapi.LookbackNoLimit, true)
if err != nil {
return err
}
}
msgCids = append(msgCids, smsg.Cid())
}
fmt.Println("waiting on messages")
for _, msgCid := range msgCids {
ml, err := api.StateWaitMsg(ctx, msgCid, 5, lapi.LookbackNoLimit, true)
if err != nil {
return err
}
if ml.Receipt.ExitCode != exitcode.Ok {
fmt.Printf("MSG %s NON-ZERO EXITCODE: %s\n", msgCid, ml.Receipt.ExitCode)
}
}
return nil
},
}