Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: paychmgr: Support paych funding (a.k.a. fast paid retrieval) #7883

Merged
merged 30 commits into from Mar 2, 2022
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8e46b9e
paych: API to pre-fund channels
magik6k Jan 4, 2022
9715113
paych: Test pre-funding
magik6k Jan 4, 2022
2e76375
Fix paych itests
magik6k Jan 4, 2022
7a938b2
paych: Output FIL in cli
magik6k Jan 4, 2022
8f6f21c
paych: Print available amounts in paych status
magik6k Jan 4, 2022
ff8b95d
paych: Reserve flag for add-funds cli
magik6k Jan 4, 2022
1f2621b
Make retrieval work with reused channels
magik6k Jan 4, 2022
eab8fec
gen stuff
magik6k Jan 4, 2022
533349c
paych: Fix cli tests
magik6k Jan 5, 2022
b0e7bc1
paych: Cleanup available fund logic
magik6k Jan 5, 2022
5b585c0
paych: reset fundsReqQueue correctly
magik6k Jan 5, 2022
8b19b84
paych: option to force off-chain get
magik6k Jan 6, 2022
4235a97
retrieval: OffChainRetrieval config
magik6k Jan 6, 2022
8f9e730
paych: Better off-chain errors
magik6k Jan 6, 2022
550e274
paych: Don't return settling/collected chennals from OutboundActiveBy…
magik6k Jan 6, 2022
10af768
Merge commit 'origin/release/v1.15.0~2' into feat/paych-avail-reuse
magik6k Feb 14, 2022
f61eb23
api: separate method for paych funding
magik6k Feb 14, 2022
df5bd14
paychmgr: Review comments
magik6k Feb 14, 2022
36a1934
paychmgr: Fix tests after api changes
magik6k Feb 14, 2022
f9485eb
Update paychmgr/store.go
magik6k Feb 14, 2022
da5ae1e
paychmgr: erlier checks in completeAmount
magik6k Feb 14, 2022
deb9882
Merge branch 'feat/paych-avail-reuse' of github.com:filecoin-project/…
magik6k Feb 14, 2022
60b9acc
gen
magik6k Feb 14, 2022
e1a3605
feat(markets): update markets to simplify client adapter
hannahhoward Feb 16, 2022
cdca1a4
Merge pull request #8102 from filecoin-project/feat/paych-avail-reuse…
magik6k Feb 16, 2022
681b907
Merge remote-tracking branch 'origin/master' into feat/paych-avail-reuse
magik6k Feb 16, 2022
e961766
fix lotus-soup build
magik6k Feb 16, 2022
3849995
paychmgr: AvailableAmt -> NonReservedAmt
magik6k Feb 16, 2022
a0cb609
Merge remote-tracking branch 'origin/master' into feat/paych-avail-reuse
magik6k Feb 22, 2022
e9a6f5f
Merge remote-tracking branch 'origin/master' into feat/paych-avail-reuse
magik6k Mar 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 18 additions & 1 deletion api/api_full.go
Expand Up @@ -689,7 +689,15 @@ type FullNode interface {
// MethodGroup: Paych
// The Paych methods are for interacting with and managing payment channels

PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt) (*ChannelInfo, error) //perm:sign
// PaychGet gets or creates a payment channel between address pair
magik6k marked this conversation as resolved.
Show resolved Hide resolved
// - If opts.Reserve is false, the specified amount will be added to the channel through on-chain send for future use
// - If opts.Reserve is true, the specified amount will be reserved for use. If there aren't enough non-reserved funds
// available, funds will be added through an on-chain message.
// - When opts.OffChain is true, this call will not cause any messages to be sent to the chain (no automatic
// channel creation/funds adding). If the operation can't be performed without sending a message an error will be
// returned. Note that even when this option is specified, this call can be blocked by previous operations on the
// channel waiting for on-chain operations.
PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt, opts PaychGetOpts) (*ChannelInfo, error) //perm:sign
PaychGetWaitReady(context.Context, cid.Cid) (address.Address, error) //perm:sign
PaychAvailableFunds(ctx context.Context, ch address.Address) (*ChannelAvailableFunds, error) //perm:sign
PaychAvailableFundsByFromTo(ctx context.Context, from, to address.Address) (*ChannelAvailableFunds, error) //perm:sign
Expand Down Expand Up @@ -828,6 +836,11 @@ const (
PCHOutbound
)

