Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

review of beneficiary change #6

Merged
merged 1 commit into from
Feb 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 19 additions & 20 deletions actors/builtin/miner/miner_actor.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,12 +248,16 @@ func (a Actor) ChangeOwnerAddress(rt Runtime, newAddress *addr.Address) *abi.Emp
rt.Abortf(exitcode.ErrIllegalArgument, "expected confirmation of %v, got %v",
info.PendingOwnerAddress, newAddress)
}
info.Owner = *info.PendingOwnerAddress
//change beneficiary address to new owner if current beneficiary address equal to old owner address

// Change beneficiary address to new owner if current beneficiary address equal to old owner address
if info.Beneficiary == info.Owner {
info.Beneficiary = *info.PendingOwnerAddress
}
// Cancel pending beneficiary term change when the owner changes
info.PendingBeneficiaryTerm = nil

// Set the new owner address
info.Owner = *info.PendingOwnerAddress
}

// Clear any resulting no-op change.
Expand Down Expand Up @@ -1977,7 +1981,7 @@ func (a Actor) ReportConsensusFault(rt Runtime, params *ReportConsensusFaultPara
type WithdrawBalanceParams = miner0.WithdrawBalanceParams

// Attempt to withdraw the specified amount from the miner's available balance.
// Only beneficiary key have permission to withdraw (to the beneficiary).
// Only beneficiary key and owner key have permission to withdraw (to the beneficiary).
// If less than the specified amount is available, yields the entire available balance.
// Returns the amount withdrawn.
func (a Actor) WithdrawBalance(rt Runtime, params *WithdrawBalanceParams) *abi.TokenAmount {
Expand All @@ -1994,8 +1998,7 @@ func (a Actor) WithdrawBalance(rt Runtime, params *WithdrawBalanceParams) *abi.T
rt.StateTransaction(&st, func() {
var err error
info = getMinerInfo(rt, &st)
// Only the beneficiary is allowed to withdraw the balance
// and not the worker.
// Only the beneficiary and owner are allowed to withdraw the balance
rt.ValidateImmediateCallerIs(info.Owner, info.Beneficiary)
// Ensure we don't have any pending terminations.
if count, err := st.EarlyTerminations.Count(); err != nil {
Expand Down Expand Up @@ -2023,25 +2026,22 @@ func (a Actor) WithdrawBalance(rt Runtime, params *WithdrawBalanceParams) *abi.T
feeToBurn = RepayDebtsOrAbort(rt, &st)

// To get the actual amount to be withdrawed
if info.Beneficiary == info.Owner {
amountWithdrawn = big.Min(availableBalance, params.AmountRequested)
} else {
amountWithdrawn = info.BeneficiaryTerm.Available(rt.CurrEpoch())
builtin.RequirePredicate(rt, amountWithdrawn.GreaterThan(big.Zero()), exitcode.ErrForbidden,
amountWithdrawn = big.Min(availableBalance, params.AmountRequested)
builtin.RequireState(rt, amountWithdrawn.GreaterThanEqual(big.Zero()), "negative amount to withdraw: %v", amountWithdrawn)
builtin.RequireState(rt, amountWithdrawn.LessThanEqual(availableBalance), "amount to withdraw %v < available %v", amountWithdrawn, availableBalance)
if info.Beneficiary != info.Owner {
remainingQuota := info.BeneficiaryTerm.Available(rt.CurrEpoch())
builtin.RequirePredicate(rt, remainingQuota.GreaterThan(big.Zero()), exitcode.ErrForbidden,
"beneficiary(%s) quota %s used quota %s expiration epoch %d current epoch %d", info.Beneficiary, info.BeneficiaryTerm.Quota, info.BeneficiaryTerm.UsedQuota, info.BeneficiaryTerm.Expiration, rt.CurrEpoch())
amountWithdrawn = big.Min(big.Min(availableBalance, params.AmountRequested), amountWithdrawn)
}
amountWithdrawn = big.Min(remainingQuota, amountWithdrawn)

if info.Beneficiary != info.Owner {
info.BeneficiaryTerm.UsedQuota = big.Add(info.BeneficiaryTerm.UsedQuota, amountWithdrawn)
}

err = st.SaveInfo(adt.AsStore(rt), info)
builtin.RequireNoErr(rt, err, exitcode.ErrIllegalState, "could not save miner info")
})

builtin.RequireState(rt, amountWithdrawn.GreaterThanEqual(big.Zero()), "negative amount to withdraw: %v", amountWithdrawn)
builtin.RequireState(rt, amountWithdrawn.LessThanEqual(availableBalance), "amount to withdraw %v < available %v", amountWithdrawn, availableBalance)

if amountWithdrawn.GreaterThan(abi.NewTokenAmount(0)) {
code := rt.Send(info.Beneficiary, builtin.MethodSend, nil, amountWithdrawn, &builtin.Discard{})
builtin.RequireSuccess(rt, code, "failed to withdraw balance")
Expand Down Expand Up @@ -3138,7 +3138,7 @@ type ChangeBeneficiaryParams struct {
NewExpiration abi.ChainEpoch
}

// ChangeBeneficiary proposal/approve beneficiary change
// ChangeBeneficiary proposes/approves a beneficiary change
func (a Actor) ChangeBeneficiary(rt Runtime, params *ChangeBeneficiaryParams) *abi.EmptyValue {
newBeneficiary, ok := rt.ResolveAddress(params.NewBeneficiary)
if !ok {
Expand All @@ -3151,7 +3151,6 @@ func (a Actor) ChangeBeneficiary(rt Runtime, params *ChangeBeneficiaryParams) *a
if rt.Caller() == info.Owner {
// This is a ChangeBeneficiary proposal when the caller is Owner
if newBeneficiary != info.Owner {
// No need to check others when the newBeneficiary is set back to owner
if params.NewExpiration <= rt.CurrEpoch() {
rt.Abortf(exitcode.ErrIllegalArgument, "new beneficial expire date (%d) must bigger than current epoch (%d)", params.NewExpiration, rt.CurrEpoch())
}
Expand All @@ -3160,7 +3159,7 @@ func (a Actor) ChangeBeneficiary(rt Runtime, params *ChangeBeneficiaryParams) *a
rt.Abortf(exitcode.ErrIllegalArgument, "beneficial quota (%s) must bigger than zero", params.NewQuota)
}
} else {
//expiration/quota must set to 0 while change beneficiary to owner
// Expiration/quota must set to 0 while change beneficiary to owner
if params.NewExpiration != 0 {
rt.Abortf(exitcode.ErrIllegalArgument, "owner beneficial expire date (%d) must be zero", params.NewExpiration)
}
Expand All @@ -3177,7 +3176,7 @@ func (a Actor) ChangeBeneficiary(rt Runtime, params *ChangeBeneficiaryParams) *a
}

if info.BeneficiaryTerm.Available(rt.CurrEpoch()).Equals(big.Zero()) {
//set current beneficiary to approved when current beneficiary not effected
// Set current beneficiary to approved when current beneficiary is not effective
info.PendingBeneficiaryTerm.ApprovedByBeneficiary = true
}
} else {
Expand Down
26 changes: 13 additions & 13 deletions actors/builtin/miner/miner_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,31 +86,31 @@ const PrecommitCleanUpAmtBitwidth = 6
const SectorsAmtBitwidth = 5

type BeneficiaryTerm struct {
//Quota: The total amount the current beneficiary can withdraw. Monotonic, but reset when beneficiary changes.
// Quota: The total amount the current beneficiary can withdraw. Monotonic, but reset when beneficiary changes.
Quota abi.TokenAmount
//Expiration: The epoch at which the beneficiary's rights expire and revert to the owner
// Expiration: The epoch at which the beneficiary's rights expire and revert to the owner
Expiration abi.ChainEpoch
//UsedQuota: The amount of quota the current beneficiary has already withdrawn
// UsedQuota: The amount of quota the current beneficiary has already withdrawn
UsedQuota abi.TokenAmount
}

//IsUsedUp check whether beneficiary has use up all quota
func (beneficiaryInfo *BeneficiaryTerm) IsUsedUp() bool {
return beneficiaryInfo.UsedQuota.GreaterThanEqual(beneficiaryInfo.Quota)
// IsUsedUp check whether beneficiary has use up all quota
func (beneficiaryTerm *BeneficiaryTerm) IsUsedUp() bool {
return beneficiaryTerm.UsedQuota.GreaterThanEqual(beneficiaryTerm.Quota)
}

//IsExpire check if the beneficiary is within the validity period
func (beneficiaryInfo *BeneficiaryTerm) IsExpire(cur abi.ChainEpoch) bool {
return beneficiaryInfo.Expiration <= cur
// IsExpire check if the beneficiary is within the validity period
func (beneficiaryTerm *BeneficiaryTerm) IsExpire(cur abi.ChainEpoch) bool {
return beneficiaryTerm.Expiration <= cur
}

//Available get the amount that the beneficiary has not yet withdrawn
func (beneficiaryInfo *BeneficiaryTerm) Available(cur abi.ChainEpoch) abi.TokenAmount {
// Available get the amount that the beneficiary has not yet withdrawn
func (beneficiaryTerm *BeneficiaryTerm) Available(cur abi.ChainEpoch) abi.TokenAmount {
// Return 0 when the usedQuota > Quota for safe
if beneficiaryInfo.IsExpire(cur) {
if beneficiaryTerm.IsExpire(cur) {
return big.Zero()
}
return big.Max(big.Sub(beneficiaryInfo.Quota, beneficiaryInfo.UsedQuota), big.NewInt(0))
return big.Max(big.Sub(beneficiaryTerm.Quota, beneficiaryTerm.UsedQuota), big.NewInt(0))
}

type PendingBeneficiaryChange struct {
Expand Down