Merge pull request #415 from filecoin-project/feat/deals-on-chain

On-Chain deals
This commit is contained in:
Łukasz Magiera
2019-10-25 17:03:25 +02:00
committed by GitHub
70 changed files with 3774 additions and 1159 deletions
+1 -1
View File
@@ -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
View File
@@ -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,
}
}
+2
View File
@@ -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
View File
@@ -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
}
+2 -1
View File
@@ -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
}
+2 -2
View File
@@ -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
},