type PaychGetOpts struct {
Reserve bool
OffChain bool
}

type PaychStatus struct {
ControlAddr address.Address
Direction PCHDir
Expand All @@ -850,6 +863,10 @@ type ChannelAvailableFunds struct {
ConfirmedAmt types.BigInt
// PendingAmt is the amount of funds that are pending confirmation on-chain
PendingAmt types.BigInt
// AvailableAmt is part of ConfirmedAmt that is available for use (pre-allocated)
AvailableAmt types.BigInt
magik6k marked this conversation as resolved.
Show resolved Hide resolved
// PendingAvailableAmt is the amount of available funds that are pending confirmation on-chain
magik6k marked this conversation as resolved.
Show resolved Hide resolved
PendingAvailableAmt types.BigInt
// PendingWaitSentinel can be used with PaychGetWaitReady to wait for
// confirmation of pending funds
PendingWaitSentinel *cid.Cid
Expand Down
8 changes: 4 additions & 4 deletions api/mocks/mock_full.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions api/proxy_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions api/v0api/v1_wrapper.go
Expand Up @@ -337,4 +337,11 @@ func (w *WrapperV1Full) clientRetrieve(ctx context.Context, order RetrievalOrder
finish(w.ClientExport(ctx, eref, *ref))
}

func (w *WrapperV1Full) PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt) (*api.ChannelInfo, error) {
return w.FullNode.PaychGet(ctx, from, to, amt, api.PaychGetOpts{
Reserve: true, // v0 always reserves
OffChain: false,
})
}

var _ FullNode = &WrapperV1Full{}
Binary file modified build/openrpc/full.json.gz
Binary file not shown.
30 changes: 19 additions & 11 deletions cli/paych.go
Expand Up @@ -8,7 +8,7 @@ import (
"sort"
"strings"

"github.com/filecoin-project/lotus/api"
lapi "github.com/filecoin-project/lotus/api"

"github.com/filecoin-project/lotus/paychmgr"

Expand Down Expand Up @@ -39,12 +39,15 @@ var paychAddFundsCmd = &cli.Command{
Usage: "Add funds to the payment channel between fromAddress and toAddress. Creates the payment channel if it doesn't already exist.",
ArgsUsage: "[fromAddress toAddress amount]",
Flags: []cli.Flag{

&cli.BoolFlag{
Name: "restart-retrievals",
Usage: "restart stalled retrieval deals on this payment channel",
Value: true,
},
&cli.BoolFlag{
Name: "reserve",
Usage: "mark funds as reserved",
},
},
Action: func(cctx *cli.Context) error {
if cctx.Args().Len() != 3 {
Expand All @@ -66,7 +69,7 @@ var paychAddFundsCmd = &cli.Command{
return ShowHelp(cctx, fmt.Errorf("parsing amount failed: %s", err))
}

api, closer, err := GetFullNodeAPI(cctx)
api, closer, err := GetFullNodeAPIV1(cctx)
if err != nil {
return err
}
Expand All @@ -76,7 +79,10 @@ var paychAddFundsCmd = &cli.Command{

// Send a message to chain to create channel / add funds to existing
// channel
info, err := api.PaychGet(ctx, from, to, types.BigInt(amt))
info, err := api.PaychGet(ctx, from, to, types.BigInt(amt), lapi.PaychGetOpts{
Reserve: cctx.Bool("reserve"),
OffChain: false,
})
if err != nil {
return err
}
Expand Down Expand Up @@ -163,13 +169,13 @@ var paychStatusCmd = &cli.Command{
},
}

func paychStatus(writer io.Writer, avail *api.ChannelAvailableFunds) {
func paychStatus(writer io.Writer, avail *lapi.ChannelAvailableFunds) {
if avail.Channel == nil {
if avail.PendingWaitSentinel != nil {
fmt.Fprint(writer, "Creating channel\n")
fmt.Fprintf(writer, " From: %s\n", avail.From)
fmt.Fprintf(writer, " To: %s\n", avail.To)
fmt.Fprintf(writer, " Pending Amt: %d\n", avail.PendingAmt)
fmt.Fprintf(writer, " Pending Amt: %s\n", types.FIL(avail.PendingAmt))
fmt.Fprintf(writer, " Wait Sentinel: %s\n", avail.PendingWaitSentinel)
return
}
Expand All @@ -189,10 +195,12 @@ func paychStatus(writer io.Writer, avail *api.ChannelAvailableFunds) {
{"Channel", avail.Channel.String()},
{"From", avail.From.String()},
{"To", avail.To.String()},
{"Confirmed Amt", fmt.Sprintf("%d", avail.ConfirmedAmt)},
{"Pending Amt", fmt.Sprintf("%d", avail.PendingAmt)},
{"Queued Amt", fmt.Sprintf("%d", avail.QueuedAmt)},
{"Voucher Redeemed Amt", fmt.Sprintf("%d", avail.VoucherReedeemedAmt)},
{"Confirmed Amt", fmt.Sprintf("%s", types.FIL(avail.ConfirmedAmt))},
{"Available Amt", fmt.Sprintf("%s", types.FIL(avail.AvailableAmt))},
{"Voucher Redeemed Amt", fmt.Sprintf("%s", types.FIL(avail.VoucherReedeemedAmt))},
{"Pending Amt", fmt.Sprintf("%s", types.FIL(avail.PendingAmt))},
{"Pending Available Amt", fmt.Sprintf("%s", types.FIL(avail.PendingAvailableAmt))},
{"Queued Amt", fmt.Sprintf("%s", types.FIL(avail.QueuedAmt))},
}
if avail.PendingWaitSentinel != nil {
nameValues = append(nameValues, []string{
Expand Down Expand Up @@ -576,7 +584,7 @@ func outputVoucher(w io.Writer, v *paych.SignedVoucher, export bool) error {
}
}

fmt.Fprintf(w, "Lane %d, Nonce %d: %s", v.Lane, v.Nonce, v.Amount.String())
fmt.Fprintf(w, "Lane %d, Nonce %d: %s", v.Lane, v.Nonce, types.FIL(v.Amount))
if export {
fmt.Fprintf(w, "; %s", enc)
}
Expand Down
4 changes: 4 additions & 0 deletions documentation/en/api-v0-methods.md
Expand Up @@ -4061,6 +4061,8 @@ Response:
"To": "f01234",
"ConfirmedAmt": "0",
"PendingAmt": "0",
"AvailableAmt": "0",
"PendingAvailableAmt": "0",
"PendingWaitSentinel": null,
"QueuedAmt": "0",
"VoucherReedeemedAmt": "0"
Expand Down Expand Up @@ -4088,6 +4090,8 @@ Response:
"To": "f01234",
"ConfirmedAmt": "0",
"PendingAmt": "0",
"AvailableAmt": "0",
"PendingAvailableAmt": "0",
"PendingWaitSentinel": null,
"QueuedAmt": "0",
"VoucherReedeemedAmt": "0"
Expand Down
20 changes: 18 additions & 2 deletions documentation/en/api-v1-unstable-methods.md
Expand Up @@ -4456,6 +4456,8 @@ Response:
"To": "f01234",
"ConfirmedAmt": "0",
"PendingAmt": "0",
"AvailableAmt": "0",
"PendingAvailableAmt": "0",
"PendingWaitSentinel": null,
"QueuedAmt": "0",
"VoucherReedeemedAmt": "0"
Expand Down Expand Up @@ -4483,6 +4485,8 @@ Response:
"To": "f01234",
"ConfirmedAmt": "0",
"PendingAmt": "0",
"AvailableAmt": "0",
"PendingAvailableAmt": "0",
"PendingWaitSentinel": null,
"QueuedAmt": "0",
"VoucherReedeemedAmt": "0"
Expand All @@ -4509,7 +4513,15 @@ Response:
```

### PaychGet
There are not yet any comments for this method.
PaychGet gets or creates a payment channel between address pair
- If opts.Reserve is false, the specified amount will be added to the channel through on-chain send for future use
- If opts.Reserve is true, the specified amount will be reserved for use. If there aren't enough non-reserved funds
available, funds will be added through an on-chain message.
- When opts.OffChain is true, this call will not cause any messages to be sent to the chain (no automatic
channel creation/funds adding). If the operation can't be performed without sending a message an error will be
returned. Note that even when this option is specified, this call can be blocked by previous operations on the
channel waiting for on-chain operations.


Perms: sign

Expand All @@ -4518,7 +4530,11 @@ Inputs:
[
"f01234",
"f01234",
"0"
"0",
{
"Reserve": true,
"OffChain": true
}
]
```

Expand Down
1 change: 1 addition & 0 deletions documentation/en/cli-lotus.md
Expand Up @@ -1347,6 +1347,7 @@ USAGE:

OPTIONS:
--restart-retrievals restart stalled retrieval deals on this payment channel (default: true)
--reserve mark funds as reserved (default: false)
--help, -h show help (default: false)

```
Expand Down
8 changes: 8 additions & 0 deletions documentation/en/default-lotus-config.toml
Expand Up @@ -121,6 +121,14 @@
# env var: LOTUS_CLIENT_SIMULTANEOUSTRANSFERSFORRETRIEVAL
#SimultaneousTransfersForRetrieval = 20

# Require that retrievals perform no on-chain retrievals. Paid retrievals
magik6k marked this conversation as resolved.
Show resolved Hide resolved
# without existing payment channels with available funds will fail instead
# of automatically performing on-chain operations.
#
# type: bool
# env var: LOTUS_CLIENT_OFFCHAINRETRIEVAL
#OffChainRetrieval = false


[Wallet]
# type: string
Expand Down
5 changes: 4 additions & 1 deletion itests/paych_api_test.go
Expand Up @@ -58,7 +58,10 @@ func TestPaymentChannelsAPI(t *testing.T) {
require.NoError(t, err)

channelAmt := int64(7000)
channelInfo, err := paymentCreator.PaychGet(ctx, createrAddr, receiverAddr, abi.NewTokenAmount(channelAmt))
channelInfo, err := paymentCreator.PaychGet(ctx, createrAddr, receiverAddr, abi.NewTokenAmount(channelAmt), api.PaychGetOpts{
Reserve: true,
OffChain: false,
})
require.NoError(t, err)

channel, err := paymentCreator.PaychGetWaitReady(ctx, channelInfo.WaitSentinel)
Expand Down
6 changes: 3 additions & 3 deletions itests/paych_cli_test.go
Expand Up @@ -133,10 +133,10 @@ func TestPaymentChannelStatus(t *testing.T) {
require.True(t, stateCreating || stateCreated)

channelAmtAtto := types.BigMul(types.NewInt(channelAmt), types.NewInt(build.FilecoinPrecision))
channelAmtStr := fmt.Sprintf("%d", channelAmtAtto)
channelAmtStr := fmt.Sprintf("%s", types.FIL(channelAmtAtto))
if stateCreating {
// If we're in the creating state (most likely) the amount should be pending
require.Regexp(t, regexp.MustCompile("Pending.*"+channelAmtStr), out)
require.Regexp(t, regexp.MustCompile("Pending Amt.*"+channelAmtStr), out)
}

// Wait for create channel to complete
Expand All @@ -159,7 +159,7 @@ func TestPaymentChannelStatus(t *testing.T) {
out = creatorCLI.RunCmd("paych", "status", chstr)
fmt.Println(out)
voucherAmtAtto := types.BigMul(types.NewInt(voucherAmt), types.NewInt(build.FilecoinPrecision))
voucherAmtStr := fmt.Sprintf("%d", voucherAmtAtto)
voucherAmtStr := fmt.Sprintf("%s", types.FIL(voucherAmtAtto))
// Output should include voucher amount
require.Regexp(t, regexp.MustCompile("Voucher.*"+voucherAmtStr), out)
}
Expand Down