Merge pull request #415 from filecoin-project/feat/deals-on-chain
On-Chain deals
This commit is contained in:
+1
-1
@@ -240,7 +240,7 @@ func Online() Option {
|
||||
Override(new(dtypes.StagingDAG), modules.StagingDAG),
|
||||
|
||||
Override(new(*retrieval.Miner), retrieval.NewMiner),
|
||||
Override(new(*deals.Handler), deals.NewHandler),
|
||||
Override(new(*deals.Provider), deals.NewProvider),
|
||||
Override(HandleRetrievalKey, modules.HandleRetrieval),
|
||||
Override(HandleDealsKey, modules.HandleDeals),
|
||||
Override(RunSectorServiceKey, modules.RunSectorService),
|
||||
|
||||
+12
-43
@@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"golang.org/x/xerrors"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
|
||||
"github.com/ipfs/go-blockservice"
|
||||
@@ -13,7 +14,6 @@ import (
|
||||
chunker "github.com/ipfs/go-ipfs-chunker"
|
||||
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
||||
files "github.com/ipfs/go-ipfs-files"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
ipld "github.com/ipfs/go-ipld-format"
|
||||
"github.com/ipfs/go-merkledag"
|
||||
"github.com/ipfs/go-unixfs/importer/balanced"
|
||||
@@ -76,50 +76,20 @@ func (a *API) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.A
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vd, err := a.DealClient.VerifyParams(ctx, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
voucherData, err := cbor.DumpObject(vd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// setup payments
|
||||
total := types.BigMul(price, types.NewInt(blocksDuration))
|
||||
|
||||
// TODO: at least ping the miner before creating paych / locking the money
|
||||
extra := &types.ModVerifyParams{
|
||||
Actor: miner,
|
||||
Method: actors.MAMethods.PaymentVerifyInclusion,
|
||||
Data: voucherData,
|
||||
}
|
||||
|
||||
head := a.Chain.GetHeaviestTipSet()
|
||||
vouchers := deals.VoucherSpec(blocksDuration, total, head.Height(), extra)
|
||||
|
||||
payment, err := a.PaychNewPayment(ctx, self, miner, vouchers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
proposal := deals.ClientDealProposal{
|
||||
Data: data,
|
||||
TotalPrice: total,
|
||||
Duration: blocksDuration,
|
||||
Payment: actors.PaymentInfo{
|
||||
PayChActor: payment.Channel,
|
||||
Payer: self,
|
||||
ChannelMessage: payment.ChannelMessage,
|
||||
Vouchers: payment.Vouchers,
|
||||
},
|
||||
MinerAddress: miner,
|
||||
ClientAddress: self,
|
||||
MinerID: pid,
|
||||
Data: data,
|
||||
TotalPrice: total,
|
||||
ProposalExpiration: math.MaxUint64, // TODO: set something reasonable
|
||||
Duration: blocksDuration,
|
||||
ProviderAddress: miner,
|
||||
Client: self,
|
||||
MinerID: pid,
|
||||
}
|
||||
|
||||
c, err := a.DealClient.Start(ctx, proposal, vd)
|
||||
c, err := a.DealClient.Start(ctx, proposal)
|
||||
// TODO: send updated voucher with PaymentVerifySector for cheaper validation (validate the sector the miner sent us first!)
|
||||
return &c, err
|
||||
}
|
||||
@@ -135,13 +105,12 @@ func (a *API) ClientListDeals(ctx context.Context) ([]api.DealInfo, error) {
|
||||
out[k] = api.DealInfo{
|
||||
ProposalCid: v.ProposalCid,
|
||||
State: v.State,
|
||||
Miner: v.Proposal.MinerAddress,
|
||||
Provider: v.Proposal.Provider,
|
||||
|
||||
PieceRef: v.Proposal.PieceRef,
|
||||
CommP: v.Proposal.CommP,
|
||||
Size: v.Proposal.Size,
|
||||
Size: v.Proposal.PieceSize,
|
||||
|
||||
TotalPrice: v.Proposal.TotalPrice,
|
||||
TotalPrice: v.Proposal.StoragePrice,
|
||||
Duration: v.Proposal.Duration,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,8 @@ func (a *CommonAPI) Version(context.Context) (api.Version, error) {
|
||||
return api.Version{
|
||||
Version: build.Version,
|
||||
APIVersion: build.APIVersion,
|
||||
|
||||
BlockDelay: build.BlockDelay,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
+71
-22
@@ -1,11 +1,15 @@
|
||||
package full
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"github.com/filecoin-project/go-amt-ipld"
|
||||
"strconv"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-hamt-ipld"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
@@ -54,25 +58,7 @@ func (a *StateAPI) StateMinerPower(ctx context.Context, maddr address.Address, t
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerWorker(ctx context.Context, m address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
ret, err := a.StateManager.Call(ctx, &types.Message{
|
||||
From: m,
|
||||
To: m,
|
||||
Method: actors.MAMethods.GetWorkerAddr,
|
||||
}, ts)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("failed to get miner worker addr: %w", err)
|
||||
}
|
||||
|
||||
if ret.ExitCode != 0 {
|
||||
return address.Undef, xerrors.Errorf("failed to get miner worker addr (exit code %d)", ret.ExitCode)
|
||||
}
|
||||
|
||||
w, err := address.NewFromBytes(ret.Return)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("GetWorkerAddr returned malformed address: %w", err)
|
||||
}
|
||||
|
||||
return w, nil
|
||||
return stmgr.GetMinerWorker(ctx, a.StateManager, ts, m)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerPeerID(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error) {
|
||||
@@ -90,8 +76,8 @@ func (a *StateAPI) StatePledgeCollateral(ctx context.Context, ts *types.TipSet)
|
||||
}
|
||||
|
||||
ret, aerr := a.StateManager.Call(ctx, &types.Message{
|
||||
From: actors.StorageMarketAddress,
|
||||
To: actors.StorageMarketAddress,
|
||||
From: actors.StoragePowerAddress,
|
||||
To: actors.StoragePowerAddress,
|
||||
Method: actors.SPAMethods.PledgeCollateralForSize,
|
||||
|
||||
Params: param,
|
||||
@@ -210,7 +196,7 @@ func (a *StateAPI) StateWaitMsg(ctx context.Context, msg cid.Cid) (*api.MsgWait,
|
||||
|
||||
func (a *StateAPI) StateListMiners(ctx context.Context, ts *types.TipSet) ([]address.Address, error) {
|
||||
var state actors.StoragePowerState
|
||||
if _, err := a.StateManager.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil {
|
||||
if _, err := a.StateManager.LoadActorState(ctx, actors.StoragePowerAddress, &state, ts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -226,3 +212,66 @@ func (a *StateAPI) StateListMiners(ctx context.Context, ts *types.TipSet) ([]add
|
||||
func (a *StateAPI) StateListActors(ctx context.Context, ts *types.TipSet) ([]address.Address, error) {
|
||||
return a.StateManager.ListAllActors(ctx, ts)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMarketBalance(ctx context.Context, addr address.Address, ts *types.TipSet) (actors.StorageParticipantBalance, error) {
|
||||
return a.StateManager.MarketBalance(ctx, addr, ts)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMarketParticipants(ctx context.Context, ts *types.TipSet) (map[string]actors.StorageParticipantBalance, error) {
|
||||
out := map[string]actors.StorageParticipantBalance{}
|
||||
|
||||
var state actors.StorageMarketState
|
||||
if _, err := a.StateManager.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cst := hamt.CSTFromBstore(a.StateManager.ChainStore().Blockstore())
|
||||
nd, err := hamt.LoadNode(ctx, cst, state.Balances)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = nd.ForEach(ctx, func(k string, val interface{}) error {
|
||||
cv := val.(*cbg.Deferred)
|
||||
a, err := address.NewFromBytes([]byte(k))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var b actors.StorageParticipantBalance
|
||||
if err := b.UnmarshalCBOR(bytes.NewReader(cv.Raw)); err != nil {
|
||||
return err
|
||||
}
|
||||
out[a.String()] = b
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMarketDeals(ctx context.Context, ts *types.TipSet) (map[string]actors.OnChainDeal, error) {
|
||||
out := map[string]actors.OnChainDeal{}
|
||||
|
||||
var state actors.StorageMarketState
|
||||
if _, err := a.StateManager.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
blks := amt.WrapBlockstore(a.StateManager.ChainStore().Blockstore())
|
||||
da, err := amt.LoadAMT(blks, state.Deals)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := da.ForEach(func(i uint64, v *cbg.Deferred) error {
|
||||
var d actors.OnChainDeal
|
||||
if err := d.UnmarshalCBOR(bytes.NewReader(v.Raw)); err != nil {
|
||||
return err
|
||||
}
|
||||
out[strconv.FormatInt(int64(i), 10)] = d
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
@@ -33,8 +33,9 @@ func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error
|
||||
func (sm *StorageMinerAPI) StoreGarbageData(ctx context.Context) (uint64, error) {
|
||||
size := sectorbuilder.UserBytesForSectorSize(build.SectorSize)
|
||||
|
||||
// TODO: create a deal
|
||||
name := fmt.Sprintf("fake-file-%d", rand.Intn(100000000))
|
||||
sectorId, err := sm.Sectors.AddPiece(name, size, io.LimitReader(rand.New(rand.NewSource(42)), int64(size)))
|
||||
sectorId, err := sm.Sectors.AddPiece(name, size, io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), 0)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -98,13 +98,13 @@ func HandleRetrieval(host host.Host, lc fx.Lifecycle, m *retrieval.Miner) {
|
||||
})
|
||||
}
|
||||
|
||||
func HandleDeals(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, h *deals.Handler) {
|
||||
func HandleDeals(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, h *deals.Provider) {
|
||||
ctx := helpers.LifecycleCtx(mctx, lc)
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStart: func(context.Context) error {
|
||||
h.Run(ctx)
|
||||
host.SetStreamHandler(deals.ProtocolID, h.HandleStream)
|
||||
host.SetStreamHandler(deals.DealProtocolID, h.HandleStream)
|
||||
host.SetStreamHandler(deals.AskProtocolID, h.HandleAskStream)
|
||||
return nil
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user