Skip to content

Commit

Permalink
Merge pull request #6 from steven004/fix/comment
Browse files Browse the repository at this point in the history
review of beneficiary change
  • Loading branch information
hunjixin authored Feb 10, 2022
2 parents e3e5da6 + 3445a56 commit 30529e3
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 33 deletions.
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

0 comments on commit 30529e3

Please sign in to comment.