lotus/markets/retrievaladapter/client.go

108 lines
4.1 KiB
Go
Raw Normal View History

package retrievaladapter
import (
"context"
2020-09-01 14:33:44 +00:00
"golang.org/x/xerrors"
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
"github.com/filecoin-project/go-fil-markets/shared"
2020-09-07 03:49:10 +00:00
"github.com/filecoin-project/go-state-types/abi"
"github.com/ipfs/go-cid"
2020-08-05 22:35:59 +00:00
"github.com/multiformats/go-multiaddr"
2020-08-05 22:35:59 +00:00
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/impl/full"
payapi "github.com/filecoin-project/lotus/node/impl/paych"
"github.com/filecoin-project/lotus/paychmgr"
)
type retrievalClientNode struct {
2020-08-05 22:35:59 +00:00
chainAPI full.ChainAPI
pmgr *paychmgr.Manager
2020-08-05 22:35:59 +00:00
payAPI payapi.PaychAPI
stateAPI full.StateAPI
}
// NewRetrievalClientNode returns a new node adapter for a retrieval client that talks to the
// Lotus Node
2020-08-05 22:35:59 +00:00
func NewRetrievalClientNode(pmgr *paychmgr.Manager, payAPI payapi.PaychAPI, chainAPI full.ChainAPI, stateAPI full.StateAPI) retrievalmarket.RetrievalClientNode {
return &retrievalClientNode{pmgr: pmgr, payAPI: payAPI, chainAPI: chainAPI, stateAPI: stateAPI}
}
// GetOrCreatePaymentChannel sets up a new payment channel if one does not exist
// between a client and a miner and ensures the client has the given amount of
// funds available in the channel.
func (rcn *retrievalClientNode) GetOrCreatePaymentChannel(ctx context.Context, clientAddress address.Address, minerAddress address.Address, clientFundsAvailable abi.TokenAmount, tok shared.TipSetToken) (address.Address, cid.Cid, error) {
// TODO: respect the provided TipSetToken (a serialized TipSetKey) when
// querying the chain
return rcn.pmgr.GetPaych(ctx, clientAddress, minerAddress, clientFundsAvailable)
}
// Allocate late creates a lane within a payment channel so that calls to
// CreatePaymentVoucher will automatically make vouchers only for the difference
// in total
2020-02-21 17:26:44 +00:00
func (rcn *retrievalClientNode) AllocateLane(paymentChannel address.Address) (uint64, error) {
return rcn.pmgr.AllocateLane(paymentChannel)
}
// CreatePaymentVoucher creates a new payment voucher in the given lane for a
// given payment channel so that all the payment vouchers in the lane add up
// to the given amount (so the payment voucher will be for the difference)
func (rcn *retrievalClientNode) CreatePaymentVoucher(ctx context.Context, paymentChannel address.Address, amount abi.TokenAmount, lane uint64, tok shared.TipSetToken) (*paych.SignedVoucher, error) {
// TODO: respect the provided TipSetToken (a serialized TipSetKey) when
// querying the chain
2020-08-05 22:35:59 +00:00
voucher, err := rcn.payAPI.PaychVoucherCreate(ctx, paymentChannel, amount, lane)
if err != nil {
return nil, err
}
2020-09-01 14:33:44 +00:00
if voucher.Voucher == nil {
return nil, xerrors.Errorf("Could not create voucher - shortfall: %d", voucher.Shortfall)
}
return voucher.Voucher, nil
}
func (rcn *retrievalClientNode) GetChainHead(ctx context.Context) (shared.TipSetToken, abi.ChainEpoch, error) {
2020-08-05 22:35:59 +00:00
head, err := rcn.chainAPI.ChainHead(ctx)
if err != nil {
return nil, 0, err
}
return head.Key().Bytes(), head.Height(), nil
}
// WaitForPaymentChannelAddFunds waits messageCID to appear on chain. If it doesn't appear within
// defaultMsgWaitTimeout it returns error
func (rcn *retrievalClientNode) WaitForPaymentChannelAddFunds(messageCID cid.Cid) error {
_, err := rcn.payAPI.PaychMgr.GetPaychWaitReady(context.TODO(), messageCID)
return err
}
func (rcn *retrievalClientNode) WaitForPaymentChannelCreation(messageCID cid.Cid) (address.Address, error) {
return rcn.payAPI.PaychMgr.GetPaychWaitReady(context.TODO(), messageCID)
}
2020-08-05 22:35:59 +00:00
func (rcn *retrievalClientNode) GetKnownAddresses(ctx context.Context, p retrievalmarket.RetrievalPeer, encodedTs shared.TipSetToken) ([]multiaddr.Multiaddr, error) {
tsk, err := types.TipSetKeyFromBytes(encodedTs)
if err != nil {
return nil, err
}
mi, err := rcn.stateAPI.StateMinerInfo(ctx, p.Address, tsk)
if err != nil {
return nil, err
}
multiaddrs := make([]multiaddr.Multiaddr, 0, len(mi.Multiaddrs))
for _, a := range mi.Multiaddrs {
maddr, err := multiaddr.NewMultiaddrBytes(a)
if err != nil {
return nil, err
}
multiaddrs = append(multiaddrs, maddr)
}
return multiaddrs, nil
}