This repository has been archived by the owner on Jun 6, 2023. It is now read-only.
/
market_balances.go
102 lines (80 loc) · 3.73 KB
/
market_balances.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package market
import (
addr "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/exitcode"
"golang.org/x/xerrors"
. "github.com/filecoin-project/specs-actors/actors/util"
)
// if the returned error is not nil, the Runtime will exit with the returned exit code.
// if the error is nil, we don't care about the exitcode.
func (m *marketStateMutation) lockClientAndProviderBalances(proposal *DealProposal) (error, exitcode.ExitCode) {
err, code := m.maybeLockBalance(proposal.Client, proposal.ClientBalanceRequirement())
if err != nil {
return xerrors.Errorf("failed to lock client funds: %w", err), code
}
err, code = m.maybeLockBalance(proposal.Provider, proposal.ProviderCollateral)
if err != nil {
return xerrors.Errorf("failed to lock provider funds: %w", err), code
}
m.totalClientLockedCollateral = big.Add(m.totalClientLockedCollateral, proposal.ClientCollateral)
m.totalClientStorageFee = big.Add(m.totalClientStorageFee, proposal.TotalStorageFee())
m.totalProviderLockedCollateral = big.Add(m.totalProviderLockedCollateral, proposal.ProviderCollateral)
return nil, exitcode.Ok
}
func (m *marketStateMutation) unlockBalance(addr addr.Address, amount abi.TokenAmount, lockReason BalanceLockingReason) error {
Assert(amount.GreaterThanEqual(big.Zero()))
err := m.lockedTable.MustSubtract(addr, amount)
if err != nil {
return xerrors.Errorf("subtracting from locked balance: %v", err)
}
switch lockReason {
case ClientCollateral:
m.totalClientLockedCollateral = big.Sub(m.totalClientLockedCollateral, amount)
case ClientStorageFee:
m.totalClientStorageFee = big.Sub(m.totalClientStorageFee, amount)
case ProviderCollateral:
m.totalProviderLockedCollateral = big.Sub(m.totalProviderLockedCollateral, amount)
}
return nil
}
// move funds from locked in client to available in provider
func (m *marketStateMutation) transferBalance(rt Runtime, fromAddr addr.Address, toAddr addr.Address, amount abi.TokenAmount) {
Assert(amount.GreaterThanEqual(big.Zero()))
if err := m.escrowTable.MustSubtract(fromAddr, amount); err != nil {
rt.Abortf(exitcode.ErrIllegalState, "subtract from escrow: %v", err)
}
if err := m.unlockBalance(fromAddr, amount, ClientStorageFee); err != nil {
rt.Abortf(exitcode.ErrIllegalState, "subtract from locked: %v", err)
}
if err := m.escrowTable.Add(toAddr, amount); err != nil {
rt.Abortf(exitcode.ErrIllegalState, "add to escrow: %v", err)
}
}
func (m *marketStateMutation) slashBalance(addr addr.Address, amount abi.TokenAmount, reason BalanceLockingReason) error {
Assert(amount.GreaterThanEqual(big.Zero()))
if err := m.escrowTable.MustSubtract(addr, amount); err != nil {
return xerrors.Errorf("subtract from escrow: %v", err)
}
return m.unlockBalance(addr, amount, reason)
}
func (m *marketStateMutation) maybeLockBalance(addr addr.Address, amount abi.TokenAmount) (error, exitcode.ExitCode) {
Assert(amount.GreaterThanEqual(big.Zero()))
prevLocked, err := m.lockedTable.Get(addr)
if err != nil {
return xerrors.Errorf("failed to get locked balance: %w", err), exitcode.ErrIllegalState
}
escrowBalance, err := m.escrowTable.Get(addr)
if err != nil {
return xerrors.Errorf("failed to get escrow balance: %w", err), exitcode.ErrIllegalState
}
if big.Add(prevLocked, amount).GreaterThan(escrowBalance) {
return xerrors.Errorf("not enough balance to lock for addr %s: escrow balance %s < locked %s + required %s", addr, escrowBalance, prevLocked, amount),
exitcode.ErrInsufficientFunds
}
if err := m.lockedTable.Add(addr, amount); err != nil {
return xerrors.Errorf("failed to add locked balance: %w", err), exitcode.ErrIllegalState
}
return nil, exitcode.Ok
}