Make retrieval work with reused channels

This commit is contained in:
Łukasz Magiera 2022-01-05 00:09:19 +01:00
parent ff8b95df93
commit 1f2621b574
2 changed files with 35 additions and 1 deletions

View File

@ -9,6 +9,8 @@ import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/ipfs/go-cid"
"github.com/multiformats/go-multiaddr"
mh "github.com/multiformats/go-multihash"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
"github.com/filecoin-project/lotus/chain/types"
@ -16,6 +18,27 @@ import (
payapi "github.com/filecoin-project/lotus/node/impl/paych"
)
func mkPaychReusedCid(addr address.Address) cid.Cid {
c, err := cid.V1Builder{Codec: cid.Raw, MhType: mh.IDENTITY}.Sum(addr.Bytes())
if err != nil {
panic(err)
}
return c
}
func extractPaychReusedCid(c cid.Cid) (address.Address, error) {
if c.Prefix().Codec != cid.Raw {
return address.Undef, nil
}
h, err := mh.Decode(c.Hash())
if err != nil {
return address.Address{}, err
}
return address.NewFromBytes(h.Digest)
}
type retrievalClientNode struct {
chainAPI full.ChainAPI
payAPI payapi.PaychAPI
@ -38,6 +61,10 @@ func (rcn *retrievalClientNode) GetOrCreatePaymentChannel(ctx context.Context, c
if err != nil {
return address.Undef, cid.Undef, err
}
if ci.WaitSentinel == cid.Undef {
return ci.Channel, mkPaychReusedCid(ci.Channel), nil
}
return ci.Channel, ci.WaitSentinel, nil
}
@ -74,6 +101,13 @@ func (rcn *retrievalClientNode) GetChainHead(ctx context.Context) (shared.TipSet
}
func (rcn *retrievalClientNode) WaitForPaymentChannelReady(ctx context.Context, messageCID cid.Cid) (address.Address, error) {
maybeAddr, err := extractPaychReusedCid(messageCID)
if err != nil {
return address.Address{}, xerrors.Errorf("extract paych reused CID: %w", err)
}
if maybeAddr != address.Undef {
return maybeAddr, nil
}
return rcn.payAPI.PaychGetWaitReady(ctx, messageCID)
}

View File

@ -41,7 +41,7 @@ type fundsReq struct {
}
func newFundsReq(ctx context.Context, amt types.BigInt, reserve bool) *fundsReq {
promise := make(chan *paychFundsRes)
promise := make(chan *paychFundsRes, 1)
return &fundsReq{
ctx: ctx,
promise: promise,