Skip to content
This repository has been archived by the owner on Jun 6, 2023. It is now read-only.

Commit

Permalink
reuse balance table instances
Browse files Browse the repository at this point in the history
  • Loading branch information
whyrusleeping committed May 4, 2020
1 parent 4d7c678 commit b2ccac0
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 50 deletions.
25 changes: 23 additions & 2 deletions actors/builtin/market/market_actor.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,16 @@ func (a Actor) CronTick(rt Runtime, params *adt.EmptyValue) *adt.EmptyValue {
rt.Abortf(exitcode.ErrIllegalState, "get state state: %v", err)
}

et, err := adt.AsBalanceTable(adt.AsStore(rt), st.EscrowTable)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "loading escrow table: %s", err)
}

lt, err := adt.AsBalanceTable(adt.AsStore(rt), st.LockedTable)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "loading locked balance table: %s", err)
}

for i := st.LastCron; i <= rt.CurrEpoch(); i++ {
if err := dbe.ForEach(i, func(dealID abi.DealID) error {
state, found, err := states.Get(dealID)
Expand All @@ -446,7 +456,7 @@ func (a Actor) CronTick(rt Runtime, params *adt.EmptyValue) *adt.EmptyValue {
if state.SectorStartEpoch == epochUndefined {
// Not yet appeared in proven sector; check for timeout.
if rt.CurrEpoch() > deal.StartEpoch {
slashed := st.processDealInitTimedOut(rt, dealID, deal, state)
slashed := st.processDealInitTimedOut(rt, et, lt, dealID, deal, state)
if !slashed.IsZero() {
amountSlashed = big.Add(amountSlashed, slashed)
}
Expand All @@ -460,7 +470,7 @@ func (a Actor) CronTick(rt Runtime, params *adt.EmptyValue) *adt.EmptyValue {
rt.Abortf(exitcode.ErrIllegalState, "invalid deal state, unstarted, not timed out")
}

slashAmount, nextEpoch := st.updatePendingDealState(rt, state, deal, dealID, rt.CurrEpoch())
slashAmount, nextEpoch := st.updatePendingDealState(rt, state, deal, dealID, et, lt, rt.CurrEpoch())
if !slashAmount.IsZero() {
amountSlashed = big.Add(amountSlashed, slashAmount)
}
Expand Down Expand Up @@ -501,6 +511,17 @@ func (a Actor) CronTick(rt Runtime, params *adt.EmptyValue) *adt.EmptyValue {
rt.Abortf(exitcode.ErrIllegalState, "failed to get root of deals by epoch set: %s", err)
}

ltc, err := lt.Root()
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to flush locked table: %s", err)
}
etc, err := et.Root()
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to flush escrow table: %s", err)
}
st.LockedTable = ltc
st.EscrowTable = etc

st.DealOpsByEpoch = ndbec

return nil
Expand Down
76 changes: 28 additions & 48 deletions actors/builtin/market/market_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func ConstructState(emptyArrayCid, emptyMapCid, emptyMSetCid cid.Cid) *State {
// Deal state operations
////////////////////////////////////////////////////////////////////////////////

func (st *State) updatePendingDealState(rt Runtime, state *DealState, deal *DealProposal, dealID abi.DealID, epoch abi.ChainEpoch) (abi.TokenAmount, abi.ChainEpoch) {
func (st *State) updatePendingDealState(rt Runtime, state *DealState, deal *DealProposal, dealID abi.DealID, et, lt *adt.BalanceTable, epoch abi.ChainEpoch) (abi.TokenAmount, abi.ChainEpoch) {
amountSlashed := abi.NewTokenAmount(0)

everUpdated := state.LastUpdatedEpoch != epochUndefined
Expand Down Expand Up @@ -99,18 +99,20 @@ func (st *State) updatePendingDealState(rt Runtime, state *DealState, deal *Deal
// unlock client collateral and locked storage fee
clientCollateral := deal.ClientCollateral
paymentRemaining := dealGetPaymentRemaining(deal, state.SlashEpoch)
st.unlockBalance(rt, deal.Client, big.Add(clientCollateral, paymentRemaining))
st.unlockBalance(lt, deal.Client, big.Add(clientCollateral, paymentRemaining))

// slash provider collateral
amountSlashed = deal.ProviderCollateral
st.slashBalance(rt, deal.Provider, amountSlashed)
if err := st.slashBalance(et, lt, deal.Provider, amountSlashed); err != nil {
rt.Abortf(exitcode.ErrIllegalState, "slashing balance: %s", err)
}

st.deleteDeal(rt, dealID)
return amountSlashed, epochUndefined
}

if epoch >= deal.EndEpoch {
st.processDealExpired(rt, dealID)
st.processDealExpired(rt, deal, state, lt, dealID)
return amountSlashed, epochUndefined
}

Expand Down Expand Up @@ -165,31 +167,31 @@ func (st *State) deleteDeal(rt Runtime, dealID abi.DealID) {
// Deal start deadline elapsed without appearing in a proven sector.
// Delete deal, slash a portion of provider's collateral, and unlock remaining collaterals
// for both provider and client.
func (st *State) processDealInitTimedOut(rt Runtime, dealID abi.DealID, deal *DealProposal, state *DealState) abi.TokenAmount {
func (st *State) processDealInitTimedOut(rt Runtime, et, lt *adt.BalanceTable, dealID abi.DealID, deal *DealProposal, state *DealState) abi.TokenAmount {
Assert(state.SectorStartEpoch == epochUndefined)

st.unlockBalance(rt, deal.Client, deal.ClientBalanceRequirement())
st.unlockBalance(lt, deal.Client, deal.ClientBalanceRequirement())

amountSlashed := collateralPenaltyForDealActivationMissed(deal.ProviderCollateral)
amountRemaining := big.Sub(deal.ProviderBalanceRequirement(), amountSlashed)

st.slashBalance(rt, deal.Provider, amountSlashed)
st.unlockBalance(rt, deal.Provider, amountRemaining)
if err := st.slashBalance(et, lt, deal.Provider, amountSlashed); err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to slash balance: %s", err)
}

st.unlockBalance(lt, deal.Provider, amountRemaining)

st.deleteDeal(rt, dealID)
return amountSlashed
}

// Normal expiration. Delete deal and unlock collaterals for both miner and client.
func (st *State) processDealExpired(rt Runtime, dealID abi.DealID) {
deal := st.mustGetDeal(rt, dealID)
state := st.mustGetDealState(rt, dealID)

func (st *State) processDealExpired(rt Runtime, deal *DealProposal, state *DealState, lt *adt.BalanceTable, dealID abi.DealID) {
Assert(state.SectorStartEpoch != epochUndefined)

// Note: payment has already been completed at this point (_rtProcessDealPaymentEpochsElapsed)
st.unlockBalance(rt, deal.Provider, deal.ProviderCollateral)
st.unlockBalance(rt, deal.Client, deal.ClientCollateral)
st.unlockBalance(lt, deal.Provider, deal.ProviderCollateral)
st.unlockBalance(lt, deal.Client, deal.ClientCollateral)

st.deleteDeal(rt, dealID)
}
Expand Down Expand Up @@ -286,16 +288,14 @@ func (st *State) maybeLockBalance(rt Runtime, addr addr.Address, amount abi.Toke
}

// TODO: all these balance table mutations need to happen at the top level and be batched (no flushing after each!)
func (st *State) unlockBalance(rt Runtime, addr addr.Address, amount abi.TokenAmount) {
func (st *State) unlockBalance(lt *adt.BalanceTable, addr addr.Address, amount abi.TokenAmount) error {
Assert(amount.GreaterThanEqual(big.Zero()))

st.MutateBalanceTable(adt.AsStore(rt), &st.LockedTable, func(lt *adt.BalanceTable) error {
err := lt.MustSubtract(addr, amount)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "subtracting from locked balance: %v", err)
}
return nil
})
err := lt.MustSubtract(addr, amount)
if err != nil {
return xerrors.Errorf("subtracting from locked balance: %v", err)
}
return nil
}

// move funds from locked in client to available in provider
Expand Down Expand Up @@ -336,38 +336,18 @@ func (st *State) transferBalance(rt Runtime, fromAddr addr.Address, toAddr addr.
st.EscrowTable = etc
}

func (st *State) slashBalance(rt Runtime, addr addr.Address, amount abi.TokenAmount) {
func (st *State) slashBalance(et, lt *adt.BalanceTable, addr addr.Address, amount abi.TokenAmount) error {
Assert(amount.GreaterThanEqual(big.Zero()))

et, err := adt.AsBalanceTable(adt.AsStore(rt), st.EscrowTable)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "loading escrow table: %s", err)
}
lt, err := adt.AsBalanceTable(adt.AsStore(rt), st.LockedTable)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "loading locked balance table: %s", err)
if err := et.MustSubtract(addr, amount); err != nil {
return xerrors.Errorf("subtract from escrow: %v", err)
}

err = et.MustSubtract(addr, amount)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "subtract from escrow: %v", err)
}
err = lt.MustSubtract(addr, amount)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "subtract from locked: %v", err)
if err := lt.MustSubtract(addr, amount); err != nil {
return xerrors.Errorf("subtract from locked: %v", err)
}

ltc, err := lt.Root()
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to flush locked table: %s", err)
}
etc, err := et.Root()
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to flush escrow table: %s", err)
}

st.LockedTable = ltc
st.EscrowTable = etc
return nil
}

////////////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit b2ccac0

Please sign in to comment.