retrieval: payment validation
This commit is contained in:
parent
0a853ac0e7
commit
9fe198dc6f
@ -120,7 +120,7 @@ type FullNode interface {
|
|||||||
PaychVoucherCheckValid(context.Context, address.Address, *types.SignedVoucher) error
|
PaychVoucherCheckValid(context.Context, address.Address, *types.SignedVoucher) error
|
||||||
PaychVoucherCheckSpendable(context.Context, address.Address, *types.SignedVoucher, []byte, []byte) (bool, error)
|
PaychVoucherCheckSpendable(context.Context, address.Address, *types.SignedVoucher, []byte, []byte) (bool, error)
|
||||||
PaychVoucherCreate(context.Context, address.Address, types.BigInt, uint64) (*types.SignedVoucher, error)
|
PaychVoucherCreate(context.Context, address.Address, types.BigInt, uint64) (*types.SignedVoucher, error)
|
||||||
PaychVoucherAdd(context.Context, address.Address, *types.SignedVoucher, []byte) error
|
PaychVoucherAdd(context.Context, address.Address, *types.SignedVoucher, []byte, types.BigInt) (types.BigInt, error)
|
||||||
PaychVoucherList(context.Context, address.Address) ([]*types.SignedVoucher, error)
|
PaychVoucherList(context.Context, address.Address) ([]*types.SignedVoucher, error)
|
||||||
PaychVoucherSubmit(context.Context, address.Address, *types.SignedVoucher) (cid.Cid, error)
|
PaychVoucherSubmit(context.Context, address.Address, *types.SignedVoucher) (cid.Cid, error)
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ type FullNodeStruct struct {
|
|||||||
PaychVoucherCheck func(context.Context, *types.SignedVoucher) error `perm:"read"`
|
PaychVoucherCheck func(context.Context, *types.SignedVoucher) error `perm:"read"`
|
||||||
PaychVoucherCheckValid func(context.Context, address.Address, *types.SignedVoucher) error `perm:"read"`
|
PaychVoucherCheckValid func(context.Context, address.Address, *types.SignedVoucher) error `perm:"read"`
|
||||||
PaychVoucherCheckSpendable func(context.Context, address.Address, *types.SignedVoucher, []byte, []byte) (bool, error) `perm:"read"`
|
PaychVoucherCheckSpendable func(context.Context, address.Address, *types.SignedVoucher, []byte, []byte) (bool, error) `perm:"read"`
|
||||||
PaychVoucherAdd func(context.Context, address.Address, *types.SignedVoucher, []byte) error `perm:"write"`
|
PaychVoucherAdd func(context.Context, address.Address, *types.SignedVoucher, []byte, types.BigInt) (types.BigInt, error) `perm:"write"`
|
||||||
PaychVoucherCreate func(context.Context, address.Address, types.BigInt, uint64) (*types.SignedVoucher, error) `perm:"sign"`
|
PaychVoucherCreate func(context.Context, address.Address, types.BigInt, uint64) (*types.SignedVoucher, error) `perm:"sign"`
|
||||||
PaychVoucherList func(context.Context, address.Address) ([]*types.SignedVoucher, error) `perm:"write"`
|
PaychVoucherList func(context.Context, address.Address) ([]*types.SignedVoucher, error) `perm:"write"`
|
||||||
PaychVoucherSubmit func(context.Context, address.Address, *types.SignedVoucher) (cid.Cid, error) `perm:"sign"`
|
PaychVoucherSubmit func(context.Context, address.Address, *types.SignedVoucher) (cid.Cid, error) `perm:"sign"`
|
||||||
@ -330,8 +330,8 @@ func (c *FullNodeStruct) PaychVoucherCheckSpendable(ctx context.Context, addr ad
|
|||||||
return c.Internal.PaychVoucherCheckSpendable(ctx, addr, sv, secret, proof)
|
return c.Internal.PaychVoucherCheckSpendable(ctx, addr, sv, secret, proof)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) PaychVoucherAdd(ctx context.Context, addr address.Address, sv *types.SignedVoucher, proof []byte) error {
|
func (c *FullNodeStruct) PaychVoucherAdd(ctx context.Context, addr address.Address, sv *types.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) {
|
||||||
return c.Internal.PaychVoucherAdd(ctx, addr, sv, proof)
|
return c.Internal.PaychVoucherAdd(ctx, addr, sv, proof, minDelta)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) PaychVoucherCreate(ctx context.Context, pch address.Address, amt types.BigInt, lane uint64) (*types.SignedVoucher, error) {
|
func (c *FullNodeStruct) PaychVoucherCreate(ctx context.Context, pch address.Address, amt types.BigInt, lane uint64) (*types.SignedVoucher, error) {
|
||||||
|
@ -32,6 +32,7 @@ func init() {
|
|||||||
cbor.RegisterCborType(types.ModVerifyParams{})
|
cbor.RegisterCborType(types.ModVerifyParams{})
|
||||||
cbor.RegisterCborType(types.Signature{})
|
cbor.RegisterCborType(types.Signature{})
|
||||||
cbor.RegisterCborType(actors.PaymentInfo{})
|
cbor.RegisterCborType(actors.PaymentInfo{})
|
||||||
|
cbor.RegisterCborType(api.PaymentInfo{})
|
||||||
cbor.RegisterCborType(actors.InclusionProof{})
|
cbor.RegisterCborType(actors.InclusionProof{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,8 @@ func (h *Handler) accept(ctx context.Context, deal MinerDeal) (func(*MinerDeal),
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i, voucher := range deal.Proposal.Payment.Vouchers {
|
for i, voucher := range deal.Proposal.Payment.Vouchers {
|
||||||
if err := h.full.PaychVoucherAdd(ctx, deal.Proposal.Payment.PayChActor, voucher, nil); err != nil {
|
// TODO: Set correct minAmount
|
||||||
|
if _, err := h.full.PaychVoucherAdd(ctx, deal.Proposal.Payment.PayChActor, voucher, nil, types.NewInt(0)); err != nil {
|
||||||
return nil, xerrors.Errorf("consuming payment voucher %d: %w", i, err)
|
return nil, xerrors.Errorf("consuming payment voucher %d: %w", i, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -240,7 +241,8 @@ func (h *Handler) sealing(ctx context.Context, deal MinerDeal) (func(*MinerDeal)
|
|||||||
// store proofs for channels
|
// store proofs for channels
|
||||||
for i, v := range deal.Proposal.Payment.Vouchers {
|
for i, v := range deal.Proposal.Payment.Vouchers {
|
||||||
if v.Extra.Method == actors.MAMethods.PaymentVerifyInclusion {
|
if v.Extra.Method == actors.MAMethods.PaymentVerifyInclusion {
|
||||||
if err := h.full.PaychVoucherAdd(ctx, deal.Proposal.Payment.PayChActor, v, proofB); err != nil {
|
// TODO: Set correct minAmount
|
||||||
|
if _, err := h.full.PaychVoucherAdd(ctx, deal.Proposal.Payment.PayChActor, v, proofB, types.NewInt(0)); err != nil {
|
||||||
return nil, xerrors.Errorf("storing payment voucher %d proof: %w", i, err)
|
return nil, xerrors.Errorf("storing payment voucher %d proof: %w", i, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ var paychVoucherAddCmd = &cli.Command{
|
|||||||
ctx := ReqContext(cctx)
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
// TODO: allow passing proof bytes
|
// TODO: allow passing proof bytes
|
||||||
if err := api.PaychVoucherAdd(ctx, ch, sv, nil); err != nil {
|
if _, err := api.PaychVoucherAdd(ctx, ch, sv, nil, types.NewInt(0)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ class Client extends React.Component {
|
|||||||
Root: deal.PieceRef,
|
Root: deal.PieceRef,
|
||||||
Size: deal.Size,
|
Size: deal.Size,
|
||||||
// TODO: support offset
|
// TODO: support offset
|
||||||
Total: "900",
|
Total: String(deal.Size * 2),
|
||||||
|
|
||||||
Client: client,
|
Client: client,
|
||||||
Miner: deal.Miner
|
Miner: deal.Miner
|
||||||
|
@ -132,7 +132,7 @@ class FullNode extends React.Component {
|
|||||||
extra = <span>Verif: <<b><Address nobalance={true} client={this.props.client} addr={voucher.Extra.Actor} method={voucher.Extra.Method} mountWindow={this.props.mountWindow}/></b>></span>
|
extra = <span>Verif: <<b><Address nobalance={true} client={this.props.client} addr={voucher.Extra.Actor} method={voucher.Extra.Method} mountWindow={this.props.mountWindow}/></b>></span>
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div key={voucher.Nonce} className="FullNode-voucher">
|
return <div key={`${addr} ${voucher.Lane} ${voucher.Nonce}`} className="FullNode-voucher">
|
||||||
Voucher Nonce:<b>{voucher.Nonce}</b> Lane:<b>{voucher.Lane}</b> Amt:<b>{voucher.Amount}</b> TL:<b>{voucher.TimeLock}</b> MinCl:<b>{voucher.MinCloseHeight}</b> {extra}
|
Voucher Nonce:<b>{voucher.Nonce}</b> Lane:<b>{voucher.Lane}</b> Amt:<b>{voucher.Amount}</b> TL:<b>{voucher.TimeLock}</b> MinCl:<b>{voucher.MinCloseHeight}</b> {extra}
|
||||||
</div>
|
</div>
|
||||||
})
|
})
|
||||||
|
@ -104,11 +104,11 @@ class StorageNode extends React.Component {
|
|||||||
<div>
|
<div>
|
||||||
<Address client={this.props.fullConn} addr={this.state.actor} mountWindow={this.props.mountWindow}/>
|
<Address client={this.props.fullConn} addr={this.state.actor} mountWindow={this.props.mountWindow}/>
|
||||||
</div>
|
</div>
|
||||||
<div>{this.state.statusCounts.map((c, i) => <span>{sealCodes[i]}: {c} | </span>)}</div>
|
<div>{this.state.statusCounts.map((c, i) => <span key={i}>{sealCodes[i]}: {c} | </span>)}</div>
|
||||||
<div>
|
<div>
|
||||||
{this.state.staged ? this.state.staged.map(s => (
|
{this.state.staged ? this.state.staged.map((s, i) => (
|
||||||
<div>{s.SectorID} {sealCodes[s.SealStatusCode]}</div>
|
<div key={i}>{s.SectorID} {sealCodes[s.SealStatusCode]}</div>
|
||||||
)) : <div></div>}
|
)) : <div/>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -134,14 +134,14 @@ func (a *PaychAPI) PaychVoucherCheckSpendable(ctx context.Context, ch address.Ad
|
|||||||
return a.PaychMgr.CheckVoucherSpendable(ctx, ch, sv, secret, proof)
|
return a.PaychMgr.CheckVoucherSpendable(ctx, ch, sv, secret, proof)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *PaychAPI) PaychVoucherAdd(ctx context.Context, ch address.Address, sv *types.SignedVoucher, proof []byte) error {
|
func (a *PaychAPI) PaychVoucherAdd(ctx context.Context, ch address.Address, sv *types.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) {
|
||||||
_ = a.PaychMgr.TrackInboundChannel(ctx, ch) // TODO: expose those calls
|
_ = a.PaychMgr.TrackInboundChannel(ctx, ch) // TODO: expose those calls
|
||||||
|
|
||||||
if err := a.PaychVoucherCheckValid(ctx, ch, sv); err != nil {
|
if err := a.PaychVoucherCheckValid(ctx, ch, sv); err != nil {
|
||||||
return err
|
return types.NewInt(0), err
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.PaychMgr.AddVoucher(ctx, ch, sv, proof)
|
return a.PaychMgr.AddVoucher(ctx, ch, sv, proof, minDelta)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PaychVoucherCreate creates a new signed voucher on the given payment channel
|
// PaychVoucherCreate creates a new signed voucher on the given payment channel
|
||||||
@ -179,7 +179,7 @@ func (a *PaychAPI) paychVoucherCreate(ctx context.Context, pch address.Address,
|
|||||||
|
|
||||||
sv.Signature = sig
|
sv.Signature = sig
|
||||||
|
|
||||||
if err := a.PaychMgr.AddVoucher(ctx, pch, sv, nil); err != nil {
|
if _, err := a.PaychMgr.AddVoucher(ctx, pch, sv, nil, types.NewInt(0)); err != nil {
|
||||||
return nil, xerrors.Errorf("failed to persist voucher: %w", err)
|
return nil, xerrors.Errorf("failed to persist voucher: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,12 +248,12 @@ func (pm *Manager) getPaychOwner(ctx context.Context, ch address.Address) (addre
|
|||||||
return address.NewFromBytes(ret.Return)
|
return address.NewFromBytes(ret.Return)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *Manager) AddVoucher(ctx context.Context, ch address.Address, sv *types.SignedVoucher, proof []byte) error {
|
func (pm *Manager) AddVoucher(ctx context.Context, ch address.Address, sv *types.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) {
|
||||||
if err := pm.CheckVoucherValid(ctx, ch, sv); err != nil {
|
if err := pm.CheckVoucherValid(ctx, ch, sv); err != nil {
|
||||||
return err
|
return types.NewInt(0), err
|
||||||
}
|
}
|
||||||
|
|
||||||
return pm.store.AddVoucher(ch, sv, proof)
|
return pm.store.AddVoucher(ch, sv, proof, minDelta)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *Manager) AllocateLane(ch address.Address) (uint64, error) {
|
func (pm *Manager) AllocateLane(ch address.Address) (uint64, error) {
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@ -181,17 +182,24 @@ func (ps *Store) findChan(filter func(*ChannelInfo) bool) (address.Address, erro
|
|||||||
return address.Undef, nil
|
return address.Undef, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *Store) AddVoucher(ch address.Address, sv *types.SignedVoucher, proof []byte) error {
|
func (ps *Store) AddVoucher(ch address.Address, sv *types.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) {
|
||||||
ps.lk.Lock()
|
ps.lk.Lock()
|
||||||
defer ps.lk.Unlock()
|
defer ps.lk.Unlock()
|
||||||
|
|
||||||
ci, err := ps.getChannelInfo(ch)
|
ci, err := ps.getChannelInfo(ch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return types.NewInt(0), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var bestAmount types.BigInt
|
||||||
|
var bestNonce uint64 = math.MaxUint64
|
||||||
|
|
||||||
// look for duplicates
|
// look for duplicates
|
||||||
for i, v := range ci.Vouchers {
|
for i, v := range ci.Vouchers {
|
||||||
|
if v.Voucher.Lane == sv.Lane && v.Voucher.Nonce + 1 > bestNonce + 1 {
|
||||||
|
bestNonce = v.Voucher.Nonce
|
||||||
|
bestAmount = v.Voucher.Amount
|
||||||
|
}
|
||||||
if !sv.Equals(v.Voucher) {
|
if !sv.Equals(v.Voucher) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -201,7 +209,7 @@ func (ps *Store) AddVoucher(ch address.Address, sv *types.SignedVoucher, proof [
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
log.Warnf("AddVoucher: voucher re-added with matching proof")
|
log.Warnf("AddVoucher: voucher re-added with matching proof")
|
||||||
return nil
|
return types.NewInt(0), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Warnf("AddVoucher: adding proof to stored voucher")
|
log.Warnf("AddVoucher: adding proof to stored voucher")
|
||||||
@ -210,7 +218,16 @@ func (ps *Store) AddVoucher(ch address.Address, sv *types.SignedVoucher, proof [
|
|||||||
Proof: proof,
|
Proof: proof,
|
||||||
}
|
}
|
||||||
|
|
||||||
return ps.putChannelInfo(ci)
|
return types.NewInt(0), ps.putChannelInfo(ci)
|
||||||
|
}
|
||||||
|
|
||||||
|
if bestAmount == (types.BigInt{}) {
|
||||||
|
bestAmount = types.NewInt(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
delta := types.BigSub(sv.Amount, bestAmount)
|
||||||
|
if types.BigCmp(minDelta, delta) > 0 {
|
||||||
|
return delta, xerrors.Errorf("addVoucher: supplied token amount too low; minD=%s, D=%s; bestAmt=%s; v.Amt=%s", minDelta, delta, bestAmount, sv.Amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
ci.Vouchers = append(ci.Vouchers, &VoucherInfo{
|
ci.Vouchers = append(ci.Vouchers, &VoucherInfo{
|
||||||
@ -222,7 +239,7 @@ func (ps *Store) AddVoucher(ch address.Address, sv *types.SignedVoucher, proof [
|
|||||||
ci.NextLane = sv.Lane + 1
|
ci.NextLane = sv.Lane + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
return ps.putChannelInfo(ci)
|
return delta, ps.putChannelInfo(ci)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *Store) AllocateLane(ch address.Address) (uint64, error) {
|
func (ps *Store) AllocateLane(ch address.Address) (uint64, error) {
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/libp2p/go-libp2p-core/network"
|
"github.com/libp2p/go-libp2p-core/network"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-lotus/api"
|
||||||
"github.com/filecoin-project/go-lotus/build"
|
"github.com/filecoin-project/go-lotus/build"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
"github.com/filecoin-project/go-lotus/lib/cborrpc"
|
"github.com/filecoin-project/go-lotus/lib/cborrpc"
|
||||||
@ -19,14 +20,17 @@ import (
|
|||||||
|
|
||||||
type Miner struct {
|
type Miner struct {
|
||||||
sectorBlocks *sectorblocks.SectorBlocks
|
sectorBlocks *sectorblocks.SectorBlocks
|
||||||
|
full api.FullNode
|
||||||
|
|
||||||
pricePerByte types.BigInt
|
pricePerByte types.BigInt
|
||||||
// TODO: Unseal price
|
// TODO: Unseal price
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMiner(sblks *sectorblocks.SectorBlocks) *Miner {
|
func NewMiner(sblks *sectorblocks.SectorBlocks, full api.FullNode) *Miner {
|
||||||
return &Miner{
|
return &Miner{
|
||||||
sectorBlocks: sblks,
|
sectorBlocks: sblks,
|
||||||
|
full: full,
|
||||||
|
|
||||||
pricePerByte: types.NewInt(2), // TODO: allow setting
|
pricePerByte: types.NewInt(2), // TODO: allow setting
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,8 +122,10 @@ func (hnd *handlerDeal) handleNext() (bool, error) {
|
|||||||
|
|
||||||
unixfs0 := deal.Params.Unixfs0
|
unixfs0 := deal.Params.Unixfs0
|
||||||
|
|
||||||
// TODO: Verify payment, check how much we can send based on that
|
expPayment := types.BigMul(hnd.m.pricePerByte, types.NewInt(deal.Params.Unixfs0.Size))
|
||||||
// Or reject (possibly returning the payment to retain reputation with the client)
|
if _, err := hnd.m.full.PaychVoucherAdd(context.TODO(), deal.Payment.Channel, deal.Payment.Voucher, nil, expPayment); err != nil {
|
||||||
|
return false, xerrors.Errorf("processing retrieval payment: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
// If the file isn't open (new deal stream), isn't the right file, or isn't
|
// If the file isn't open (new deal stream), isn't the right file, or isn't
|
||||||
// at the right offset, (re)open it
|
// at the right offset, (re)open it
|
||||||
|
Loading…
Reference in New Issue
Block a user