2019-11-08 17:15:38 +00:00
|
|
|
package market
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2020-07-30 00:27:22 +00:00
|
|
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
2019-11-08 17:15:38 +00:00
|
|
|
"sync"
|
|
|
|
|
2020-02-13 03:50:37 +00:00
|
|
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
2020-05-05 01:31:56 +00:00
|
|
|
"github.com/ipfs/go-cid"
|
2020-02-28 18:01:43 +00:00
|
|
|
logging "github.com/ipfs/go-log"
|
2019-11-08 17:15:38 +00:00
|
|
|
|
2019-12-19 20:13:17 +00:00
|
|
|
"github.com/filecoin-project/go-address"
|
2019-11-08 17:15:38 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/actors"
|
|
|
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
|
|
"github.com/filecoin-project/lotus/node/impl/full"
|
|
|
|
)
|
|
|
|
|
2020-02-28 18:01:43 +00:00
|
|
|
var log = logging.Logger("market_adapter")
|
|
|
|
|
2019-11-08 17:15:38 +00:00
|
|
|
type FundMgr struct {
|
|
|
|
sm *stmgr.StateManager
|
|
|
|
mpool full.MpoolAPI
|
|
|
|
|
|
|
|
lk sync.Mutex
|
|
|
|
available map[address.Address]types.BigInt
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewFundMgr(sm *stmgr.StateManager, mpool full.MpoolAPI) *FundMgr {
|
|
|
|
return &FundMgr{
|
|
|
|
sm: sm,
|
|
|
|
mpool: mpool,
|
|
|
|
|
|
|
|
available: map[address.Address]types.BigInt{},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-05 01:31:56 +00:00
|
|
|
func (fm *FundMgr) EnsureAvailable(ctx context.Context, addr, wallet address.Address, amt types.BigInt) (cid.Cid, error) {
|
2019-11-08 17:15:38 +00:00
|
|
|
fm.lk.Lock()
|
|
|
|
avail, ok := fm.available[addr]
|
|
|
|
if !ok {
|
|
|
|
bal, err := fm.sm.MarketBalance(ctx, addr, nil)
|
|
|
|
if err != nil {
|
|
|
|
fm.lk.Unlock()
|
2020-05-05 01:31:56 +00:00
|
|
|
return cid.Undef, err
|
2019-11-08 17:15:38 +00:00
|
|
|
}
|
|
|
|
|
2020-02-08 02:18:32 +00:00
|
|
|
avail = types.BigSub(bal.Escrow, bal.Locked)
|
2019-11-08 17:15:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
toAdd := types.NewInt(0)
|
|
|
|
avail = types.BigSub(avail, amt)
|
|
|
|
if avail.LessThan(types.NewInt(0)) {
|
|
|
|
// TODO: some rules around adding more to avoid doing stuff on-chain
|
|
|
|
// all the time
|
2020-07-30 00:27:22 +00:00
|
|
|
toAdd = avail.Neg()
|
2019-11-08 17:15:38 +00:00
|
|
|
avail = types.NewInt(0)
|
|
|
|
}
|
|
|
|
fm.available[addr] = avail
|
2019-11-08 20:11:56 +00:00
|
|
|
|
2019-11-08 17:15:38 +00:00
|
|
|
fm.lk.Unlock()
|
|
|
|
|
2020-07-30 00:27:22 +00:00
|
|
|
if toAdd.LessThanEqual(big.Zero()) {
|
|
|
|
return cid.Undef, nil
|
|
|
|
} else {
|
|
|
|
var err error
|
|
|
|
params, err := actors.SerializeParams(&addr)
|
|
|
|
if err != nil {
|
|
|
|
return cid.Undef, err
|
|
|
|
}
|
2020-02-13 03:50:37 +00:00
|
|
|
|
2020-07-30 00:27:22 +00:00
|
|
|
smsg, err := fm.mpool.MpoolPushMessage(ctx, &types.Message{
|
|
|
|
To: builtin.StorageMarketActorAddr,
|
|
|
|
From: wallet,
|
|
|
|
Value: toAdd,
|
|
|
|
Method: builtin.MethodsMarket.AddBalance,
|
|
|
|
Params: params,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return cid.Undef, err
|
|
|
|
}
|
2019-11-08 17:15:38 +00:00
|
|
|
|
2020-07-30 00:27:22 +00:00
|
|
|
return smsg.Cid(), nil
|
|
|
|
}
|
2019-11-08 17:15:38 +00:00
|
|
|
}
|