diff --git a/api/api.go b/api/api.go
index f2b38f670..e14eed76c 100644
--- a/api/api.go
+++ b/api/api.go
@@ -120,7 +120,7 @@ type FullNode interface {
PaychVoucherCheckValid(context.Context, address.Address, *types.SignedVoucher) error
PaychVoucherCheckSpendable(context.Context, address.Address, *types.SignedVoucher, []byte, []byte) (bool, 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)
PaychVoucherSubmit(context.Context, address.Address, *types.SignedVoucher) (cid.Cid, error)
}
diff --git a/api/struct.go b/api/struct.go
index 553586dc5..2dad2aecb 100644
--- a/api/struct.go
+++ b/api/struct.go
@@ -93,7 +93,7 @@ type FullNodeStruct struct {
PaychVoucherCheck func(context.Context, *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"`
- 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"`
PaychVoucherList func(context.Context, address.Address) ([]*types.SignedVoucher, error) `perm:"write"`
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)
}
-func (c *FullNodeStruct) PaychVoucherAdd(ctx context.Context, addr address.Address, sv *types.SignedVoucher, proof []byte) error {
- return c.Internal.PaychVoucherAdd(ctx, addr, sv, proof)
+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, minDelta)
}
func (c *FullNodeStruct) PaychVoucherCreate(ctx context.Context, pch address.Address, amt types.BigInt, lane uint64) (*types.SignedVoucher, error) {
diff --git a/chain/deals/client.go b/chain/deals/client.go
index 42b454659..70fe26252 100644
--- a/chain/deals/client.go
+++ b/chain/deals/client.go
@@ -32,6 +32,7 @@ func init() {
cbor.RegisterCborType(types.ModVerifyParams{})
cbor.RegisterCborType(types.Signature{})
cbor.RegisterCborType(actors.PaymentInfo{})
+ cbor.RegisterCborType(api.PaymentInfo{})
cbor.RegisterCborType(actors.InclusionProof{})
}
diff --git a/chain/deals/handler_states.go b/chain/deals/handler_states.go
index fc1b122c5..0b2314acc 100644
--- a/chain/deals/handler_states.go
+++ b/chain/deals/handler_states.go
@@ -124,7 +124,8 @@ func (h *Handler) accept(ctx context.Context, deal MinerDeal) (func(*MinerDeal),
}
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)
}
}
@@ -240,7 +241,8 @@ func (h *Handler) sealing(ctx context.Context, deal MinerDeal) (func(*MinerDeal)
// store proofs for channels
for i, v := range deal.Proposal.Payment.Vouchers {
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)
}
}
diff --git a/cli/paych.go b/cli/paych.go
index e79d14141..db5ab0b71 100644
--- a/cli/paych.go
+++ b/cli/paych.go
@@ -203,7 +203,7 @@ var paychVoucherAddCmd = &cli.Command{
ctx := ReqContext(cctx)
// 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
}
diff --git a/lotuspond/front/src/Client.js b/lotuspond/front/src/Client.js
index 698badada..8a4472ddd 100644
--- a/lotuspond/front/src/Client.js
+++ b/lotuspond/front/src/Client.js
@@ -57,7 +57,7 @@ class Client extends React.Component {
Root: deal.PieceRef,
Size: deal.Size,
// TODO: support offset
- Total: "900",
+ Total: String(deal.Size * 2),
Client: client,
Miner: deal.Miner
diff --git a/lotuspond/front/src/FullNode.js b/lotuspond/front/src/FullNode.js
index 59b23ff08..312e917db 100644
--- a/lotuspond/front/src/FullNode.js
+++ b/lotuspond/front/src/FullNode.js
@@ -132,7 +132,7 @@ class FullNode extends React.Component {
extra = Verif: <>
}
- return
+ return
Voucher Nonce:{voucher.Nonce} Lane:{voucher.Lane} Amt:{voucher.Amount} TL:{voucher.TimeLock} MinCl:{voucher.MinCloseHeight} {extra}
})
diff --git a/lotuspond/front/src/StorageNode.js b/lotuspond/front/src/StorageNode.js
index a27295fb5..e2f2f86de 100644
--- a/lotuspond/front/src/StorageNode.js
+++ b/lotuspond/front/src/StorageNode.js
@@ -104,11 +104,11 @@ class StorageNode extends React.Component {
-
{this.state.statusCounts.map((c, i) => {sealCodes[i]}: {c} | )}
+
{this.state.statusCounts.map((c, i) => {sealCodes[i]}: {c} | )}
- {this.state.staged ? this.state.staged.map(s => (
-
{s.SectorID} {sealCodes[s.SealStatusCode]}
- )) :
}
+ {this.state.staged ? this.state.staged.map((s, i) => (
+
{s.SectorID} {sealCodes[s.SealStatusCode]}
+ )) :
}
diff --git a/node/impl/paych/paych.go b/node/impl/paych/paych.go
index b3dd2fd4f..15c89befe 100644
--- a/node/impl/paych/paych.go
+++ b/node/impl/paych/paych.go
@@ -134,14 +134,14 @@ func (a *PaychAPI) PaychVoucherCheckSpendable(ctx context.Context, ch address.Ad
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
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
@@ -179,7 +179,7 @@ func (a *PaychAPI) paychVoucherCreate(ctx context.Context, pch address.Address,
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)
}
diff --git a/paych/paych.go b/paych/paych.go
index ed47357ee..d3b91b0e9 100644
--- a/paych/paych.go
+++ b/paych/paych.go
@@ -248,12 +248,12 @@ func (pm *Manager) getPaychOwner(ctx context.Context, ch address.Address) (addre
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 {
- 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) {
diff --git a/paych/store.go b/paych/store.go
index 9bd493dda..ad1286e72 100644
--- a/paych/store.go
+++ b/paych/store.go
@@ -4,6 +4,7 @@ import (
"bytes"
"errors"
"fmt"
+ "math"
"strings"
"sync"
@@ -181,17 +182,24 @@ func (ps *Store) findChan(filter func(*ChannelInfo) bool) (address.Address, erro
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()
defer ps.lk.Unlock()
ci, err := ps.getChannelInfo(ch)
if err != nil {
- return err
+ return types.NewInt(0), err
}
+ var bestAmount types.BigInt
+ var bestNonce uint64 = math.MaxUint64
+
// look for duplicates
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) {
continue
}
@@ -201,7 +209,7 @@ func (ps *Store) AddVoucher(ch address.Address, sv *types.SignedVoucher, proof [
break
}
log.Warnf("AddVoucher: voucher re-added with matching proof")
- return nil
+ return types.NewInt(0), nil
}
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,
}
- 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{
@@ -222,7 +239,7 @@ func (ps *Store) AddVoucher(ch address.Address, sv *types.SignedVoucher, proof [
ci.NextLane = sv.Lane + 1
}
- return ps.putChannelInfo(ci)
+ return delta, ps.putChannelInfo(ci)
}
func (ps *Store) AllocateLane(ch address.Address) (uint64, error) {
diff --git a/retrieval/miner.go b/retrieval/miner.go
index 434ccfab3..ebbe1f093 100644
--- a/retrieval/miner.go
+++ b/retrieval/miner.go
@@ -11,6 +11,7 @@ import (
"github.com/libp2p/go-libp2p-core/network"
"golang.org/x/xerrors"
+ "github.com/filecoin-project/go-lotus/api"
"github.com/filecoin-project/go-lotus/build"
"github.com/filecoin-project/go-lotus/chain/types"
"github.com/filecoin-project/go-lotus/lib/cborrpc"
@@ -19,14 +20,17 @@ import (
type Miner struct {
sectorBlocks *sectorblocks.SectorBlocks
+ full api.FullNode
pricePerByte types.BigInt
// TODO: Unseal price
}
-func NewMiner(sblks *sectorblocks.SectorBlocks) *Miner {
+func NewMiner(sblks *sectorblocks.SectorBlocks, full api.FullNode) *Miner {
return &Miner{
sectorBlocks: sblks,
+ full: full,
+
pricePerByte: types.NewInt(2), // TODO: allow setting
}
}
@@ -118,8 +122,10 @@ func (hnd *handlerDeal) handleNext() (bool, error) {
unixfs0 := deal.Params.Unixfs0
- // TODO: Verify payment, check how much we can send based on that
- // Or reject (possibly returning the payment to retain reputation with the client)
+ expPayment := types.BigMul(hnd.m.pricePerByte, types.NewInt(deal.Params.Unixfs0.Size))
+ 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
// at the right offset, (re)open it