Paych improvements; Retrieval payments
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
package full
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -26,18 +26,20 @@ import (
|
||||
"github.com/filecoin-project/go-lotus/chain/deals"
|
||||
"github.com/filecoin-project/go-lotus/chain/store"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
"github.com/filecoin-project/go-lotus/node/impl/full"
|
||||
"github.com/filecoin-project/go-lotus/node/impl/paych"
|
||||
"github.com/filecoin-project/go-lotus/node/modules/dtypes"
|
||||
"github.com/filecoin-project/go-lotus/retrieval"
|
||||
"github.com/filecoin-project/go-lotus/retrieval/discovery"
|
||||
)
|
||||
|
||||
type ClientAPI struct {
|
||||
type API struct {
|
||||
fx.In
|
||||
|
||||
ChainAPI
|
||||
StateAPI
|
||||
WalletAPI
|
||||
PaychAPI
|
||||
full.ChainAPI
|
||||
full.StateAPI
|
||||
full.WalletAPI
|
||||
paych.PaychAPI
|
||||
|
||||
DealClient *deals.Client
|
||||
RetDiscovery discovery.PeerResolver
|
||||
@@ -49,7 +51,7 @@ type ClientAPI struct {
|
||||
Filestore dtypes.ClientFilestore `optional:"true"`
|
||||
}
|
||||
|
||||
func (a *ClientAPI) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error) {
|
||||
func (a *API) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error) {
|
||||
// TODO: make this a param
|
||||
self, err := a.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
@@ -118,7 +120,7 @@ func (a *ClientAPI) ClientStartDeal(ctx context.Context, data cid.Cid, miner add
|
||||
return &c, err
|
||||
}
|
||||
|
||||
func (a *ClientAPI) ClientListDeals(ctx context.Context) ([]api.DealInfo, error) {
|
||||
func (a *API) ClientListDeals(ctx context.Context) ([]api.DealInfo, error) {
|
||||
deals, err := a.DealClient.List()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -143,7 +145,7 @@ func (a *ClientAPI) ClientListDeals(ctx context.Context) ([]api.DealInfo, error)
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (a *ClientAPI) ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) {
|
||||
func (a *API) ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) {
|
||||
// TODO: check if we have the ENTIRE dag
|
||||
|
||||
offExch := merkledag.NewDAGService(blockservice.New(a.Blockstore, offline.Exchange(a.Blockstore)))
|
||||
@@ -157,7 +159,7 @@ func (a *ClientAPI) ClientHasLocal(ctx context.Context, root cid.Cid) (bool, err
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (a *ClientAPI) ClientFindData(ctx context.Context, root cid.Cid) ([]api.QueryOffer, error) {
|
||||
func (a *API) ClientFindData(ctx context.Context, root cid.Cid) ([]api.QueryOffer, error) {
|
||||
peers, err := a.RetDiscovery.GetPeers(root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -171,7 +173,7 @@ func (a *ClientAPI) ClientFindData(ctx context.Context, root cid.Cid) ([]api.Que
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (a *ClientAPI) ClientImport(ctx context.Context, path string) (cid.Cid, error) {
|
||||
func (a *API) ClientImport(ctx context.Context, path string) (cid.Cid, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
@@ -208,7 +210,7 @@ func (a *ClientAPI) ClientImport(ctx context.Context, path string) (cid.Cid, err
|
||||
return nd.Cid(), bufferedDS.Commit()
|
||||
}
|
||||
|
||||
func (a *ClientAPI) ClientListImports(ctx context.Context) ([]api.Import, error) {
|
||||
func (a *API) ClientListImports(ctx context.Context) ([]api.Import, error) {
|
||||
if a.Filestore == nil {
|
||||
return nil, errors.New("listing imports is not supported with in-memory dag yet")
|
||||
}
|
||||
@@ -237,13 +239,13 @@ func (a *ClientAPI) ClientListImports(ctx context.Context) ([]api.Import, error)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *ClientAPI) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, path string) error {
|
||||
func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, path string) error {
|
||||
outFile, err := os.OpenFile(path, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = a.Retrieval.RetrieveUnixfs(ctx, order.Root, order.Size, order.MinerPeerID, order.Miner, outFile)
|
||||
err = a.Retrieval.RetrieveUnixfs(ctx, order.Root, order.Size, order.Total, order.MinerPeerID, order.Client, order.Miner, outFile)
|
||||
if err != nil {
|
||||
_ = outFile.Close()
|
||||
return err
|
||||
+4
-4
@@ -3,10 +3,6 @@ package impl
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/api"
|
||||
"github.com/filecoin-project/go-lotus/build"
|
||||
"github.com/filecoin-project/go-lotus/node/modules/dtypes"
|
||||
|
||||
"github.com/gbrlsnchs/jwt/v3"
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
@@ -14,6 +10,10 @@ import (
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/api"
|
||||
"github.com/filecoin-project/go-lotus/build"
|
||||
"github.com/filecoin-project/go-lotus/node/modules/dtypes"
|
||||
)
|
||||
|
||||
type CommonAPI struct {
|
||||
|
||||
+6
-3
@@ -2,12 +2,15 @@ package impl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/filecoin-project/go-lotus/node/impl/client"
|
||||
"github.com/filecoin-project/go-lotus/node/impl/paych"
|
||||
|
||||
logging "github.com/ipfs/go-log"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/api"
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/miner"
|
||||
"github.com/filecoin-project/go-lotus/node/impl/full"
|
||||
logging "github.com/ipfs/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("node")
|
||||
@@ -15,9 +18,9 @@ var log = logging.Logger("node")
|
||||
type FullNodeAPI struct {
|
||||
CommonAPI
|
||||
full.ChainAPI
|
||||
full.ClientAPI
|
||||
client.API
|
||||
full.MpoolAPI
|
||||
full.PaychAPI
|
||||
paych.PaychAPI
|
||||
full.StateAPI
|
||||
full.WalletAPI
|
||||
|
||||
|
||||
@@ -1,151 +1,60 @@
|
||||
package full
|
||||
package paych
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/api"
|
||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
full "github.com/filecoin-project/go-lotus/node/impl/full"
|
||||
"github.com/filecoin-project/go-lotus/paych"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type PaychAPI struct {
|
||||
fx.In
|
||||
|
||||
MpoolAPI
|
||||
WalletAPI
|
||||
ChainAPI
|
||||
full.MpoolAPI
|
||||
full.WalletAPI
|
||||
full.ChainAPI
|
||||
|
||||
PaychMgr *paych.Manager
|
||||
}
|
||||
|
||||
func (a *PaychAPI) PaychCreate(ctx context.Context, from, to address.Address, amt types.BigInt) (*api.ChannelInfo, error) {
|
||||
params, aerr := actors.SerializeParams(&actors.PCAConstructorParams{To: to})
|
||||
if aerr != nil {
|
||||
return nil, aerr
|
||||
}
|
||||
|
||||
nonce, err := a.MpoolGetNonce(ctx, from)
|
||||
func (a *PaychAPI) PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*api.ChannelInfo, error) {
|
||||
ch, mcid, err := a.PaychMgr.GetPaych(ctx, from, to, ensureFunds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
enc, err := actors.SerializeParams(&actors.ExecParams{
|
||||
Params: params,
|
||||
Code: actors.PaymentChannelActorCodeCid,
|
||||
})
|
||||
|
||||
msg := &types.Message{
|
||||
To: actors.InitActorAddress,
|
||||
From: from,
|
||||
Value: amt,
|
||||
Nonce: nonce,
|
||||
Method: actors.IAMethods.Exec,
|
||||
Params: enc,
|
||||
GasLimit: types.NewInt(1000000),
|
||||
GasPrice: types.NewInt(0),
|
||||
}
|
||||
|
||||
smsg, err := a.WalletSignMessage(ctx, from, msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := a.MpoolPush(ctx, smsg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mcid := smsg.Cid()
|
||||
mwait, err := a.ChainWaitMsg(ctx, mcid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if mwait.Receipt.ExitCode != 0 {
|
||||
return nil, fmt.Errorf("payment channel creation failed (exit code %d)", mwait.Receipt.ExitCode)
|
||||
}
|
||||
|
||||
paychaddr, err := address.NewFromBytes(mwait.Receipt.Return)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := a.PaychMgr.TrackOutboundChannel(ctx, paychaddr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &api.ChannelInfo{
|
||||
Channel: paychaddr,
|
||||
Channel: ch,
|
||||
ChannelMessage: mcid,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *PaychAPI) PaychAllocateLane(ctx context.Context, ch address.Address) (uint64, error) {
|
||||
return a.PaychMgr.AllocateLane(ch)
|
||||
}
|
||||
|
||||
func (a *PaychAPI) PaychNewPayment(ctx context.Context, from, to address.Address, amount types.BigInt, extra *types.ModVerifyParams, tl uint64, minClose uint64) (*api.PaymentInfo, error) {
|
||||
ch, err := a.PaychMgr.OutboundChanTo(from, to)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var chMsg *cid.Cid
|
||||
if ch == address.Undef {
|
||||
// don't have matching channel, open new
|
||||
|
||||
// TODO: this should be more atomic
|
||||
chInfo, err := a.PaychCreate(ctx, from, to, amount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ch = chInfo.Channel
|
||||
chMsg = &chInfo.ChannelMessage
|
||||
} else {
|
||||
// already have chanel to the destination, add funds, and open a new lane
|
||||
// TODO: track free funds in channel
|
||||
|
||||
nonce, err := a.MpoolGetNonce(ctx, from)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msg := &types.Message{
|
||||
To: ch,
|
||||
From: from,
|
||||
Value: amount,
|
||||
Nonce: nonce,
|
||||
Method: 0,
|
||||
GasLimit: types.NewInt(1000000),
|
||||
GasPrice: types.NewInt(0),
|
||||
}
|
||||
|
||||
smsg, err := a.WalletSignMessage(ctx, from, msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := a.MpoolPush(ctx, smsg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mwait, err := a.ChainWaitMsg(ctx, smsg.Cid())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if mwait.Receipt.ExitCode != 0 {
|
||||
return nil, fmt.Errorf("voucher channel creation failed: adding funds (exit code %d)", mwait.Receipt.ExitCode)
|
||||
}
|
||||
}
|
||||
|
||||
lane, err := a.PaychMgr.AllocateLane(ch)
|
||||
// TODO: Fix free fund tracking in PaychGet, pass amount
|
||||
ch, err := a.PaychGet(ctx, from, to, types.NewInt(0))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sv, err := a.paychVoucherCreate(ctx, ch, types.SignedVoucher{
|
||||
lane, err := a.PaychMgr.AllocateLane(ch.Channel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sv, err := a.paychVoucherCreate(ctx, ch.Channel, types.SignedVoucher{
|
||||
Amount: amount,
|
||||
Lane: lane,
|
||||
|
||||
@@ -158,8 +67,8 @@ func (a *PaychAPI) PaychNewPayment(ctx context.Context, from, to address.Address
|
||||
}
|
||||
|
||||
return &api.PaymentInfo{
|
||||
Channel: ch,
|
||||
ChannelMessage: chMsg,
|
||||
Channel: ch.Channel,
|
||||
ChannelMessage: &ch.ChannelMessage,
|
||||
Voucher: sv,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user