diff --git a/cmd/cli/miner.go b/cmd/cli/miner.go index e1b1060..ddff28b 100644 --- a/cmd/cli/miner.go +++ b/cmd/cli/miner.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "os" + "strconv" "strings" "text/tabwriter" "time" @@ -32,6 +33,7 @@ var MinerCmd = &cli.Command{ minerSetOwnerCmd, minerSetWorkerCmd, minerSetControllersCmd, + minerSetBeneficiaryCmd, }, } @@ -490,8 +492,14 @@ var minerInfoCmd = &cli.Command{ var minerSetOwnerCmd = &cli.Command{ Name: "set-owner", - Usage: "set the owner address of a miner", + Usage: "set the owner address of a miner (this command should be invoked by old owner firstly, then new owner invoke with '--confirm' flag to confirm the change)", ArgsUsage: " ", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "confirm", + Usage: "confirm to change by the new owner", + }, + }, Action: func(cctx *cli.Context) error { ctx := cctx.Context api, err := getAPI(cctx) @@ -520,12 +528,20 @@ var minerSetOwnerCmd = &cli.Command{ fmt.Println("This will take some time (maybe 10 epoch), to ensure message is chained...") - err = api.MinerSetOwner(ctx, req) - if err != nil { - return err + if cctx.Bool("confirm") { + oldOwner, err := api.MinerConfirmOwner(ctx, req) + if err != nil { + return err + } + fmt.Printf("Miner owner changed to %s from %s \n", newOwner, oldOwner) + } else { + err = api.MinerSetOwner(ctx, req) + if err != nil { + return err + } + fmt.Printf("Miner owner proposed , it should be confirm by new owner(%s), who shall invoke 'set-owner' command with with '--confirm' flag \n", newOwner) } - fmt.Printf("Owner address changed to %s \n", newOwner) return nil }, } @@ -567,7 +583,7 @@ var minerSetWorkerCmd = &cli.Command{ NewWorker: newWorker, } - fmt.Println("This will take some time (maybe 10 epoch), to ensure message is chained...") + fmt.Println("This will take some time (maybe 5 epoch), to ensure message is chained...") if cctx.Bool("confirm") { err := api.MinerConfirmWorker(ctx, req) @@ -660,3 +676,96 @@ var minerSetControllersCmd = &cli.Command{ return nil }, } + +var minerSetBeneficiaryCmd = &cli.Command{ + Name: "set-beneficiary", + Usage: "set the beneficiary address of a miner (the change should be proposed by owner, and confirmed by old beneficiary and nominee)", + ArgsUsage: " ", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "confirm-by-beneficiary", + Usage: "confirm the change by the old beneficiary", + }, + &cli.BoolFlag{ + Name: "confirm-by-nominee", + Usage: "confirm the change by the nominee", + }, + }, + Action: func(cctx *cli.Context) error { + ctx := cctx.Context + api, err := getAPI(cctx) + if err != nil { + return err + } + + if cctx.Bool("confirm-by-beneficiary") && cctx.Bool("confirm-by-nominee") { + return fmt.Errorf("can't confirm by beneficiary and nominee at the same time") + } + + if cctx.NArg() < 2 { + return fmt.Errorf("must pass miner address and new beneficiary address as first and second arguments") + } + + mAddr, err := address.NewFromString(cctx.Args().First()) + if err != nil { + return err + } + + newBeneficiary, err := address.NewFromString(cctx.Args().Get(1)) + if err != nil { + return err + } + + fmt.Println("This will take some time (maybe 5 epoch), to ensure message is chained...") + if cctx.Bool("confirm-by-beneficiary") || cctx.Bool("confirm-by-nominee") { + req := &service.MinerConfirmBeneficiaryReq{ + Miner: mAddr, + NewBeneficiary: newBeneficiary, + ByNominee: cctx.Bool("confirm-by-nominee"), + } + + confirmor, err := api.MinerConfirmBeneficiary(ctx, req) + if err != nil { + return err + } + + fmt.Printf("Beneficiary address changed to %s has been confirm by %s \n", newBeneficiary, confirmor) + + } else { + if cctx.NArg() != 4 { + return fmt.Errorf("must pass miner address, new beneficiary address, quota and expiration as arguments") + } + + quota, err := types.ParseFIL(cctx.Args().Get(2)) + if err != nil { + return err + } + + expiration, err := strconv.ParseInt(cctx.Args().Get(3), 10, 64) + if err != nil { + return err + } + + req := &service.MinerSetBeneficiaryReq{ + Miner: mAddr, + ChangeBeneficiaryParams: types.ChangeBeneficiaryParams{ + NewBeneficiary: newBeneficiary, + NewQuota: abi.TokenAmount(quota), + NewExpiration: abi.ChainEpoch(expiration), + }, + } + + pendingChange, err := api.MinerSetBeneficiary(ctx, req) + if err != nil { + return err + } + fmt.Println("Beneficiary changed proposed:") + err = printJSON(pendingChange) + if err != nil { + return err + } + } + + return nil + }, +} diff --git a/service/api.go b/service/api.go index 70c1bac..675fe8d 100644 --- a/service/api.go +++ b/service/api.go @@ -8,6 +8,7 @@ import ( "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/venus/venus-shared/types" venusTypes "github.com/filecoin-project/venus/venus-shared/types" marketTypes "github.com/filecoin-project/venus/venus-shared/types/market" "github.com/ipfs/go-cid" @@ -25,17 +26,20 @@ type IService interface { AddrOperate(ctx context.Context, params *AddrsOperateReq) error // PUT:/addr/operate AddrList(ctx context.Context) ([]*AddrsResp, error) // GET:/addr/list - MinerInfo(ctx context.Context, mAddr address.Address) (*MinerInfoResp, error) // GET:/miner/info - MinerCreate(ctx context.Context, params *MinerCreateReq) (address.Address, error) // POST:/miner/create - MinerGetStorageAsk(ctx context.Context, mAddr address.Address) (*storagemarket.StorageAsk, error) // GET:/miner/storageask/ - MinerGetRetrievalAsk(ctx context.Context, mAddr address.Address) (*retrievalmarket.Ask, error) // GET:/miner/retrievalask/ - MinerSetStorageAsk(ctx context.Context, p *MinerSetAskReq) error // PUT:/miner/storageask/ - MinerSetRetrievalAsk(ctx context.Context, p *MinerSetRetrievalAskReq) error // PUT:/miner/retrievalask/ - MinerGetDeadlines(ctx context.Context, mAddr address.Address) (*dline.Info, error) // GET:/miner/deadline - MinerSetOwner(ctx context.Context, p *MinerSetOwnerReq) error // PUT:/miner/owner - MinerSetWorker(ctx context.Context, req *MinerSetWorkerReq) (WorkerChangeEpoch abi.ChainEpoch, err error) // PUT:/miner/worker - MinerConfirmWorker(ctx context.Context, req *MinerSetWorkerReq) error // PUT:/miner/confirmworker - MinerSetControllers(ctx context.Context, req *MinerSetControllersReq) (oldController []address.Address, err error) // PUT:/miner/controllers + MinerInfo(ctx context.Context, mAddr address.Address) (*MinerInfoResp, error) // GET:/miner/info + MinerCreate(ctx context.Context, params *MinerCreateReq) (address.Address, error) // POST:/miner/create + MinerGetStorageAsk(ctx context.Context, mAddr address.Address) (*storagemarket.StorageAsk, error) // GET:/miner/storageask/ + MinerGetRetrievalAsk(ctx context.Context, mAddr address.Address) (*retrievalmarket.Ask, error) // GET:/miner/retrievalask/ + MinerSetStorageAsk(ctx context.Context, p *MinerSetAskReq) error // PUT:/miner/storageask/ + MinerSetRetrievalAsk(ctx context.Context, p *MinerSetRetrievalAskReq) error // PUT:/miner/retrievalask/ + MinerGetDeadlines(ctx context.Context, mAddr address.Address) (*dline.Info, error) // GET:/miner/deadline + MinerSetOwner(ctx context.Context, p *MinerSetOwnerReq) error // PUT:/miner/owner + MinerConfirmOwner(ctx context.Context, p *MinerSetOwnerReq) (oldOwner address.Address, err error) // PUT:/miner/confirmowner + MinerSetWorker(ctx context.Context, req *MinerSetWorkerReq) (WorkerChangeEpoch abi.ChainEpoch, err error) // PUT:/miner/worker + MinerConfirmWorker(ctx context.Context, req *MinerSetWorkerReq) error // PUT:/miner/confirmworker + MinerSetControllers(ctx context.Context, req *MinerSetControllersReq) (oldController []address.Address, err error) // PUT:/miner/controllers + MinerSetBeneficiary(ctx context.Context, req *MinerSetBeneficiaryReq) (*types.PendingBeneficiaryChange, error) // PUT:/miner/beneficiary + MinerConfirmBeneficiary(ctx context.Context, req *MinerConfirmBeneficiaryReq) (confirmor address.Address, err error) // PUT:/miner/confirmbeneficiary StorageDealList(ctx context.Context, miner address.Address) ([]marketTypes.MinerDeal, error) // GET:/deal/storage StorageDealUpdateState(ctx context.Context, req StorageDealUpdateStateReq) error // PUT:/deal/storage/state diff --git a/service/impl.go b/service/impl.go index 0b4ac47..c74bbe4 100644 --- a/service/impl.go +++ b/service/impl.go @@ -23,7 +23,7 @@ import ( nodeV1 "github.com/filecoin-project/venus/venus-shared/api/chain/v1" "github.com/filecoin-project/venus/venus-shared/api/market" "github.com/filecoin-project/venus/venus-shared/api/messager" - venusTypes "github.com/filecoin-project/venus/venus-shared/types" + "github.com/filecoin-project/venus/venus-shared/types" marketTypes "github.com/filecoin-project/venus/venus-shared/types/market" msgTypes "github.com/filecoin-project/venus/venus-shared/types/messager" "github.com/google/uuid" @@ -43,7 +43,7 @@ type ServiceImpl struct { var _ IService = &ServiceImpl{} -func (s *ServiceImpl) ChainHead(ctx context.Context) (*venusTypes.TipSet, error) { +func (s *ServiceImpl) ChainHead(ctx context.Context) (*types.TipSet, error) { return s.Node.ChainHead(ctx) } @@ -61,7 +61,7 @@ func (s *ServiceImpl) MsgSend(ctx context.Context, params *MsgSendReq) (string, return "", err } - msg := &venusTypes.Message{ + msg := &types.Message{ From: params.From, To: params.To, Value: params.Value, @@ -217,7 +217,7 @@ func (s *ServiceImpl) MinerCreate(ctx context.Context, params *MinerCreateReq) ( params.SealProofType = sealProof if params.Owner == address.Undef { - actor, err := s.Node.StateLookupID(ctx, params.From, venusTypes.EmptyTSK) + actor, err := s.Node.StateLookupID(ctx, params.From, types.EmptyTSK) if err != nil { return address.Undef, err } @@ -232,7 +232,7 @@ func (s *ServiceImpl) MinerCreate(ctx context.Context, params *MinerCreateReq) ( if err != nil { return address.Undef, err } - msg := &venusTypes.Message{ + msg := &types.Message{ From: params.From, To: power.Address, Method: power.Methods.CreateMiner, @@ -293,7 +293,7 @@ func (s *ServiceImpl) MinerGetRetrievalAsk(ctx context.Context, mAddr address.Ad } func (s *ServiceImpl) MinerSetStorageAsk(ctx context.Context, p *MinerSetAskReq) error { - info, err := s.Node.StateMinerInfo(ctx, p.Miner, venusTypes.EmptyTSK) + info, err := s.Node.StateMinerInfo(ctx, p.Miner, types.EmptyTSK) if err != nil { return fmt.Errorf("get miner sector size failed: %s", err) } @@ -305,7 +305,7 @@ func (s *ServiceImpl) MinerSetStorageAsk(ctx context.Context, p *MinerSetAskReq) } if p.MaxPieceSize > smax { - return fmt.Errorf("max piece size (w/bit-padding) %s cannot exceed miner sector size %s", venusTypes.SizeStr(venusTypes.NewInt(uint64(p.MaxPieceSize))), venusTypes.SizeStr(venusTypes.NewInt(uint64(smax)))) + return fmt.Errorf("max piece size (w/bit-padding) %s cannot exceed miner sector size %s", types.SizeStr(types.NewInt(uint64(p.MaxPieceSize))), types.SizeStr(types.NewInt(uint64(smax)))) } return s.Market.MarketSetAsk(ctx, p.Miner, p.Price, p.VerifiedPrice, p.Duration, p.MinPieceSize, p.MaxPieceSize) } @@ -315,21 +315,21 @@ func (s *ServiceImpl) MinerSetRetrievalAsk(ctx context.Context, p *MinerSetRetri } func (s *ServiceImpl) MinerInfo(ctx context.Context, mAddr address.Address) (*MinerInfoResp, error) { - mi, err := s.Node.StateMinerInfo(ctx, mAddr, venusTypes.EmptyTSK) + mi, err := s.Node.StateMinerInfo(ctx, mAddr, types.EmptyTSK) if err != nil { return nil, fmt.Errorf("get miner(%s) info failed: %s", mAddr, err) } - availBalance, err := s.Node.StateMinerAvailableBalance(ctx, mAddr, venusTypes.EmptyTSK) + availBalance, err := s.Node.StateMinerAvailableBalance(ctx, mAddr, types.EmptyTSK) if err != nil { return nil, fmt.Errorf("get miner(%s) available balance failed: %s", mAddr, err) } - power, err := s.Node.StateMinerPower(ctx, mAddr, venusTypes.EmptyTSK) + power, err := s.Node.StateMinerPower(ctx, mAddr, types.EmptyTSK) if err != nil { return nil, fmt.Errorf("get miner(%s) power failed: %s", mAddr, err) } - deadline, err := s.Node.StateMinerProvingDeadline(ctx, mAddr, venusTypes.EmptyTSK) + deadline, err := s.Node.StateMinerProvingDeadline(ctx, mAddr, types.EmptyTSK) if err != nil { return nil, fmt.Errorf("get miner(%s) deadline failed: %s", mAddr, err) } @@ -343,12 +343,12 @@ func (s *ServiceImpl) MinerInfo(ctx context.Context, mAddr address.Address) (*Mi } func (s *ServiceImpl) MinerSetOwner(ctx context.Context, p *MinerSetOwnerReq) error { - minerInfo, err := s.Node.StateMinerInfo(ctx, p.Miner, venusTypes.EmptyTSK) + minerInfo, err := s.Node.StateMinerInfo(ctx, p.Miner, types.EmptyTSK) if err != nil { return fmt.Errorf("get miner(%s) info failed: %s", p.Miner, err) } - newOwnerId, err := s.Node.StateLookupID(ctx, p.NewOwner, venusTypes.EmptyTSK) + newOwnerId, err := s.Node.StateLookupID(ctx, p.NewOwner, types.EmptyTSK) if err != nil { return fmt.Errorf("get new owner(%s) id failed: %s", p.NewOwner, err) } @@ -362,7 +362,7 @@ func (s *ServiceImpl) MinerSetOwner(ctx context.Context, p *MinerSetOwnerReq) er return fmt.Errorf("serialize params failed: %s", err) } - msg, err := s.PushMessageAndWait(ctx, &venusTypes.Message{ + msg, err := s.PushMessageAndWait(ctx, &types.Message{ From: minerInfo.Owner, To: p.Miner, Method: builtin.MethodsMiner.ChangeOwnerAddress, @@ -373,7 +373,31 @@ func (s *ServiceImpl) MinerSetOwner(ctx context.Context, p *MinerSetOwnerReq) er return fmt.Errorf("push message(%s) failed: %s", msg.ID, err) } - msg, err = s.PushMessageAndWait(ctx, &venusTypes.Message{ + return nil +} + +func (s *ServiceImpl) MinerConfirmOwner(ctx context.Context, p *MinerSetOwnerReq) (oldOwner address.Address, err error) { + minerInfo, err := s.Node.StateMinerInfo(ctx, p.Miner, types.EmptyTSK) + if err != nil { + return address.Undef, fmt.Errorf("get miner(%s) info failed: %s", p.Miner, err) + } + oldOwner = minerInfo.Owner + + newOwnerId, err := s.Node.StateLookupID(ctx, p.NewOwner, types.EmptyTSK) + if err != nil { + return address.Undef, fmt.Errorf("get new owner(%s) id failed: %s", p.NewOwner, err) + } + + if minerInfo.Owner == newOwnerId { + return address.Undef, fmt.Errorf("new owner(%s) is the same as old owner(%s)", p.NewOwner, minerInfo.Owner) + } + + param, err := actors.SerializeParams(&newOwnerId) + if err != nil { + return address.Undef, fmt.Errorf("serialize params failed: %s", err) + } + + msg, err := s.PushMessageAndWait(ctx, &types.Message{ From: p.NewOwner, To: p.Miner, Method: builtin.MethodsMiner.ChangeOwnerAddress, @@ -381,19 +405,19 @@ func (s *ServiceImpl) MinerSetOwner(ctx context.Context, p *MinerSetOwnerReq) er Value: big.Zero(), }, nil) if err != nil { - return fmt.Errorf("push message(%s) failed: %s", msg.ID, err) + return address.Undef, fmt.Errorf("push message(%s) failed: %s", msg.ID, err) } - return nil + return oldOwner, nil } func (s *ServiceImpl) MinerSetWorker(ctx context.Context, req *MinerSetWorkerReq) (WorkerChangeEpoch abi.ChainEpoch, err error) { - minerInfo, err := s.Node.StateMinerInfo(ctx, req.Miner, venusTypes.EmptyTSK) + minerInfo, err := s.Node.StateMinerInfo(ctx, req.Miner, types.EmptyTSK) if err != nil { return 0, fmt.Errorf("get miner(%s) info failed: %s", req.Miner, err) } - newWorkerId, err := s.Node.StateLookupID(ctx, req.NewWorker, venusTypes.EmptyTSK) + newWorkerId, err := s.Node.StateLookupID(ctx, req.NewWorker, types.EmptyTSK) if err != nil { return 0, fmt.Errorf("get new worker(%s) id failed: %s", req.NewWorker, err) } @@ -406,7 +430,7 @@ func (s *ServiceImpl) MinerSetWorker(ctx context.Context, req *MinerSetWorkerReq return 0, fmt.Errorf("new worker(%s) has been proposed before, which will be effective after epoch(%d)", minerInfo.NewWorker, minerInfo.WorkerChangeEpoch) } - param, err := actors.SerializeParams(&venusTypes.ChangeWorkerAddressParams{ + param, err := actors.SerializeParams(&types.ChangeWorkerAddressParams{ NewWorker: newWorkerId, NewControlAddrs: minerInfo.ControlAddresses, }) @@ -414,7 +438,7 @@ func (s *ServiceImpl) MinerSetWorker(ctx context.Context, req *MinerSetWorkerReq return 0, fmt.Errorf("serialize params failed: %s", err) } - msg, err := s.PushMessageAndWait(ctx, &venusTypes.Message{ + msg, err := s.PushMessageAndWait(ctx, &types.Message{ From: minerInfo.Owner, To: req.Miner, Method: builtin.MethodsMiner.ChangeWorkerAddress, @@ -425,7 +449,7 @@ func (s *ServiceImpl) MinerSetWorker(ctx context.Context, req *MinerSetWorkerReq return 0, fmt.Errorf("push message(%s) failed: %s", msg.ID, err) } - minerInfo, err = s.Node.StateMinerInfo(ctx, req.Miner, venusTypes.EmptyTSK) + minerInfo, err = s.Node.StateMinerInfo(ctx, req.Miner, types.EmptyTSK) if err != nil { return 0, fmt.Errorf("get miner(%s) info failed: %s", req.Miner, err) } @@ -434,7 +458,7 @@ func (s *ServiceImpl) MinerSetWorker(ctx context.Context, req *MinerSetWorkerReq } func (s *ServiceImpl) MinerConfirmWorker(ctx context.Context, req *MinerSetWorkerReq) error { - minerInfo, err := s.Node.StateMinerInfo(ctx, req.Miner, venusTypes.EmptyTSK) + minerInfo, err := s.Node.StateMinerInfo(ctx, req.Miner, types.EmptyTSK) if err != nil { return fmt.Errorf("get miner(%s) info failed: %s", req.Miner, err) } @@ -456,7 +480,7 @@ func (s *ServiceImpl) MinerConfirmWorker(ctx context.Context, req *MinerSetWorke return fmt.Errorf("worker change epoch(%d) is not reached", minerInfo.WorkerChangeEpoch) } - msg, err := s.PushMessageAndWait(ctx, &venusTypes.Message{ + msg, err := s.PushMessageAndWait(ctx, &types.Message{ From: minerInfo.Owner, To: req.Miner, Method: builtin.MethodsMiner.ConfirmUpdateWorkerKey, @@ -470,7 +494,7 @@ func (s *ServiceImpl) MinerConfirmWorker(ctx context.Context, req *MinerSetWorke } func (s *ServiceImpl) MinerSetControllers(ctx context.Context, req *MinerSetControllersReq) (oldController []address.Address, err error) { - minerInfo, err := s.Node.StateMinerInfo(ctx, req.Miner, venusTypes.EmptyTSK) + minerInfo, err := s.Node.StateMinerInfo(ctx, req.Miner, types.EmptyTSK) if err != nil { return nil, fmt.Errorf("get miner(%s) info failed: %s", req.Miner, err) } @@ -478,7 +502,7 @@ func (s *ServiceImpl) MinerSetControllers(ctx context.Context, req *MinerSetCont newControllers := make([]address.Address, 0, len(req.NewControllers)) for _, c := range req.NewControllers { - id, err := s.Node.StateLookupID(ctx, c, venusTypes.EmptyTSK) + id, err := s.Node.StateLookupID(ctx, c, types.EmptyTSK) if err != nil { return nil, fmt.Errorf("get controller(%s) id failed: %s", c, err) } @@ -489,7 +513,7 @@ func (s *ServiceImpl) MinerSetControllers(ctx context.Context, req *MinerSetCont return nil, fmt.Errorf("new controllers(%s) is the same as old controllers(%s)", req.NewControllers, minerInfo.ControlAddresses) } - rawParam := &venusTypes.ChangeWorkerAddressParams{ + rawParam := &types.ChangeWorkerAddressParams{ NewWorker: minerInfo.Worker, NewControlAddrs: newControllers, } @@ -499,7 +523,7 @@ func (s *ServiceImpl) MinerSetControllers(ctx context.Context, req *MinerSetCont return nil, fmt.Errorf("serialize params failed: %s", err) } - msg, err := s.PushMessageAndWait(ctx, &venusTypes.Message{ + msg, err := s.PushMessageAndWait(ctx, &types.Message{ From: minerInfo.Owner, To: req.Miner, Method: builtin.MethodsMiner.ChangeWorkerAddress, @@ -513,8 +537,98 @@ func (s *ServiceImpl) MinerSetControllers(ctx context.Context, req *MinerSetCont return oldController, nil } +func (s *ServiceImpl) MinerSetBeneficiary(ctx context.Context, req *MinerSetBeneficiaryReq) (*types.PendingBeneficiaryChange, error) { + minerInfo, err := s.Node.StateMinerInfo(ctx, req.Miner, types.EmptyTSK) + if err != nil { + return nil, fmt.Errorf("get miner(%s) info failed: %s", req.Miner, err) + } + + newBeneficiary, err := s.Node.StateLookupID(ctx, req.NewBeneficiary, types.EmptyTSK) + if err != nil { + return nil, fmt.Errorf("get beneficiary(%s) id failed: %s", req.NewBeneficiary, err) + } + req.NewBeneficiary = newBeneficiary + + if minerInfo.Beneficiary == newBeneficiary { + return nil, fmt.Errorf("new beneficiary(%s) is the same as old beneficiary(%s)", req.NewBeneficiary, minerInfo.Beneficiary) + } + + param, err := actors.SerializeParams(&req.ChangeBeneficiaryParams) + if err != nil { + return nil, fmt.Errorf("serialize params failed: %s", err) + } + + // owner proposal + msg, err := s.PushMessageAndWait(ctx, &types.Message{ + From: minerInfo.Owner, + To: req.Miner, + Method: builtin.MethodsMiner.ChangeBeneficiary, + Params: param, + Value: big.Zero(), + }, nil) + if err != nil { + return nil, fmt.Errorf("push message(%s) failed: %s", msg.ID, err) + } + + minerInfo, err = s.Node.StateMinerInfo(ctx, req.Miner, types.EmptyTSK) + if err != nil { + return nil, fmt.Errorf("get miner(%s) info failed: %s", req.Miner, err) + } + + if minerInfo.PendingBeneficiaryTerm == nil { + return nil, fmt.Errorf("owner proposal beneficial change failed") + } + + return minerInfo.PendingBeneficiaryTerm, nil +} + +func (s *ServiceImpl) MinerConfirmBeneficiary(ctx context.Context, req *MinerConfirmBeneficiaryReq) (confirmor address.Address, err error) { + minerInfo, err := s.Node.StateMinerInfo(ctx, req.Miner, types.EmptyTSK) + if err != nil { + return address.Undef, fmt.Errorf("get miner(%s) info failed: %s", req.Miner, err) + } + + if minerInfo.PendingBeneficiaryTerm == nil { + return address.Undef, fmt.Errorf("miner(%s) no pending beneficiary", req.Miner) + } + + sender := minerInfo.Beneficiary + if !req.ByNominee { + if minerInfo.PendingBeneficiaryTerm.ApprovedByBeneficiary { + return address.Undef, fmt.Errorf("proposal already approved by beneficiary(%s)", minerInfo.Beneficiary) + } + } else { + if minerInfo.PendingBeneficiaryTerm.ApprovedByNominee { + return address.Undef, fmt.Errorf("proposal already approved by nominee(%s)", minerInfo.PendingBeneficiaryTerm.NewBeneficiary) + } + sender = minerInfo.PendingBeneficiaryTerm.NewBeneficiary + } + + param, err := actors.SerializeParams(&types.ChangeBeneficiaryParams{ + NewBeneficiary: minerInfo.PendingBeneficiaryTerm.NewBeneficiary, + NewQuota: minerInfo.PendingBeneficiaryTerm.NewQuota, + NewExpiration: minerInfo.PendingBeneficiaryTerm.NewExpiration, + }) + if err != nil { + return address.Undef, fmt.Errorf("serialize params failed: %s", err) + } + + msg, err := s.PushMessageAndWait(ctx, &types.Message{ + From: sender, + To: req.Miner, + Method: builtin.MethodsMiner.ChangeBeneficiary, + Params: param, + Value: big.Zero(), + }, nil) + if err != nil { + return address.Undef, fmt.Errorf("push message(%s) failed: %s", msg.ID, err) + } + + return sender, nil +} + func (s *ServiceImpl) MinerGetDeadlines(ctx context.Context, mAddr address.Address) (*dline.Info, error) { - return s.Node.StateMinerProvingDeadline(ctx, mAddr, venusTypes.EmptyTSK) + return s.Node.StateMinerProvingDeadline(ctx, mAddr, types.EmptyTSK) } func (s *ServiceImpl) StorageDealList(ctx context.Context, miner address.Address) ([]marketTypes.MinerDeal, error) { @@ -548,11 +662,11 @@ func (s *ServiceImpl) RetrievalDealList(ctx context.Context) ([]marketTypes.Prov func (s *ServiceImpl) SectorExtend(ctx context.Context, req SectorExtendReq) error { var err error - rawParams := &venusTypes.ExtendSectorExpirationParams{} + rawParams := &types.ExtendSectorExpirationParams{} sectors := map[lminer.SectorLocation][]abi.SectorNumber{} for _, num := range req.SectorNumbers { - p, err := s.Node.StateSectorPartition(ctx, req.Miner, num, venusTypes.EmptyTSK) + p, err := s.Node.StateSectorPartition(ctx, req.Miner, num, types.EmptyTSK) if err != nil { return fmt.Errorf("get sector partition failed: %s", err) } @@ -569,7 +683,7 @@ func (s *ServiceImpl) SectorExtend(ctx context.Context, req SectorExtendReq) err for i, n := range numbers { nums[i] = uint64(n) } - rawParams.Extensions = append(rawParams.Extensions, venusTypes.ExpirationExtension{ + rawParams.Extensions = append(rawParams.Extensions, types.ExpirationExtension{ Deadline: p.Deadline, Partition: p.Partition, Sectors: bitfield.NewFromSet(nums), @@ -582,12 +696,12 @@ func (s *ServiceImpl) SectorExtend(ctx context.Context, req SectorExtendReq) err return err } - mi, err := s.Node.StateMinerInfo(ctx, req.Miner, venusTypes.EmptyTSK) + mi, err := s.Node.StateMinerInfo(ctx, req.Miner, types.EmptyTSK) if err != nil { return fmt.Errorf("get miner info failed: %s", err) } - _, err = s.Messager.PushMessage(ctx, &venusTypes.Message{ + _, err = s.Messager.PushMessage(ctx, &types.Message{ From: mi.Worker, To: req.Miner, Method: builtin.MethodsMiner.ExtendSectorExpiration, @@ -604,12 +718,12 @@ func (s *ServiceImpl) SectorExtend(ctx context.Context, req SectorExtendReq) err func (s *ServiceImpl) SectorGet(ctx context.Context, req SectorGetReq) ([]*SectorResp, error) { ret := make([]*SectorResp, 0) for _, num := range req.SectorNumbers { - sector, err := s.Node.StateSectorGetInfo(ctx, req.Miner, num, venusTypes.EmptyTSK) + sector, err := s.Node.StateSectorGetInfo(ctx, req.Miner, num, types.EmptyTSK) if err != nil { return nil, fmt.Errorf("get sector(%s) info failed: %s", num, err) } - p, err := s.Node.StateSectorPartition(ctx, req.Miner, num, venusTypes.EmptyTSK) + p, err := s.Node.StateSectorPartition(ctx, req.Miner, num, types.EmptyTSK) if err != nil { return nil, fmt.Errorf("get sector(%s) partition failed: %s", num, err) } @@ -623,7 +737,7 @@ func (s *ServiceImpl) SectorGet(ctx context.Context, req SectorGetReq) ([]*Secto return ret, nil } -func (s *ServiceImpl) PushMessageAndWait(ctx context.Context, msg *venusTypes.Message, spec *msgTypes.SendSpec) (*msgTypes.Message, error) { +func (s *ServiceImpl) PushMessageAndWait(ctx context.Context, msg *types.Message, spec *msgTypes.SendSpec) (*msgTypes.Message, error) { id, err := s.Messager.PushMessage(ctx, msg, spec) if err != nil { return nil, err diff --git a/service/proxy_gen.go b/service/proxy_gen.go index 516a15d..44f4dbf 100644 --- a/service/proxy_gen.go +++ b/service/proxy_gen.go @@ -11,34 +11,38 @@ import ( "github.com/filecoin-project/go-state-types/dline" cid "github.com/ipfs/go-cid" + "github.com/filecoin-project/venus/venus-shared/types" venusTypes "github.com/filecoin-project/venus/venus-shared/types" marketTypes "github.com/filecoin-project/venus/venus-shared/types/market" ) type IServiceStruct struct { Internal struct { - AddrList func(ctx context.Context) ([]*AddrsResp, error) ` GET:"/addr/list" ` - AddrOperate func(ctx context.Context, params *AddrsOperateReq) error ` PUT:"/addr/operate" ` - ChainHead func(ctx context.Context) (*venusTypes.TipSet, error) ` GET:"/chain/head" ` - MinerConfirmWorker func(ctx context.Context, req *MinerSetWorkerReq) error ` PUT:"/miner/confirmworker" ` - MinerCreate func(ctx context.Context, params *MinerCreateReq) (address.Address, error) ` POST:"/miner/create" ` - MinerGetDeadlines func(ctx context.Context, mAddr address.Address) (*dline.Info, error) ` GET:"/miner/deadline" ` - MinerGetRetrievalAsk func(ctx context.Context, mAddr address.Address) (*retrievalmarket.Ask, error) ` GET:"/miner/retrievalask/" ` - MinerGetStorageAsk func(ctx context.Context, mAddr address.Address) (*storagemarket.StorageAsk, error) ` GET:"/miner/storageask/" ` - MinerInfo func(ctx context.Context, mAddr address.Address) (*MinerInfoResp, error) ` GET:"/miner/info" ` - MinerSetControllers func(ctx context.Context, req *MinerSetControllersReq) (oldController []address.Address, err error) ` PUT:"/miner/controllers" ` - MinerSetOwner func(ctx context.Context, p *MinerSetOwnerReq) error ` PUT:"/miner/owner" ` - MinerSetRetrievalAsk func(ctx context.Context, p *MinerSetRetrievalAskReq) error ` PUT:"/miner/retrievalask/" ` - MinerSetStorageAsk func(ctx context.Context, p *MinerSetAskReq) error ` PUT:"/miner/storageask/" ` - MinerSetWorker func(ctx context.Context, req *MinerSetWorkerReq) (WorkerChangeEpoch abi.ChainEpoch, err error) ` PUT:"/miner/worker" ` - MsgQuery func(ctx context.Context, params *MsgQueryReq) ([]*MsgResp, error) ` GET:"/msg/query" ` - MsgReplace func(ctx context.Context, params *MsgReplaceReq) (cid.Cid, error) ` POST:"/msg/replace" ` - MsgSend func(ctx context.Context, params *MsgSendReq) (string, error) ` POST:"/msg/send" ` - RetrievalDealList func(ctx context.Context) ([]marketTypes.ProviderDealState, error) ` GET:"/deal/retrieval" ` - SectorExtend func(ctx context.Context, req SectorExtendReq) error ` PUT:"/sector/extend" ` - SectorGet func(ctx context.Context, req SectorGetReq) ([]*SectorResp, error) ` GET:"/sector/get" ` - StorageDealList func(ctx context.Context, miner address.Address) ([]marketTypes.MinerDeal, error) ` GET:"/deal/storage" ` - StorageDealUpdateState func(ctx context.Context, req StorageDealUpdateStateReq) error ` PUT:"/deal/storage/state" ` + AddrList func(ctx context.Context) ([]*AddrsResp, error) ` GET:"/addr/list" ` + AddrOperate func(ctx context.Context, params *AddrsOperateReq) error ` PUT:"/addr/operate" ` + ChainHead func(ctx context.Context) (*venusTypes.TipSet, error) ` GET:"/chain/head" ` + MinerConfirmBeneficiary func(ctx context.Context, req *MinerConfirmBeneficiaryReq) (confirmor address.Address, err error) ` PUT:"/miner/confirmbeneficiary" ` + MinerConfirmOwner func(ctx context.Context, p *MinerSetOwnerReq) (oldOwner address.Address, err error) ` PUT:"/miner/confirmowner" ` + MinerConfirmWorker func(ctx context.Context, req *MinerSetWorkerReq) error ` PUT:"/miner/confirmworker" ` + MinerCreate func(ctx context.Context, params *MinerCreateReq) (address.Address, error) ` POST:"/miner/create" ` + MinerGetDeadlines func(ctx context.Context, mAddr address.Address) (*dline.Info, error) ` GET:"/miner/deadline" ` + MinerGetRetrievalAsk func(ctx context.Context, mAddr address.Address) (*retrievalmarket.Ask, error) ` GET:"/miner/retrievalask/" ` + MinerGetStorageAsk func(ctx context.Context, mAddr address.Address) (*storagemarket.StorageAsk, error) ` GET:"/miner/storageask/" ` + MinerInfo func(ctx context.Context, mAddr address.Address) (*MinerInfoResp, error) ` GET:"/miner/info" ` + MinerSetBeneficiary func(ctx context.Context, req *MinerSetBeneficiaryReq) (*types.PendingBeneficiaryChange, error) ` PUT:"/miner/beneficiary" ` + MinerSetControllers func(ctx context.Context, req *MinerSetControllersReq) (oldController []address.Address, err error) ` PUT:"/miner/controllers" ` + MinerSetOwner func(ctx context.Context, p *MinerSetOwnerReq) error ` PUT:"/miner/owner" ` + MinerSetRetrievalAsk func(ctx context.Context, p *MinerSetRetrievalAskReq) error ` PUT:"/miner/retrievalask/" ` + MinerSetStorageAsk func(ctx context.Context, p *MinerSetAskReq) error ` PUT:"/miner/storageask/" ` + MinerSetWorker func(ctx context.Context, req *MinerSetWorkerReq) (WorkerChangeEpoch abi.ChainEpoch, err error) ` PUT:"/miner/worker" ` + MsgQuery func(ctx context.Context, params *MsgQueryReq) ([]*MsgResp, error) ` GET:"/msg/query" ` + MsgReplace func(ctx context.Context, params *MsgReplaceReq) (cid.Cid, error) ` POST:"/msg/replace" ` + MsgSend func(ctx context.Context, params *MsgSendReq) (string, error) ` POST:"/msg/send" ` + RetrievalDealList func(ctx context.Context) ([]marketTypes.ProviderDealState, error) ` GET:"/deal/retrieval" ` + SectorExtend func(ctx context.Context, req SectorExtendReq) error ` PUT:"/sector/extend" ` + SectorGet func(ctx context.Context, req SectorGetReq) ([]*SectorResp, error) ` GET:"/sector/get" ` + StorageDealList func(ctx context.Context, miner address.Address) ([]marketTypes.MinerDeal, error) ` GET:"/deal/storage" ` + StorageDealUpdateState func(ctx context.Context, req StorageDealUpdateStateReq) error ` PUT:"/deal/storage/state" ` } } @@ -51,6 +55,12 @@ func (s *IServiceStruct) AddrOperate(p0 context.Context, p1 *AddrsOperateReq) er func (s *IServiceStruct) ChainHead(p0 context.Context) (*venusTypes.TipSet, error) { return s.Internal.ChainHead(p0) } +func (s *IServiceStruct) MinerConfirmBeneficiary(p0 context.Context, p1 *MinerConfirmBeneficiaryReq) (address.Address, error) { + return s.Internal.MinerConfirmBeneficiary(p0, p1) +} +func (s *IServiceStruct) MinerConfirmOwner(p0 context.Context, p1 *MinerSetOwnerReq) (address.Address, error) { + return s.Internal.MinerConfirmOwner(p0, p1) +} func (s *IServiceStruct) MinerConfirmWorker(p0 context.Context, p1 *MinerSetWorkerReq) error { return s.Internal.MinerConfirmWorker(p0, p1) } @@ -69,6 +79,9 @@ func (s *IServiceStruct) MinerGetStorageAsk(p0 context.Context, p1 address.Addre func (s *IServiceStruct) MinerInfo(p0 context.Context, p1 address.Address) (*MinerInfoResp, error) { return s.Internal.MinerInfo(p0, p1) } +func (s *IServiceStruct) MinerSetBeneficiary(p0 context.Context, p1 *MinerSetBeneficiaryReq) (*types.PendingBeneficiaryChange, error) { + return s.Internal.MinerSetBeneficiary(p0, p1) +} func (s *IServiceStruct) MinerSetControllers(p0 context.Context, p1 *MinerSetControllersReq) ([]address.Address, error) { return s.Internal.MinerSetControllers(p0, p1) } diff --git a/service/transport.go b/service/transport.go index bc7ce2d..4d19bae 100644 --- a/service/transport.go +++ b/service/transport.go @@ -156,6 +156,17 @@ type MinerSetRetrievalAskReq struct { Miner address.Address } +type MinerSetBeneficiaryReq struct { + Miner address.Address + venusTypes.ChangeBeneficiaryParams +} + +type MinerConfirmBeneficiaryReq struct { + Miner address.Address + NewBeneficiary address.Address + ByNominee bool +} + type StorageDealUpdateStateReq struct { ProposalCid cid.Cid State storagemarket.StorageDealStatus