Merge branch 'bloxico/system-test-matrix' of https://github.com/filecoin-project/lotus into merge_lotus

This commit is contained in:
Darko Brdareski
2021-12-20 15:48:16 +01:00
343 changed files with 13836 additions and 4287 deletions
+8 -3
View File
@@ -19,7 +19,6 @@ import (
"github.com/libp2p/go-libp2p-core/peerstore"
"github.com/libp2p/go-libp2p-core/routing"
dht "github.com/libp2p/go-libp2p-kad-dht"
"github.com/libp2p/go-libp2p-peerstore/pstoremem"
pubsub "github.com/libp2p/go-libp2p-pubsub"
record "github.com/libp2p/go-libp2p-record"
"github.com/libp2p/go-libp2p/p2p/net/conngater"
@@ -162,6 +161,12 @@ func defaults() []Option {
}),
Override(new(dtypes.ShutdownChan), make(chan struct{})),
// the great context in the sky, otherwise we can't DI build genesis; there has to be a better
// solution than this hack.
Override(new(context.Context), func(lc fx.Lifecycle, mctx helpers.MetricsCtx) context.Context {
return helpers.LifecycleCtx(mctx, lc)
}),
}
}
@@ -170,14 +175,14 @@ var LibP2P = Options(
Override(new(dtypes.Bootstrapper), dtypes.Bootstrapper(false)),
// Host dependencies
Override(new(peerstore.Peerstore), pstoremem.NewPeerstore),
Override(new(peerstore.Peerstore), lp2p.Peerstore),
Override(PstoreAddSelfKeysKey, lp2p.PstoreAddSelfKeys),
Override(StartListeningKey, lp2p.StartListening(config.DefaultFullNode().Libp2p.ListenAddresses)),
// Host settings
Override(DefaultTransportsKey, lp2p.DefaultTransports),
Override(AddrsFactoryKey, lp2p.AddrsFactory(nil, nil)),
Override(SmuxTransportKey, lp2p.SmuxTransport(true)),
Override(SmuxTransportKey, lp2p.SmuxTransport()),
Override(RelayKey, lp2p.NoRelay()),
Override(SecurityKey, lp2p.Security(true, false)),
+3 -2
View File
@@ -136,7 +136,7 @@ func ConfigStorageMiner(c interface{}) Option {
If(cfg.Subsystems.EnableMarkets,
// Markets
Override(new(dtypes.StagingBlockstore), modules.StagingBlockstore),
Override(new(dtypes.StagingGraphsync), modules.StagingGraphsync(cfg.Dealmaking.SimultaneousTransfersForStorage, cfg.Dealmaking.SimultaneousTransfersForRetrieval)),
Override(new(dtypes.StagingGraphsync), modules.StagingGraphsync(cfg.Dealmaking.SimultaneousTransfersForStorage, cfg.Dealmaking.SimultaneousTransfersForStoragePerClient, cfg.Dealmaking.SimultaneousTransfersForRetrieval)),
Override(new(dtypes.ProviderPieceStore), modules.NewProviderPieceStore),
Override(new(*sectorblocks.SectorBlocks), sectorblocks.NewSectorBlocks),
@@ -155,7 +155,8 @@ func ConfigStorageMiner(c interface{}) Option {
Override(DAGStoreKey, modules.DAGStore),
// Markets (retrieval)
Override(new(retrievalmarket.SectorAccessor), sectoraccessor.NewSectorAccessor),
Override(new(dagstore.SectorAccessor), sectoraccessor.NewSectorAccessor),
Override(new(retrievalmarket.SectorAccessor), From(new(dagstore.SectorAccessor))),
Override(new(retrievalmarket.RetrievalProviderNode), retrievaladapter.NewRetrievalProviderNode),
Override(new(rmnet.RetrievalMarketNetwork), modules.RetrievalNetwork),
Override(new(retrievalmarket.RetrievalProvider), modules.RetrievalProvider),
+3 -2
View File
@@ -160,8 +160,9 @@ func DefaultStorageMiner() *StorageMiner {
MaxDealsPerPublishMsg: 8,
MaxProviderCollateralMultiplier: 2,
SimultaneousTransfersForStorage: DefaultSimultaneousTransfers,
SimultaneousTransfersForRetrieval: DefaultSimultaneousTransfers,
SimultaneousTransfersForStorage: DefaultSimultaneousTransfers,
SimultaneousTransfersForStoragePerClient: 0,
SimultaneousTransfersForRetrieval: DefaultSimultaneousTransfers,
StartEpochSealingBuffer: 480, // 480 epochs buffer == 4 hours from adding deal to sector to sector being sealed
+11
View File
@@ -272,6 +272,17 @@ passed to the sealing node by the markets service. 0 is unlimited.`,
Comment: `The maximum number of parallel online data transfers for storage deals`,
},
{
Name: "SimultaneousTransfersForStoragePerClient",
Type: "uint64",
Comment: `The maximum number of simultaneous data transfers from any single client
for storage deals.
Unset by default (0), and values higher than SimultaneousTransfersForStorage
will have no effect; i.e. the total number of simultaneous data transfers
across all storage clients is bound by SimultaneousTransfersForStorage
regardless of this number.`,
},
{
Name: "SimultaneousTransfersForRetrieval",
Type: "uint64",
+7
View File
@@ -131,6 +131,13 @@ type DealmakingConfig struct {
MaxStagingDealsBytes int64
// The maximum number of parallel online data transfers for storage deals
SimultaneousTransfersForStorage uint64
// The maximum number of simultaneous data transfers from any single client
// for storage deals.
// Unset by default (0), and values higher than SimultaneousTransfersForStorage
// will have no effect; i.e. the total number of simultaneous data transfers
// across all storage clients is bound by SimultaneousTransfersForStorage
// regardless of this number.
SimultaneousTransfersForStoragePerClient uint64
// The maximum number of parallel online data transfers for retrieval deals
SimultaneousTransfersForRetrieval uint64
// Minimum start epoch buffer to give time for sealing of sector with deal.
+1 -1
View File
@@ -141,7 +141,7 @@ func (hs *Service) SayHello(ctx context.Context, pid peer.ID) error {
return err
}
gen, err := hs.cs.GetGenesis()
gen, err := hs.cs.GetGenesis(ctx)
if err != nil {
return err
}
+3 -2
View File
@@ -1,6 +1,7 @@
package impl
import (
"context"
"os"
"path/filepath"
"strings"
@@ -12,7 +13,7 @@ import (
"github.com/filecoin-project/lotus/node/modules/dtypes"
)
func backup(mds dtypes.MetadataDS, fpath string) error {
func backup(ctx context.Context, mds dtypes.MetadataDS, fpath string) error {
bb, ok := os.LookupEnv("LOTUS_BACKUP_BASE_PATH")
if !ok {
return xerrors.Errorf("LOTUS_BACKUP_BASE_PATH env var not set")
@@ -52,7 +53,7 @@ func backup(mds dtypes.MetadataDS, fpath string) error {
return xerrors.Errorf("open %s: %w", fpath, err)
}
if err := bds.Backup(out); err != nil {
if err := bds.Backup(ctx, out); err != nil {
if cerr := out.Close(); cerr != nil {
log.Errorw("error closing backup file while handling backup error", "closeErr", cerr, "backupErr", err)
}
+354 -265
View File
@@ -4,17 +4,22 @@ import (
"bufio"
"bytes"
"context"
"errors"
"fmt"
"io"
"os"
"sort"
"strings"
"time"
bstore "github.com/ipfs/go-ipfs-blockstore"
format "github.com/ipfs/go-ipld-format"
unixfile "github.com/ipfs/go-unixfs/file"
"github.com/ipld/go-car"
"github.com/ipld/go-car/util"
carv2 "github.com/ipld/go-car/v2"
carv2bs "github.com/ipld/go-car/v2/blockstore"
"github.com/ipld/go-ipld-prime/datamodel"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-padreader"
@@ -58,7 +63,6 @@ import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/specs-actors/v3/actors/builtin/market"
marketevents "github.com/filecoin-project/lotus/markets/loggers"
"github.com/filecoin-project/lotus/node/config"
"github.com/filecoin-project/lotus/node/repo/imports"
@@ -146,7 +150,7 @@ func (a *API) dealStarter(ctx context.Context, params *api.StartDealParams, isSt
if err != nil {
return nil, xerrors.Errorf("failed to find blockstore for root CID: %w", err)
}
if has, err := bs.Has(params.Data.Root); err != nil {
if has, err := bs.Has(ctx, params.Data.Root); err != nil {
return nil, xerrors.Errorf("failed to query blockstore for root CID: %w", err)
} else if !has {
return nil, xerrors.Errorf("failed to find root CID in blockstore: %w", err)
@@ -516,7 +520,7 @@ func (a *API) ClientImport(ctx context.Context, ref api.FileRef) (res *api.Impor
}
defer f.Close() //nolint:errcheck
hd, _, err := car.ReadHeader(bufio.NewReader(f))
hd, err := car.ReadHeader(bufio.NewReader(f))
if err != nil {
return nil, xerrors.Errorf("failed to read CAR header: %w", err)
}
@@ -760,325 +764,405 @@ func (a *API) ClientCancelRetrievalDeal(ctx context.Context, dealID rm.DealID) e
}
}
func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error {
events := make(chan marketevents.RetrievalEvent)
go a.clientRetrieve(ctx, order, ref, events)
for {
select {
case evt, ok := <-events:
if !ok { // done successfully
return nil
}
if evt.Err != "" {
return xerrors.Errorf("retrieval failed: %s", evt.Err)
}
case <-ctx.Done():
return xerrors.Errorf("retrieval timed out")
}
}
}
func (a *API) ClientRetrieveWithEvents(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) (<-chan marketevents.RetrievalEvent, error) {
events := make(chan marketevents.RetrievalEvent)
go a.clientRetrieve(ctx, order, ref, events)
return events, nil
}
type retrievalSubscribeEvent struct {
event rm.ClientEvent
state rm.ClientDealState
}
func consumeAllEvents(ctx context.Context, dealID rm.DealID, subscribeEvents chan retrievalSubscribeEvent, events chan marketevents.RetrievalEvent) error {
for {
var subscribeEvent retrievalSubscribeEvent
select {
case <-ctx.Done():
return xerrors.New("Retrieval Timed Out")
case subscribeEvent = <-subscribeEvents:
if subscribeEvent.state.ID != dealID {
// we can't check the deal ID ahead of time because:
// 1. We need to subscribe before retrieving.
// 2. We won't know the deal ID until after retrieving.
continue
}
}
select {
case <-ctx.Done():
return xerrors.New("Retrieval Timed Out")
case events <- marketevents.RetrievalEvent{
Event: subscribeEvent.event,
Status: subscribeEvent.state.Status,
BytesReceived: subscribeEvent.state.TotalReceived,
FundsSpent: subscribeEvent.state.FundsSpent,
}:
}
state := subscribeEvent.state
switch state.Status {
case rm.DealStatusCompleted:
return nil
case rm.DealStatusRejected:
return xerrors.Errorf("Retrieval Proposal Rejected: %s", state.Message)
case rm.DealStatusCancelled:
return xerrors.Errorf("Retrieval was cancelled externally: %s", state.Message)
case
rm.DealStatusDealNotFound,
rm.DealStatusErrored:
return xerrors.Errorf("Retrieval Error: %s", state.Message)
}
}
}
func (a *API) clientRetrieve(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef, events chan marketevents.RetrievalEvent) {
defer close(events)
finish := func(e error) {
if e != nil {
events <- marketevents.RetrievalEvent{Err: e.Error(), FundsSpent: big.Zero()}
}
}
func getDataSelector(dps *api.Selector, matchPath bool) (datamodel.Node, error) {
sel := selectorparse.CommonSelector_ExploreAllRecursively
if order.DatamodelPathSelector != nil {
if dps != nil {
ssb := builder.NewSelectorSpecBuilder(basicnode.Prototype.Any)
if strings.HasPrefix(string(*dps), "{") {
var err error
sel, err = selectorparse.ParseJSONSelector(string(*dps))
if err != nil {
return nil, xerrors.Errorf("failed to parse json-selector '%s': %w", *dps, err)
}
} else {
ssb := builder.NewSelectorSpecBuilder(basicnode.Prototype.Any)
selspec, err := textselector.SelectorSpecFromPath(
selspec, err := textselector.SelectorSpecFromPath(
textselector.Expression(*dps), matchPath,
*order.DatamodelPathSelector,
ssb.ExploreRecursive(
selector.RecursionLimitNone(),
ssb.ExploreUnion(ssb.Matcher(), ssb.ExploreAll(ssb.ExploreRecursiveEdge())),
),
)
if err != nil {
return nil, xerrors.Errorf("failed to parse text-selector '%s': %w", *dps, err)
}
// URGH - this is a direct copy from https://github.com/filecoin-project/go-fil-markets/blob/v1.12.0/shared/selectors.go#L10-L16
// Unable to use it because we need the SelectorSpec, and markets exposes just a reified node
ssb.ExploreRecursive(
selector.RecursionLimitNone(),
ssb.ExploreAll(ssb.ExploreRecursiveEdge()),
),
)
if err != nil {
finish(xerrors.Errorf("failed to parse text-selector '%s': %w", *order.DatamodelPathSelector, err))
return
sel = selspec.Node()
log.Infof("partial retrieval of datamodel-path-selector %s/*", *dps)
}
sel = selspec.Node()
log.Infof("partial retrieval of datamodel-path-selector %s/*", *order.DatamodelPathSelector)
}
// summary:
// 1. if we're retrieving from an import, FromLocalCAR will be set.
// Skip the retrieval itself, and use the provided car as a blockstore further down
// to extract a CAR or UnixFS export from.
// 2. if we're using an IPFS blockstore for retrieval, retrieve into it,
// then use the virtual blockstore to extract a CAR or UnixFS export from it.
// 3. if we have to retrieve, perform a CARv2 retrieval, then either
// extract the CARv1 (with ExtractV1File) or use it as a blockstore further down.
return sel, nil
}
// this indicates we're proxying to IPFS.
func (a *API) ClientRetrieve(ctx context.Context, params api.RetrievalOrder) (*api.RestrievalRes, error) {
sel, err := getDataSelector(params.DataSelector, false)
if err != nil {
return nil, err
}
di, err := a.doRetrieval(ctx, params, sel)
if err != nil {
return nil, err
}
return &api.RestrievalRes{
DealID: di,
}, nil
}
func (a *API) doRetrieval(ctx context.Context, order api.RetrievalOrder, sel datamodel.Node) (rm.DealID, error) {
if order.MinerPeer == nil || order.MinerPeer.ID == "" {
mi, err := a.StateMinerInfo(ctx, order.Miner, types.EmptyTSK)
if err != nil {
return 0, err
}
order.MinerPeer = &rm.RetrievalPeer{
ID: *mi.PeerId,
Address: order.Miner,
}
}
if order.Total.Int == nil {
return 0, xerrors.Errorf("cannot make retrieval deal for null total")
}
if order.Size == 0 {
return 0, xerrors.Errorf("cannot make retrieval deal for zero bytes")
}
ppb := types.BigDiv(order.Total, types.NewInt(order.Size))
params, err := rm.NewParamsV1(ppb, order.PaymentInterval, order.PaymentIntervalIncrease, sel, order.Piece, order.UnsealPrice)
if err != nil {
return 0, xerrors.Errorf("Error in retrieval params: %s", err)
}
id := a.Retrieval.NextID()
id, err = a.Retrieval.Retrieve(
ctx,
id,
order.Root,
params,
order.Total,
*order.MinerPeer,
order.Client,
order.Miner,
)
if err != nil {
return 0, xerrors.Errorf("Retrieve failed: %w", err)
}
return id, nil
}
func (a *API) ClientRetrieveWait(ctx context.Context, deal rm.DealID) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
subscribeEvents := make(chan rm.ClientDealState, 1)
unsubscribe := a.Retrieval.SubscribeToEvents(func(event rm.ClientEvent, state rm.ClientDealState) {
// We'll check the deal IDs inside consumeAllEvents.
if state.ID != deal {
return
}
select {
case <-ctx.Done():
case subscribeEvents <- state:
}
})
defer unsubscribe()
{
state, err := a.Retrieval.GetDeal(deal)
if err != nil {
return xerrors.Errorf("getting deal state: %w", err)
}
select {
case subscribeEvents <- state:
default: // already have an event queued from the subscription
}
}
for {
select {
case <-ctx.Done():
return xerrors.New("Retrieval Timed Out")
case state := <-subscribeEvents:
switch state.Status {
case rm.DealStatusCompleted:
return nil
case rm.DealStatusRejected:
return xerrors.Errorf("Retrieval Proposal Rejected: %s", state.Message)
case rm.DealStatusCancelled:
return xerrors.Errorf("Retrieval was cancelled externally: %s", state.Message)
case
rm.DealStatusDealNotFound,
rm.DealStatusErrored:
return xerrors.Errorf("Retrieval Error: %s", state.Message)
}
}
}
}
type ExportDest struct {
Writer io.Writer
Path string
}
func (ed *ExportDest) doWrite(cb func(io.Writer) error) error {
if ed.Writer != nil {
return cb(ed.Writer)
}
f, err := os.OpenFile(ed.Path, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return err
}
if err := cb(f); err != nil {
_ = f.Close()
return err
}
return f.Close()
}
func (a *API) ClientExport(ctx context.Context, exportRef api.ExportRef, ref api.FileRef) error {
return a.ClientExportInto(ctx, exportRef, ref.IsCAR, ExportDest{Path: ref.Path})
}
func (a *API) ClientExportInto(ctx context.Context, exportRef api.ExportRef, car bool, dest ExportDest) error {
proxyBss, retrieveIntoIPFS := a.RtvlBlockstoreAccessor.(*retrievaladapter.ProxyBlockstoreAccessor)
carBss, retrieveIntoCAR := a.RtvlBlockstoreAccessor.(*retrievaladapter.CARBlockstoreAccessor)
carPath := exportRef.FromLocalCAR
carPath := order.FromLocalCAR
// we actually need to retrieve from the network
if carPath == "" {
if !retrieveIntoIPFS && !retrieveIntoCAR {
// we don't recognize the blockstore accessor.
finish(xerrors.Errorf("unsupported retrieval blockstore accessor"))
return
}
if order.MinerPeer == nil || order.MinerPeer.ID == "" {
mi, err := a.StateMinerInfo(ctx, order.Miner, types.EmptyTSK)
if err != nil {
finish(err)
return
}
order.MinerPeer = &rm.RetrievalPeer{
ID: *mi.PeerId,
Address: order.Miner,
}
}
if order.Total.Int == nil {
finish(xerrors.Errorf("cannot make retrieval deal for null total"))
return
}
if order.Size == 0 {
finish(xerrors.Errorf("cannot make retrieval deal for zero bytes"))
return
}
ppb := types.BigDiv(order.Total, types.NewInt(order.Size))
params, err := rm.NewParamsV1(ppb, order.PaymentInterval, order.PaymentIntervalIncrease, sel, order.Piece, order.UnsealPrice)
if err != nil {
finish(xerrors.Errorf("Error in retrieval params: %s", err))
return
}
// Subscribe to events before retrieving to avoid losing events.
subscribeEvents := make(chan retrievalSubscribeEvent, 1)
subscribeCtx, cancel := context.WithCancel(ctx)
defer cancel()
unsubscribe := a.Retrieval.SubscribeToEvents(func(event rm.ClientEvent, state rm.ClientDealState) {
// We'll check the deal IDs inside consumeAllEvents.
if state.PayloadCID.Equals(order.Root) {
select {
case <-subscribeCtx.Done():
case subscribeEvents <- retrievalSubscribeEvent{event, state}:
}
}
})
id := a.Retrieval.NextID()
id, err = a.Retrieval.Retrieve(
ctx,
id,
order.Root,
params,
order.Total,
*order.MinerPeer,
order.Client,
order.Miner,
)
if err != nil {
unsubscribe()
finish(xerrors.Errorf("Retrieve failed: %w", err))
return
}
err = consumeAllEvents(ctx, id, subscribeEvents, events)
unsubscribe()
if err != nil {
finish(xerrors.Errorf("Retrieve: %w", err))
return
return xerrors.Errorf("unsupported retrieval blockstore accessor")
}
if retrieveIntoCAR {
carPath = carBss.PathFor(id)
carPath = carBss.PathFor(exportRef.DealID)
}
}
if ref == nil {
// If ref is nil, it only fetches the data into the configured blockstore
// (if fetching from network).
finish(nil)
return
}
// determine where did the retrieval go
var retrievalBs bstore.Blockstore
if retrieveIntoIPFS {
retrievalBs = proxyBss.Blockstore
} else {
cbs, err := stores.ReadOnlyFilestore(carPath)
if err != nil {
finish(err)
return
return err
}
defer cbs.Close() //nolint:errcheck
retrievalBs = cbs
}
dserv := merkledag.NewDAGService(blockservice.New(retrievalBs, offline.Exchange(retrievalBs)))
// Are we outputting a CAR?
if ref.IsCAR {
if car {
// not IPFS and we do full selection - just extract the CARv1 from the CARv2 we stored the retrieval in
if !retrieveIntoIPFS && order.DatamodelPathSelector == nil {
finish(carv2.ExtractV1File(carPath, ref.Path))
return
if !retrieveIntoIPFS && len(exportRef.DAGs) == 0 && dest.Writer == nil {
return carv2.ExtractV1File(carPath, dest.Path)
}
// generating a CARv1 from the configured blockstore
f, err := os.OpenFile(ref.Path, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
finish(err)
return
}
err = car.NewSelectiveCar(
ctx,
retrievalBs,
[]car.Dag{{
Root: order.Root,
Selector: sel,
}},
car.MaxTraversalLinks(config.MaxTraversalLinks),
).Write(f)
if err != nil {
finish(err)
return
}
finish(f.Close())
return
}
// we are extracting a UnixFS file.
ds := merkledag.NewDAGService(blockservice.New(retrievalBs, offline.Exchange(retrievalBs)))
root := order.Root
roots, err := parseDagSpec(ctx, exportRef.Root, exportRef.DAGs, dserv, car)
if err != nil {
return xerrors.Errorf("parsing dag spec: %w", err)
}
if car {
return a.outputCAR(ctx, dserv, retrievalBs, exportRef.Root, roots, dest)
}
// if we used a selector - need to find the sub-root the user actually wanted to retrieve
if order.DatamodelPathSelector != nil {
if len(roots) != 1 {
return xerrors.Errorf("unixfs retrieval requires one root node, got %d", len(roots))
}
var subRootFound bool
return a.outputUnixFS(ctx, roots[0].root, dserv, dest)
}
// no err check - we just compiled this before starting, but now we do not wrap a `*`
selspec, _ := textselector.SelectorSpecFromPath(*order.DatamodelPathSelector, nil) //nolint:errcheck
func (a *API) outputCAR(ctx context.Context, ds format.DAGService, bs bstore.Blockstore, root cid.Cid, dags []dagSpec, dest ExportDest) error {
// generating a CARv1 from the configured blockstore
roots := make([]cid.Cid, len(dags))
for i, dag := range dags {
roots[i] = dag.root
}
return dest.doWrite(func(w io.Writer) error {
if err := car.WriteHeader(&car.CarHeader{
Roots: roots,
Version: 1,
}, w); err != nil {
return fmt.Errorf("failed to write car header: %s", err)
}
cs := cid.NewSet()
for _, dagSpec := range dags {
if err := utils.TraverseDag(
ctx,
ds,
root,
dagSpec.selector,
func(p traversal.Progress, n ipld.Node, r traversal.VisitReason) error {
if r == traversal.VisitReason_SelectionMatch {
var c cid.Cid
if p.LastBlock.Link == nil {
c = root
} else {
cidLnk, castOK := p.LastBlock.Link.(cidlink.Link)
if !castOK {
return xerrors.Errorf("cidlink cast unexpectedly failed on '%s'", p.LastBlock.Link)
}
c = cidLnk.Cid
}
if cs.Visit(c) {
nb, err := bs.Get(ctx, c)
if err != nil {
return xerrors.Errorf("getting block data: %w", err)
}
err = util.LdWrite(w, c.Bytes(), nb.RawData())
if err != nil {
return xerrors.Errorf("writing block data: %w", err)
}
}
return nil
}
return nil
},
); err != nil {
return xerrors.Errorf("error while traversing car dag: %w", err)
}
}
return nil
})
}
func (a *API) outputUnixFS(ctx context.Context, root cid.Cid, ds format.DAGService, dest ExportDest) error {
nd, err := ds.Get(ctx, root)
if err != nil {
return xerrors.Errorf("ClientRetrieve: %w", err)
}
file, err := unixfile.NewUnixfsFile(ctx, ds, nd)
if err != nil {
return xerrors.Errorf("ClientRetrieve: %w", err)
}
if dest.Writer == nil {
return files.WriteTo(file, dest.Path)
}
switch f := file.(type) {
case files.File:
_, err = io.Copy(dest.Writer, f)
if err != nil {
return err
}
return nil
default:
return fmt.Errorf("file type %T is not supported", nd)
}
}
type dagSpec struct {
root cid.Cid
selector ipld.Node
}
func parseDagSpec(ctx context.Context, root cid.Cid, dsp []api.DagSpec, ds format.DAGService, car bool) ([]dagSpec, error) {
if len(dsp) == 0 {
return []dagSpec{
{
root: root,
selector: nil,
},
}, nil
}
out := make([]dagSpec, len(dsp))
for i, spec := range dsp {
if spec.DataSelector == nil {
return nil, xerrors.Errorf("invalid DagSpec at position %d: `DataSelector` can not be nil", i)
}
// reify selector
var err error
out[i].selector, err = getDataSelector(spec.DataSelector, car && spec.ExportMerkleProof)
if err != nil {
return nil, err
}
// find the pointed-at root node within the containing ds
var rsn ipld.Node
if strings.HasPrefix(string(*spec.DataSelector), "{") {
var err error
rsn, err = selectorparse.ParseJSONSelector(string(*spec.DataSelector))
if err != nil {
return nil, xerrors.Errorf("failed to parse json-selector '%s': %w", *spec.DataSelector, err)
}
} else {
selspec, _ := textselector.SelectorSpecFromPath(textselector.Expression(*spec.DataSelector), car && spec.ExportMerkleProof, nil) //nolint:errcheck
rsn = selspec.Node()
}
var newRoot cid.Cid
var errHalt = errors.New("halt walk")
if err := utils.TraverseDag(
ctx,
ds,
root,
selspec.Node(),
rsn,
func(p traversal.Progress, n ipld.Node, r traversal.VisitReason) error {
if r == traversal.VisitReason_SelectionMatch {
if p.LastBlock.Path.String() != p.Path.String() {
if !car && p.LastBlock.Path.String() != p.Path.String() {
return xerrors.Errorf("unsupported selection path '%s' does not correspond to a block boundary (a.k.a. CID link)", p.Path.String())
}
if p.LastBlock.Link == nil {
// this is likely the root node that we've matched here
newRoot = root
return errHalt
}
cidLnk, castOK := p.LastBlock.Link.(cidlink.Link)
if !castOK {
return xerrors.Errorf("cidlink cast unexpectedly failed on '%s'", p.LastBlock.Link.String())
return xerrors.Errorf("cidlink cast unexpectedly failed on '%s'", p.LastBlock.Link)
}
root = cidLnk.Cid
subRootFound = true
newRoot = cidLnk.Cid
return errHalt
}
return nil
},
); err != nil {
finish(xerrors.Errorf("error while locating partial retrieval sub-root: %w", err))
return
); err != nil && err != errHalt {
return nil, xerrors.Errorf("error while locating partial retrieval sub-root: %w", err)
}
if !subRootFound {
finish(xerrors.Errorf("path selection '%s' does not match a node within %s", *order.DatamodelPathSelector, root))
return
if newRoot == cid.Undef {
return nil, xerrors.Errorf("path selection does not match a node within %s", root)
}
out[i].root = newRoot
}
nd, err := ds.Get(ctx, root)
if err != nil {
finish(xerrors.Errorf("ClientRetrieve: %w", err))
return
}
file, err := unixfile.NewUnixfsFile(ctx, ds, nd)
if err != nil {
finish(xerrors.Errorf("ClientRetrieve: %w", err))
return
}
finish(files.WriteTo(file, ref.Path))
return out, nil
}
func (a *API) ClientListRetrievals(ctx context.Context) ([]api.RetrievalInfo, error) {
@@ -1110,8 +1194,13 @@ func (a *API) ClientListRetrievals(ctx context.Context) ([]api.RetrievalInfo, er
func (a *API) ClientGetRetrievalUpdates(ctx context.Context) (<-chan api.RetrievalInfo, error) {
updates := make(chan api.RetrievalInfo)
unsub := a.Retrieval.SubscribeToEvents(func(_ rm.ClientEvent, deal rm.ClientDealState) {
updates <- a.newRetrievalInfo(ctx, deal)
unsub := a.Retrieval.SubscribeToEvents(func(evt rm.ClientEvent, deal rm.ClientDealState) {
update := a.newRetrievalInfo(ctx, deal)
update.Event = &evt
select {
case updates <- update:
case <-ctx.Done():
}
})
go func() {
@@ -1196,7 +1285,7 @@ func (a *API) ClientCalcCommP(ctx context.Context, inpath string) (*api.CommPRet
}
// check that the data is a car file; if it's not, retrieval won't work
_, _, err = car.ReadHeader(bufio.NewReader(rdr))
_, err = car.ReadHeader(bufio.NewReader(rdr))
if err != nil {
return nil, xerrors.Errorf("not a car file: %w", err)
}
+4 -5
View File
@@ -64,7 +64,7 @@ func TestImportLocal(t *testing.T) {
require.NoError(t, err)
require.True(t, local)
order := api.RetrievalOrder{
order := api.ExportRef{
Root: root,
FromLocalCAR: it.CARPath,
}
@@ -72,8 +72,7 @@ func TestImportLocal(t *testing.T) {
// retrieve as UnixFS.
out1 := filepath.Join(dir, "retrieval1.data") // as unixfs
out2 := filepath.Join(dir, "retrieval2.data") // as car
//stm: @CLIENT_RETRIEVAL_RETRIEVE_001
err = a.ClientRetrieve(ctx, order, &api.FileRef{
err = a.ClientExport(ctx, order, api.FileRef{
Path: out1,
})
require.NoError(t, err)
@@ -82,7 +81,7 @@ func TestImportLocal(t *testing.T) {
require.NoError(t, err)
require.Equal(t, b, outBytes)
err = a.ClientRetrieve(ctx, order, &api.FileRef{
err = a.ClientExport(ctx, order, api.FileRef{
Path: out2,
IsCAR: true,
})
@@ -112,7 +111,7 @@ func TestImportLocal(t *testing.T) {
// recreate the unixfs dag, and see if it matches the original file byte by byte
// import the car into a memory blockstore, then export the unixfs file.
bs := blockstore.NewBlockstore(datastore.NewMapDatastore())
_, err = car.LoadCar(bs, exported.DataReader())
_, err = car.LoadCar(ctx, bs, exported.DataReader())
require.NoError(t, err)
dag := merkledag.NewDAGService(blockservice.New(bs, offline.Exchange(bs)))
+1 -1
View File
@@ -42,7 +42,7 @@ type FullNodeAPI struct {
}
func (n *FullNodeAPI) CreateBackup(ctx context.Context, fpath string) error {
return backup(n.DS, fpath)
return backup(ctx, n.DS, fpath)
}
func (n *FullNodeAPI) NodeStatus(ctx context.Context, inclChainStatus bool) (status api.NodeStatus, err error) {
+27 -27
View File
@@ -99,11 +99,11 @@ func (m *ChainModule) ChainHead(context.Context) (*types.TipSet, error) {
}
func (a *ChainAPI) ChainGetBlock(ctx context.Context, msg cid.Cid) (*types.BlockHeader, error) {
return a.Chain.GetBlock(msg)
return a.Chain.GetBlock(ctx, msg)
}
func (m *ChainModule) ChainGetTipSet(ctx context.Context, key types.TipSetKey) (*types.TipSet, error) {
return m.Chain.LoadTipSet(key)
return m.Chain.LoadTipSet(ctx, key)
}
func (m *ChainModule) ChainGetPath(ctx context.Context, from, to types.TipSetKey) ([]*api.HeadChange, error) {
@@ -111,12 +111,12 @@ func (m *ChainModule) ChainGetPath(ctx context.Context, from, to types.TipSetKey
}
func (m *ChainModule) ChainGetBlockMessages(ctx context.Context, msg cid.Cid) (*api.BlockMessages, error) {
b, err := m.Chain.GetBlock(msg)
b, err := m.Chain.GetBlock(ctx, msg)
if err != nil {
return nil, err
}
bmsgs, smsgs, err := m.Chain.MessagesForBlock(b)
bmsgs, smsgs, err := m.Chain.MessagesForBlock(ctx, b)
if err != nil {
return nil, err
}
@@ -143,7 +143,7 @@ func (a *ChainAPI) ChainGetPath(ctx context.Context, from types.TipSetKey, to ty
}
func (a *ChainAPI) ChainGetParentMessages(ctx context.Context, bcid cid.Cid) ([]api.Message, error) {
b, err := a.Chain.GetBlock(bcid)
b, err := a.Chain.GetBlock(ctx, bcid)
if err != nil {
return nil, err
}
@@ -154,12 +154,12 @@ func (a *ChainAPI) ChainGetParentMessages(ctx context.Context, bcid cid.Cid) ([]
}
// TODO: need to get the number of messages better than this
pts, err := a.Chain.LoadTipSet(types.NewTipSetKey(b.Parents...))
pts, err := a.Chain.LoadTipSet(ctx, types.NewTipSetKey(b.Parents...))
if err != nil {
return nil, err
}
cm, err := a.Chain.MessagesForTipset(pts)
cm, err := a.Chain.MessagesForTipset(ctx, pts)
if err != nil {
return nil, err
}
@@ -176,7 +176,7 @@ func (a *ChainAPI) ChainGetParentMessages(ctx context.Context, bcid cid.Cid) ([]
}
func (a *ChainAPI) ChainGetParentReceipts(ctx context.Context, bcid cid.Cid) ([]*types.MessageReceipt, error) {
b, err := a.Chain.GetBlock(bcid)
b, err := a.Chain.GetBlock(ctx, bcid)
if err != nil {
return nil, err
}
@@ -186,19 +186,19 @@ func (a *ChainAPI) ChainGetParentReceipts(ctx context.Context, bcid cid.Cid) ([]
}
// TODO: need to get the number of messages better than this
pts, err := a.Chain.LoadTipSet(types.NewTipSetKey(b.Parents...))
pts, err := a.Chain.LoadTipSet(ctx, types.NewTipSetKey(b.Parents...))
if err != nil {
return nil, err
}
cm, err := a.Chain.MessagesForTipset(pts)
cm, err := a.Chain.MessagesForTipset(ctx, pts)
if err != nil {
return nil, err
}
var out []*types.MessageReceipt
for i := 0; i < len(cm); i++ {
r, err := a.Chain.GetParentReceipt(b, i)
r, err := a.Chain.GetParentReceipt(ctx, b, i)
if err != nil {
return nil, err
}
@@ -210,7 +210,7 @@ func (a *ChainAPI) ChainGetParentReceipts(ctx context.Context, bcid cid.Cid) ([]
}
func (a *ChainAPI) ChainGetMessagesInTipset(ctx context.Context, tsk types.TipSetKey) ([]api.Message, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, err
}
@@ -220,7 +220,7 @@ func (a *ChainAPI) ChainGetMessagesInTipset(ctx context.Context, tsk types.TipSe
return nil, nil
}
cm, err := a.Chain.MessagesForTipset(ts)
cm, err := a.Chain.MessagesForTipset(ctx, ts)
if err != nil {
return nil, err
}
@@ -237,7 +237,7 @@ func (a *ChainAPI) ChainGetMessagesInTipset(ctx context.Context, tsk types.TipSe
}
func (m *ChainModule) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -245,7 +245,7 @@ func (m *ChainModule) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpo
}
func (m *ChainModule) ChainGetTipSetAfterHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -253,7 +253,7 @@ func (m *ChainModule) ChainGetTipSetAfterHeight(ctx context.Context, h abi.Chain
}
func (m *ChainModule) ChainReadObj(ctx context.Context, obj cid.Cid) ([]byte, error) {
blk, err := m.ExposedBlockstore.Get(obj)
blk, err := m.ExposedBlockstore.Get(ctx, obj)
if err != nil {
return nil, xerrors.Errorf("blockstore get: %w", err)
}
@@ -262,11 +262,11 @@ func (m *ChainModule) ChainReadObj(ctx context.Context, obj cid.Cid) ([]byte, er
}
func (a *ChainAPI) ChainDeleteObj(ctx context.Context, obj cid.Cid) error {
return a.ExposedBlockstore.DeleteBlock(obj)
return a.ExposedBlockstore.DeleteBlock(ctx, obj)
}
func (m *ChainModule) ChainHasObj(ctx context.Context, obj cid.Cid) (bool, error) {
return m.ExposedBlockstore.Has(obj)
return m.ExposedBlockstore.Has(ctx, obj)
}
func (a *ChainAPI) ChainStatObj(ctx context.Context, obj cid.Cid, base cid.Cid) (api.ObjStat, error) {
@@ -318,7 +318,7 @@ func (a *ChainAPI) ChainStatObj(ctx context.Context, obj cid.Cid, base cid.Cid)
}
func (a *ChainAPI) ChainSetHead(ctx context.Context, tsk types.TipSetKey) error {
newHeadTs, err := a.Chain.GetTipSetFromKey(tsk)
newHeadTs, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -342,11 +342,11 @@ func (a *ChainAPI) ChainSetHead(ctx context.Context, tsk types.TipSetKey) error
}
}
return a.Chain.SetHead(newHeadTs)
return a.Chain.SetHead(ctx, newHeadTs)
}
func (a *ChainAPI) ChainGetGenesis(ctx context.Context) (*types.TipSet, error) {
genb, err := a.Chain.GetGenesis()
genb, err := a.Chain.GetGenesis(ctx)
if err != nil {
return nil, err
}
@@ -355,7 +355,7 @@ func (a *ChainAPI) ChainGetGenesis(ctx context.Context) (*types.TipSet, error) {
}
func (a *ChainAPI) ChainTipSetWeight(ctx context.Context, tsk types.TipSetKey) (types.BigInt, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return types.EmptyInt, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -434,7 +434,7 @@ func resolveOnce(bs blockstore.Blockstore, tse stmgr.Executor) func(ctx context.
return nil, nil, err
}
if err := bs.Put(n); err != nil {
if err := bs.Put(ctx, n); err != nil {
return nil, nil, xerrors.Errorf("put hamt val: %w", err)
}
@@ -482,7 +482,7 @@ func resolveOnce(bs blockstore.Blockstore, tse stmgr.Executor) func(ctx context.
return nil, nil, err
}
if err := bs.Put(n); err != nil {
if err := bs.Put(ctx, n); err != nil {
return nil, nil, xerrors.Errorf("put amt val: %w", err)
}
@@ -530,7 +530,7 @@ func resolveOnce(bs blockstore.Blockstore, tse stmgr.Executor) func(ctx context.
return nil, nil, err
}
if err := bs.Put(n); err != nil {
if err := bs.Put(ctx, n); err != nil {
return nil, nil, xerrors.Errorf("put amt val: %w", err)
}
@@ -577,7 +577,7 @@ func (a *ChainAPI) ChainGetNode(ctx context.Context, p string) (*api.IpldObject,
}
func (m *ChainModule) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) {
cm, err := m.Chain.GetCMessage(mc)
cm, err := m.Chain.GetCMessage(ctx, mc)
if err != nil {
return nil, err
}
@@ -586,7 +586,7 @@ func (m *ChainModule) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.M
}
func (a *ChainAPI) ChainExport(ctx context.Context, nroots abi.ChainEpoch, skipoldmsgs bool, tsk types.TipSetKey) (<-chan []byte, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
+10 -10
View File
@@ -82,14 +82,14 @@ type GasMeta struct {
Limit int64
}
func (g *GasPriceCache) GetTSGasStats(cstore *store.ChainStore, ts *types.TipSet) ([]GasMeta, error) {
func (g *GasPriceCache) GetTSGasStats(ctx context.Context, cstore *store.ChainStore, ts *types.TipSet) ([]GasMeta, error) {
i, has := g.c.Get(ts.Key())
if has {
return i.([]GasMeta), nil
}
var prices []GasMeta
msgs, err := cstore.MessagesForTipset(ts)
msgs, err := cstore.MessagesForTipset(ctx, ts)
if err != nil {
return nil, xerrors.Errorf("loading messages: %w", err)
}
@@ -173,7 +173,7 @@ func (a *GasAPI) GasEstimateGasPremium(
gaslimit int64,
_ types.TipSetKey,
) (types.BigInt, error) {
return gasEstimateGasPremium(a.Chain, a.PriceCache, nblocksincl)
return gasEstimateGasPremium(ctx, a.Chain, a.PriceCache, nblocksincl)
}
func (m *GasModule) GasEstimateGasPremium(
ctx context.Context,
@@ -182,9 +182,9 @@ func (m *GasModule) GasEstimateGasPremium(
gaslimit int64,
_ types.TipSetKey,
) (types.BigInt, error) {
return gasEstimateGasPremium(m.Chain, m.PriceCache, nblocksincl)
return gasEstimateGasPremium(ctx, m.Chain, m.PriceCache, nblocksincl)
}
func gasEstimateGasPremium(cstore *store.ChainStore, cache *GasPriceCache, nblocksincl uint64) (types.BigInt, error) {
func gasEstimateGasPremium(ctx context.Context, cstore *store.ChainStore, cache *GasPriceCache, nblocksincl uint64) (types.BigInt, error) {
if nblocksincl == 0 {
nblocksincl = 1
}
@@ -198,13 +198,13 @@ func gasEstimateGasPremium(cstore *store.ChainStore, cache *GasPriceCache, nbloc
break // genesis
}
pts, err := cstore.LoadTipSet(ts.Parents())
pts, err := cstore.LoadTipSet(ctx, ts.Parents())
if err != nil {
return types.BigInt{}, err
}
blocks += len(pts.Blocks())
meta, err := cache.GetTSGasStats(cstore, pts)
meta, err := cache.GetTSGasStats(ctx, cstore, pts)
if err != nil {
return types.BigInt{}, err
}
@@ -236,14 +236,14 @@ func gasEstimateGasPremium(cstore *store.ChainStore, cache *GasPriceCache, nbloc
}
func (a *GasAPI) GasEstimateGasLimit(ctx context.Context, msgIn *types.Message, tsk types.TipSetKey) (int64, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return -1, xerrors.Errorf("getting tipset: %w", err)
}
return gasEstimateGasLimit(ctx, a.Chain, a.Stmgr, a.Mpool, msgIn, ts)
}
func (m *GasModule) GasEstimateGasLimit(ctx context.Context, msgIn *types.Message, tsk types.TipSetKey) (int64, error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return -1, xerrors.Errorf("getting tipset: %w", err)
}
@@ -283,7 +283,7 @@ func gasEstimateGasLimit(
if err != stmgr.ErrExpensiveFork {
break
}
ts, err = cstore.GetTipSetFromKey(ts.Parents())
ts, err = cstore.GetTipSetFromKey(ctx, ts.Parents())
if err != nil {
return -1, xerrors.Errorf("getting parent tipset: %w", err)
}
+6 -6
View File
@@ -51,11 +51,11 @@ func (a *MpoolAPI) MpoolGetConfig(context.Context) (*types.MpoolConfig, error) {
}
func (a *MpoolAPI) MpoolSetConfig(ctx context.Context, cfg *types.MpoolConfig) error {
return a.Mpool.SetConfig(cfg)
return a.Mpool.SetConfig(ctx, cfg)
}
func (a *MpoolAPI) MpoolSelect(ctx context.Context, tsk types.TipSetKey, ticketQuality float64) ([]*types.SignedMessage, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -64,7 +64,7 @@ func (a *MpoolAPI) MpoolSelect(ctx context.Context, tsk types.TipSetKey, ticketQ
}
func (a *MpoolAPI) MpoolPending(ctx context.Context, tsk types.TipSetKey) ([]*types.SignedMessage, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -87,7 +87,7 @@ func (a *MpoolAPI) MpoolPending(ctx context.Context, tsk types.TipSetKey) ([]*ty
// different blocks in tipsets of the same height
// we exclude messages that have been included in blocks in the mpool tipset
have, err := a.Mpool.MessagesForBlocks(mpts.Blocks())
have, err := a.Mpool.MessagesForBlocks(ctx, mpts.Blocks())
if err != nil {
return nil, xerrors.Errorf("getting messages for base ts: %w", err)
}
@@ -97,7 +97,7 @@ func (a *MpoolAPI) MpoolPending(ctx context.Context, tsk types.TipSetKey) ([]*ty
}
}
msgs, err := a.Mpool.MessagesForBlocks(ts.Blocks())
msgs, err := a.Mpool.MessagesForBlocks(ctx, ts.Blocks())
if err != nil {
return nil, xerrors.Errorf(": %w", err)
}
@@ -115,7 +115,7 @@ func (a *MpoolAPI) MpoolPending(ctx context.Context, tsk types.TipSetKey) ([]*ty
return pending, nil
}
ts, err = a.Chain.LoadTipSet(ts.Parents())
ts, err = a.Chain.LoadTipSet(ctx, ts.Parents())
if err != nil {
return nil, xerrors.Errorf("loading parent tipset: %w", err)
}
+7 -3
View File
@@ -100,7 +100,7 @@ func (a *MsigAPI) MsigAddCancel(ctx context.Context, msig address.Address, src a
return nil, actErr
}
return a.MsigCancel(ctx, msig, txID, msig, big.Zero(), src, uint64(multisig.Methods.AddSigner), enc)
return a.MsigCancelTxnHash(ctx, msig, txID, msig, big.Zero(), src, uint64(multisig.Methods.AddSigner), enc)
}
func (a *MsigAPI) MsigSwapPropose(ctx context.Context, msig address.Address, src address.Address, oldAdd address.Address, newAdd address.Address) (*api.MessagePrototype, error) {
@@ -127,7 +127,7 @@ func (a *MsigAPI) MsigSwapCancel(ctx context.Context, msig address.Address, src
return nil, actErr
}
return a.MsigCancel(ctx, msig, txID, msig, big.Zero(), src, uint64(multisig.Methods.SwapSigner), enc)
return a.MsigCancelTxnHash(ctx, msig, txID, msig, big.Zero(), src, uint64(multisig.Methods.SwapSigner), enc)
}
func (a *MsigAPI) MsigApprove(ctx context.Context, msig address.Address, txID uint64, src address.Address) (*api.MessagePrototype, error) {
@@ -138,7 +138,11 @@ func (a *MsigAPI) MsigApproveTxnHash(ctx context.Context, msig address.Address,
return a.msigApproveOrCancelTxnHash(ctx, api.MsigApprove, msig, txID, proposer, to, amt, src, method, params)
}
func (a *MsigAPI) MsigCancel(ctx context.Context, msig address.Address, txID uint64, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (*api.MessagePrototype, error) {
func (a *MsigAPI) MsigCancel(ctx context.Context, msig address.Address, txID uint64, src address.Address) (*api.MessagePrototype, error) {
return a.msigApproveOrCancelSimple(ctx, api.MsigCancel, msig, txID, src)
}
func (a *MsigAPI) MsigCancelTxnHash(ctx context.Context, msig address.Address, txID uint64, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (*api.MessagePrototype, error) {
return a.msigApproveOrCancelTxnHash(ctx, api.MsigCancel, msig, txID, src, to, amt, src, method, params)
}
+40 -40
View File
@@ -132,7 +132,7 @@ func (a *StateAPI) StateMinerActiveSectors(ctx context.Context, maddr address.Ad
}
func (m *StateModule) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return miner.MinerInfo{}, xerrors.Errorf("failed to load tipset: %w", err)
}
@@ -250,7 +250,7 @@ func (a *StateAPI) StateMinerPartitions(ctx context.Context, m address.Address,
}
func (m *StateModule) StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -345,7 +345,7 @@ func (a *StateAPI) StateMinerRecoveries(ctx context.Context, addr address.Addres
}
func (m *StateModule) StateMinerPower(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*api.MinerPower, error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -363,7 +363,7 @@ func (m *StateModule) StateMinerPower(ctx context.Context, addr address.Address,
}
func (a *StateAPI) StateCall(ctx context.Context, msg *types.Message, tsk types.TipSetKey) (res *api.InvocResult, err error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -372,7 +372,7 @@ func (a *StateAPI) StateCall(ctx context.Context, msg *types.Message, tsk types.
if err != stmgr.ErrExpensiveFork {
break
}
ts, err = a.Chain.GetTipSetFromKey(ts.Parents())
ts, err = a.Chain.GetTipSetFromKey(ctx, ts.Parents())
if err != nil {
return nil, xerrors.Errorf("getting parent tipset: %w", err)
}
@@ -395,17 +395,17 @@ func (a *StateAPI) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid.
msgToReplay = mlkp.Message
executionTs, err := a.Chain.GetTipSetFromKey(mlkp.TipSet)
executionTs, err := a.Chain.GetTipSetFromKey(ctx, mlkp.TipSet)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", mlkp.TipSet, err)
}
ts, err = a.Chain.LoadTipSet(executionTs.Parents())
ts, err = a.Chain.LoadTipSet(ctx, executionTs.Parents())
if err != nil {
return nil, xerrors.Errorf("loading parent tipset %s: %w", mlkp.TipSet, err)
}
} else {
ts, err = a.Chain.LoadTipSet(tsk)
ts, err = a.Chain.LoadTipSet(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading specified tipset %s: %w", tsk, err)
}
@@ -433,7 +433,7 @@ func (a *StateAPI) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid.
}
func (m *StateModule) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (a *types.Actor, err error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -441,7 +441,7 @@ func (m *StateModule) StateGetActor(ctx context.Context, actor address.Address,
}
func (m *StateModule) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return address.Undef, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -450,7 +450,7 @@ func (m *StateModule) StateLookupID(ctx context.Context, addr address.Address, t
}
func (m *StateModule) StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return address.Undef, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -459,7 +459,7 @@ func (m *StateModule) StateAccountKey(ctx context.Context, addr address.Address,
}
func (a *StateAPI) StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -468,7 +468,7 @@ func (a *StateAPI) StateReadState(ctx context.Context, actor address.Address, ts
return nil, xerrors.Errorf("getting actor: %w", err)
}
blk, err := a.Chain.StateBlockstore().Get(act.Head)
blk, err := a.Chain.StateBlockstore().Get(ctx, act.Head)
if err != nil {
return nil, xerrors.Errorf("getting actor head: %w", err)
}
@@ -556,7 +556,7 @@ func (m *StateModule) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence
var returndec interface{}
if recpt.ExitCode == 0 && len(recpt.Return) > 0 {
cmsg, err := m.Chain.GetCMessage(msg)
cmsg, err := m.Chain.GetCMessage(ctx, msg)
if err != nil {
return nil, xerrors.Errorf("failed to load message after successful receipt search: %w", err)
}
@@ -585,7 +585,7 @@ func (m *StateModule) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence
}
func (m *StateModule) StateSearchMsg(ctx context.Context, tsk types.TipSetKey, msg cid.Cid, lookbackLimit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) {
fromTs, err := m.Chain.GetTipSetFromKey(tsk)
fromTs, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -607,7 +607,7 @@ func (m *StateModule) StateSearchMsg(ctx context.Context, tsk types.TipSetKey, m
}
func (m *StateModule) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -615,7 +615,7 @@ func (m *StateModule) StateListMiners(ctx context.Context, tsk types.TipSetKey)
}
func (a *StateAPI) StateListActors(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -623,7 +623,7 @@ func (a *StateAPI) StateListActors(ctx context.Context, tsk types.TipSetKey) ([]
}
func (m *StateModule) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return api.MarketBalance{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -633,7 +633,7 @@ func (m *StateModule) StateMarketBalance(ctx context.Context, addr address.Addre
func (a *StateAPI) StateMarketParticipants(ctx context.Context, tsk types.TipSetKey) (map[string]api.MarketBalance, error) {
out := map[string]api.MarketBalance{}
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -673,7 +673,7 @@ func (a *StateAPI) StateMarketParticipants(ctx context.Context, tsk types.TipSet
func (a *StateAPI) StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (map[string]api.MarketDeal, error) {
out := map[string]api.MarketDeal{}
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -712,7 +712,7 @@ func (a *StateAPI) StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (m
}
func (m *StateModule) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -777,7 +777,7 @@ func (a *StateAPI) StateMinerSectorCount(ctx context.Context, addr address.Addre
}
func (a *StateAPI) StateSectorPreCommitInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return miner.SectorPreCommitOnChainInfo{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -793,7 +793,7 @@ func (a *StateAPI) StateSectorPreCommitInfo(ctx context.Context, maddr address.A
}
func (m *StateModule) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -825,7 +825,7 @@ func (a *StateAPI) StateSectorPartition(ctx context.Context, maddr address.Addre
}
func (a *StateAPI) StateListMessages(ctx context.Context, match *api.MessageMatch, tsk types.TipSetKey, toheight abi.ChainEpoch) ([]cid.Cid, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -874,7 +874,7 @@ func (a *StateAPI) StateListMessages(ctx context.Context, match *api.MessageMatc
var out []cid.Cid
for ts.Height() >= toheight {
msgs, err := a.Chain.MessagesForTipset(ts)
msgs, err := a.Chain.MessagesForTipset(ctx, ts)
if err != nil {
return nil, xerrors.Errorf("failed to get messages for tipset (%s): %w", ts.Key(), err)
}
@@ -889,7 +889,7 @@ func (a *StateAPI) StateListMessages(ctx context.Context, match *api.MessageMatc
break
}
next, err := a.Chain.LoadTipSet(ts.Parents())
next, err := a.Chain.LoadTipSet(ctx, ts.Parents())
if err != nil {
return nil, xerrors.Errorf("loading next tipset: %w", err)
}
@@ -901,7 +901,7 @@ func (a *StateAPI) StateListMessages(ctx context.Context, match *api.MessageMatc
}
func (a *StateAPI) StateCompute(ctx context.Context, height abi.ChainEpoch, msgs []*types.Message, tsk types.TipSetKey) (*api.ComputeStateOutput, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -917,7 +917,7 @@ func (a *StateAPI) StateCompute(ctx context.Context, height abi.ChainEpoch, msgs
}
func (m *StateModule) MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return types.EmptyInt, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -938,7 +938,7 @@ func (m *StateModule) MsigGetAvailableBalance(ctx context.Context, addr address.
}
func (a *StateAPI) MsigGetVestingSchedule(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MsigVesting, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return api.EmptyVesting, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -976,12 +976,12 @@ func (a *StateAPI) MsigGetVestingSchedule(ctx context.Context, addr address.Addr
}
func (m *StateModule) MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error) {
startTs, err := m.Chain.GetTipSetFromKey(start)
startTs, err := m.Chain.GetTipSetFromKey(ctx, start)
if err != nil {
return types.EmptyInt, xerrors.Errorf("loading start tipset %s: %w", start, err)
}
endTs, err := m.Chain.GetTipSetFromKey(end)
endTs, err := m.Chain.GetTipSetFromKey(ctx, end)
if err != nil {
return types.EmptyInt, xerrors.Errorf("loading end tipset %s: %w", end, err)
}
@@ -1016,7 +1016,7 @@ func (m *StateModule) MsigGetVested(ctx context.Context, addr address.Address, s
}
func (m *StateModule) MsigGetPending(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*api.MsigTransaction, error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -1053,7 +1053,7 @@ var initialPledgeNum = types.NewInt(110)
var initialPledgeDen = types.NewInt(100)
func (a *StateAPI) StateMinerPreCommitDepositForPower(ctx context.Context, maddr address.Address, pci miner.SectorPreCommitInfo, tsk types.TipSetKey) (types.BigInt, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return types.EmptyInt, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -1114,7 +1114,7 @@ func (a *StateAPI) StateMinerPreCommitDepositForPower(ctx context.Context, maddr
func (a *StateAPI) StateMinerInitialPledgeCollateral(ctx context.Context, maddr address.Address, pci miner.SectorPreCommitInfo, tsk types.TipSetKey) (types.BigInt, error) {
// TODO: this repeats a lot of the previous function. Fix that.
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return types.EmptyInt, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -1190,7 +1190,7 @@ func (a *StateAPI) StateMinerInitialPledgeCollateral(ctx context.Context, maddr
}
func (a *StateAPI) StateMinerAvailableBalance(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (types.BigInt, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return types.EmptyInt, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -1219,7 +1219,7 @@ func (a *StateAPI) StateMinerAvailableBalance(ctx context.Context, maddr address
}
func (a *StateAPI) StateMinerSectorAllocated(ctx context.Context, maddr address.Address, s abi.SectorNumber, tsk types.TipSetKey) (bool, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return false, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -1319,7 +1319,7 @@ var dealProviderCollateralDen = types.NewInt(100)
// StateDealProviderCollateralBounds returns the min and max collateral a storage provider
// can issue. It takes the deal size and verified status as parameters.
func (m *StateModule) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return api.DealCollateralBounds{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -1376,7 +1376,7 @@ func (m *StateModule) StateDealProviderCollateralBounds(ctx context.Context, siz
}
func (a *StateAPI) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (abi.TokenAmount, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return types.EmptyInt, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -1397,7 +1397,7 @@ func stateVMCirculatingSupplyInternal(
cstore *store.ChainStore,
smgr *stmgr.StateManager,
) (api.CirculatingSupply, error) {
ts, err := cstore.GetTipSetFromKey(tsk)
ts, err := cstore.GetTipSetFromKey(ctx, tsk)
if err != nil {
return api.CirculatingSupply{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -1411,7 +1411,7 @@ func stateVMCirculatingSupplyInternal(
}
func (m *StateModule) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (network.Version, error) {
ts, err := m.Chain.GetTipSetFromKey(tsk)
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return network.VersionMax, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
+6 -6
View File
@@ -51,25 +51,25 @@ func (a *SyncAPI) SyncState(ctx context.Context) (*api.SyncState, error) {
}
func (a *SyncAPI) SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error {
parent, err := a.Syncer.ChainStore().GetBlock(blk.Header.Parents[0])
parent, err := a.Syncer.ChainStore().GetBlock(ctx, blk.Header.Parents[0])
if err != nil {
return xerrors.Errorf("loading parent block: %w", err)
}
if a.SlashFilter != nil {
if err := a.SlashFilter.MinedBlock(blk.Header, parent.Height); err != nil {
if err := a.SlashFilter.MinedBlock(ctx, blk.Header, parent.Height); err != nil {
log.Errorf("<!!> SLASH FILTER ERROR: %s", err)
return xerrors.Errorf("<!!> SLASH FILTER ERROR: %w", err)
}
}
// TODO: should we have some sort of fast path to adding a local block?
bmsgs, err := a.Syncer.ChainStore().LoadMessagesFromCids(blk.BlsMessages)
bmsgs, err := a.Syncer.ChainStore().LoadMessagesFromCids(ctx, blk.BlsMessages)
if err != nil {
return xerrors.Errorf("failed to load bls messages: %w", err)
}
smsgs, err := a.Syncer.ChainStore().LoadSignedMessagesFromCids(blk.SecpkMessages)
smsgs, err := a.Syncer.ChainStore().LoadSignedMessagesFromCids(ctx, blk.SecpkMessages)
if err != nil {
return xerrors.Errorf("failed to load secpk message: %w", err)
}
@@ -137,12 +137,12 @@ func (a *SyncAPI) SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error
}
func (a *SyncAPI) SyncValidateTipset(ctx context.Context, tsk types.TipSetKey) (bool, error) {
ts, err := a.Syncer.ChainStore().LoadTipSet(tsk)
ts, err := a.Syncer.ChainStore().LoadTipSet(ctx, tsk)
if err != nil {
return false, err
}
fts, err := a.Syncer.ChainStore().TryFillTipSet(ts)
fts, err := a.Syncer.ChainStore().TryFillTipSet(ctx, ts)
if err != nil {
return false, err
}
+6 -6
View File
@@ -35,11 +35,11 @@ func (a *PaychAPI) PaychGet(ctx context.Context, from, to address.Address, amt t
}
func (a *PaychAPI) PaychAvailableFunds(ctx context.Context, ch address.Address) (*api.ChannelAvailableFunds, error) {
return a.PaychMgr.AvailableFunds(ch)
return a.PaychMgr.AvailableFunds(ctx, ch)
}
func (a *PaychAPI) PaychAvailableFundsByFromTo(ctx context.Context, from, to address.Address) (*api.ChannelAvailableFunds, error) {
return a.PaychMgr.AvailableFundsByFromTo(from, to)
return a.PaychMgr.AvailableFundsByFromTo(ctx, from, to)
}
func (a *PaychAPI) PaychGetWaitReady(ctx context.Context, sentinel cid.Cid) (address.Address, error) {
@@ -47,7 +47,7 @@ func (a *PaychAPI) PaychGetWaitReady(ctx context.Context, sentinel cid.Cid) (add
}
func (a *PaychAPI) PaychAllocateLane(ctx context.Context, ch address.Address) (uint64, error) {
return a.PaychMgr.AllocateLane(ch)
return a.PaychMgr.AllocateLane(ctx, ch)
}
func (a *PaychAPI) PaychNewPayment(ctx context.Context, from, to address.Address, vouchers []api.VoucherSpec) (*api.PaymentInfo, error) {
@@ -60,7 +60,7 @@ func (a *PaychAPI) PaychNewPayment(ctx context.Context, from, to address.Address
return nil, err
}
lane, err := a.PaychMgr.AllocateLane(ch.Channel)
lane, err := a.PaychMgr.AllocateLane(ctx, ch.Channel)
if err != nil {
return nil, err
}
@@ -95,11 +95,11 @@ func (a *PaychAPI) PaychNewPayment(ctx context.Context, from, to address.Address
}
func (a *PaychAPI) PaychList(ctx context.Context) ([]address.Address, error) {
return a.PaychMgr.ListChannels()
return a.PaychMgr.ListChannels(ctx)
}
func (a *PaychAPI) PaychStatus(ctx context.Context, pch address.Address) (*api.PaychStatus, error) {
ci, err := a.PaychMgr.GetChannelInfo(pch)
ci, err := a.PaychMgr.GetChannelInfo(ctx, pch)
if err != nil {
return nil, err
}
+3 -3
View File
@@ -300,11 +300,11 @@ func (sm *StorageMinerAPI) StorageLocal(ctx context.Context) (map[stores.ID]stri
return out, nil
}
func (sm *StorageMinerAPI) SectorsRefs(context.Context) (map[string][]api.SealedRef, error) {
func (sm *StorageMinerAPI) SectorsRefs(ctx context.Context) (map[string][]api.SealedRef, error) {
// json can't handle cids as map keys
out := map[string][]api.SealedRef{}
refs, err := sm.SectorBlocks.List()
refs, err := sm.SectorBlocks.List(ctx)
if err != nil {
return nil, err
}
@@ -948,7 +948,7 @@ func (sm *StorageMinerAPI) PiecesGetCIDInfo(ctx context.Context, payloadCid cid.
}
func (sm *StorageMinerAPI) CreateBackup(ctx context.Context, fpath string) error {
return backup(sm.DS, fpath)
return backup(ctx, sm.DS, fpath)
}
func (sm *StorageMinerAPI) CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []sto.SectorRef, expensive bool) (map[abi.SectorNumber]string, error) {
+7 -5
View File
@@ -30,7 +30,7 @@ import (
)
// ChainBitswap uses a blockstore that bypasses all caches.
func ChainBitswap(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, rt routing.Routing, bs dtypes.ExposedBlockstore) dtypes.ChainBitswap {
func ChainBitswap(lc fx.Lifecycle, mctx helpers.MetricsCtx, host host.Host, rt routing.Routing, bs dtypes.ExposedBlockstore) dtypes.ChainBitswap {
// prefix protocol for chain bitswap
// (so bitswap uses /chain/ipfs/bitswap/1.0.0 internally for chain sync stuff)
bitswapNetwork := network.NewFromIpfsHost(host, rt, network.Prefix("/chain"))
@@ -58,8 +58,8 @@ func ChainBlockService(bs dtypes.ExposedBlockstore, rem dtypes.ChainBitswap) dty
return blockservice.New(bs, rem)
}
func MessagePool(lc fx.Lifecycle, us stmgr.UpgradeSchedule, mpp messagepool.Provider, ds dtypes.MetadataDS, nn dtypes.NetworkName, j journal.Journal, protector dtypes.GCReferenceProtector) (*messagepool.MessagePool, error) {
mp, err := messagepool.New(mpp, ds, us, nn, j)
func MessagePool(lc fx.Lifecycle, mctx helpers.MetricsCtx, us stmgr.UpgradeSchedule, mpp messagepool.Provider, ds dtypes.MetadataDS, nn dtypes.NetworkName, j journal.Journal, protector dtypes.GCReferenceProtector) (*messagepool.MessagePool, error) {
mp, err := messagepool.New(helpers.LifecycleCtx(mctx, lc), mpp, ds, us, nn, j)
if err != nil {
return nil, xerrors.Errorf("constructing mpool: %w", err)
}
@@ -73,23 +73,25 @@ func MessagePool(lc fx.Lifecycle, us stmgr.UpgradeSchedule, mpp messagepool.Prov
}
func ChainStore(lc fx.Lifecycle,
mctx helpers.MetricsCtx,
cbs dtypes.ChainBlockstore,
sbs dtypes.StateBlockstore,
ds dtypes.MetadataDS,
basebs dtypes.BaseBlockstore,
weight store.WeightFunc,
us stmgr.UpgradeSchedule,
j journal.Journal) *store.ChainStore {
chain := store.NewChainStore(cbs, sbs, ds, weight, j)
if err := chain.Load(); err != nil {
if err := chain.Load(helpers.LifecycleCtx(mctx, lc)); err != nil {
log.Warnf("loading chain state from disk: %s", err)
}
var startHook func(context.Context) error
if ss, ok := basebs.(*splitstore.SplitStore); ok {
startHook = func(_ context.Context) error {
err := ss.Start(chain)
err := ss.Start(chain, us)
if err != nil {
err = xerrors.Errorf("error starting splitstore: %w", err)
}
+4 -3
View File
@@ -40,11 +40,12 @@ import (
"github.com/filecoin-project/lotus/node/impl/full"
payapi "github.com/filecoin-project/lotus/node/impl/paych"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/lotus/node/modules/helpers"
"github.com/filecoin-project/lotus/node/repo"
"github.com/filecoin-project/lotus/node/repo/imports"
)
func HandleMigrateClientFunds(lc fx.Lifecycle, ds dtypes.MetadataDS, wallet full.WalletAPI, fundMgr *market.FundManager) {
func HandleMigrateClientFunds(lc fx.Lifecycle, mctx helpers.MetricsCtx, ds dtypes.MetadataDS, wallet full.WalletAPI, fundMgr *market.FundManager) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
addr, err := wallet.WalletDefaultAddress(ctx)
@@ -52,7 +53,7 @@ func HandleMigrateClientFunds(lc fx.Lifecycle, ds dtypes.MetadataDS, wallet full
if err != nil {
return nil
}
b, err := ds.Get(datastore.NewKey("/marketfunds/client"))
b, err := ds.Get(helpers.LifecycleCtx(mctx, lc), datastore.NewKey("/marketfunds/client"))
if err != nil {
if xerrors.Is(err, datastore.ErrNotFound) {
return nil
@@ -73,7 +74,7 @@ func HandleMigrateClientFunds(lc fx.Lifecycle, ds dtypes.MetadataDS, wallet full
return nil
}
return ds.Delete(datastore.NewKey("/marketfunds/client"))
return ds.Delete(helpers.LifecycleCtx(mctx, lc), datastore.NewKey("/marketfunds/client"))
},
})
}
+12 -7
View File
@@ -4,6 +4,8 @@ import (
"bytes"
"os"
"go.uber.org/fx"
"github.com/ipfs/go-datastore"
"github.com/ipld/go-car"
"golang.org/x/xerrors"
@@ -11,6 +13,7 @@ import (
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/lotus/node/modules/helpers"
)
func ErrorGenesis() Genesis {
@@ -19,17 +22,18 @@ func ErrorGenesis() Genesis {
}
}
func LoadGenesis(genBytes []byte) func(dtypes.ChainBlockstore) Genesis {
return func(bs dtypes.ChainBlockstore) Genesis {
func LoadGenesis(genBytes []byte) func(fx.Lifecycle, helpers.MetricsCtx, dtypes.ChainBlockstore) Genesis {
return func(lc fx.Lifecycle, mctx helpers.MetricsCtx, bs dtypes.ChainBlockstore) Genesis {
return func() (header *types.BlockHeader, e error) {
c, err := car.LoadCar(bs, bytes.NewReader(genBytes))
ctx := helpers.LifecycleCtx(mctx, lc)
c, err := car.LoadCar(ctx, bs, bytes.NewReader(genBytes))
if err != nil {
return nil, xerrors.Errorf("loading genesis car file failed: %w", err)
}
if len(c.Roots) != 1 {
return nil, xerrors.New("expected genesis file to have one root")
}
root, err := bs.Get(c.Roots[0])
root, err := bs.Get(ctx, c.Roots[0])
if err != nil {
return nil, err
}
@@ -45,8 +49,9 @@ func LoadGenesis(genBytes []byte) func(dtypes.ChainBlockstore) Genesis {
func DoSetGenesis(_ dtypes.AfterGenesisSet) {}
func SetGenesis(cs *store.ChainStore, g Genesis) (dtypes.AfterGenesisSet, error) {
genFromRepo, err := cs.GetGenesis()
func SetGenesis(lc fx.Lifecycle, mctx helpers.MetricsCtx, cs *store.ChainStore, g Genesis) (dtypes.AfterGenesisSet, error) {
ctx := helpers.LifecycleCtx(mctx, lc)
genFromRepo, err := cs.GetGenesis(ctx)
if err == nil {
if os.Getenv("LOTUS_SKIP_GENESIS_CHECK") != "_yes_" {
expectedGenesis, err := g()
@@ -69,5 +74,5 @@ func SetGenesis(cs *store.ChainStore, g Genesis) (dtypes.AfterGenesisSet, error)
return dtypes.AfterGenesisSet{}, xerrors.Errorf("genesis func failed: %w", err)
}
return dtypes.AfterGenesisSet{}, cs.SetGenesis(genesis)
return dtypes.AfterGenesisSet{}, cs.SetGenesis(ctx, genesis)
}
+6 -3
View File
@@ -10,6 +10,7 @@ import (
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/peerstore"
dht "github.com/libp2p/go-libp2p-kad-dht"
"github.com/libp2p/go-libp2p-peerstore/pstoremem"
record "github.com/libp2p/go-libp2p-record"
routedhost "github.com/libp2p/go-libp2p/p2p/host/routed"
mocknet "github.com/libp2p/go-libp2p/p2p/net/mock"
@@ -33,9 +34,11 @@ type P2PHostIn struct {
type RawHost host.Host
func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (RawHost, error) {
ctx := helpers.LifecycleCtx(mctx, lc)
func Peerstore() (peerstore.Peerstore, error) {
return pstoremem.NewPeerstore()
}
func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (RawHost, error) {
pkey := params.Peerstore.PrivKey(params.ID)
if pkey == nil {
return nil, fmt.Errorf("missing private key for node ID: %s", params.ID.Pretty())
@@ -52,7 +55,7 @@ func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (RawHost,
opts = append(opts, o...)
}
h, err := libp2p.New(ctx, opts...)
h, err := libp2p.New(opts...)
if err != nil {
return nil, err
}
+5 -1
View File
@@ -69,7 +69,11 @@ func genLibp2pKey() (crypto.PrivKey, error) {
func ConnectionManager(low, high uint, grace time.Duration, protected []string) func() (opts Libp2pOpts, err error) {
return func() (Libp2pOpts, error) {
cm := connmgr.NewConnManager(int(low), int(high), grace)
cm, err := connmgr.NewConnManager(int(low), int(high), connmgr.WithGracePeriod(grace))
if err != nil {
return Libp2pOpts{}, err
}
for _, p := range protected {
pid, err := peer.IDFromString(p)
if err != nil {
+4 -30
View File
@@ -2,17 +2,13 @@ package lp2p
import (
"os"
"strings"
"github.com/libp2p/go-libp2p"
smux "github.com/libp2p/go-libp2p-core/mux"
mplex "github.com/libp2p/go-libp2p-mplex"
yamux "github.com/libp2p/go-libp2p-yamux"
)
func makeSmuxTransportOption(mplexExp bool) libp2p.Option {
func makeSmuxTransportOption() libp2p.Option {
const yamuxID = "/yamux/1.0.0"
const mplexID = "/mplex/6.7.0"
ymxtpt := *yamux.DefaultTransport
ymxtpt.AcceptBacklog = 512
@@ -21,34 +17,12 @@ func makeSmuxTransportOption(mplexExp bool) libp2p.Option {
ymxtpt.LogOutput = os.Stderr
}
muxers := map[string]smux.Multiplexer{yamuxID: &ymxtpt}
if mplexExp {
muxers[mplexID] = mplex.DefaultTransport
}
// Allow muxer preference order overriding
order := []string{yamuxID, mplexID}
if prefs := os.Getenv("LIBP2P_MUX_PREFS"); prefs != "" {
order = strings.Fields(prefs)
}
opts := make([]libp2p.Option, 0, len(order))
for _, id := range order {
tpt, ok := muxers[id]
if !ok {
log.Warnf("unknown or duplicate muxer in LIBP2P_MUX_PREFS: %s", id)
continue
}
delete(muxers, id)
opts = append(opts, libp2p.Muxer(id, tpt))
}
return libp2p.ChainOptions(opts...)
return libp2p.Muxer(yamuxID, &ymxtpt)
}
func SmuxTransport(mplex bool) func() (opts Libp2pOpts, err error) {
func SmuxTransport() func() (opts Libp2pOpts, err error) {
return func() (opts Libp2pOpts, err error) {
opts.Opts = append(opts.Opts, makeSmuxTransportOption(mplex))
opts.Opts = append(opts.Opts, makeSmuxTransportOption())
return
}
}
+2 -2
View File
@@ -228,8 +228,8 @@ func BuiltinDrandConfig() dtypes.DrandSchedule {
return build.DrandConfigSchedule()
}
func RandomSchedule(p RandomBeaconParams, _ dtypes.AfterGenesisSet) (beacon.Schedule, error) {
gen, err := p.Cs.GetGenesis()
func RandomSchedule(lc fx.Lifecycle, mctx helpers.MetricsCtx, p RandomBeaconParams, _ dtypes.AfterGenesisSet) (beacon.Schedule, error) {
gen, err := p.Cs.GetGenesis(helpers.LifecycleCtx(mctx, lc))
if err != nil {
return nil, err
}
+11 -7
View File
@@ -32,13 +32,13 @@ import (
"github.com/filecoin-project/go-jsonrpc/auth"
"github.com/filecoin-project/go-paramfetch"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-statestore"
"github.com/filecoin-project/go-storedcounter"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore"
"github.com/ipfs/go-datastore/namespace"
graphsync "github.com/ipfs/go-graphsync/impl"
graphsyncimpl "github.com/ipfs/go-graphsync/impl"
gsnet "github.com/ipfs/go-graphsync/network"
"github.com/ipfs/go-graphsync/storeutil"
"github.com/libp2p/go-libp2p-core/host"
@@ -77,7 +77,7 @@ var (
)
func minerAddrFromDS(ds dtypes.MetadataDS) (address.Address, error) {
maddrb, err := ds.Get(datastore.NewKey("miner-address"))
maddrb, err := ds.Get(context.TODO(), datastore.NewKey("miner-address"))
if err != nil {
return address.Undef, err
}
@@ -299,7 +299,7 @@ func HandleDeals(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, h sto
func HandleMigrateProviderFunds(lc fx.Lifecycle, ds dtypes.MetadataDS, node api.FullNode, minerAddress dtypes.MinerAddress) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
b, err := ds.Get(datastore.NewKey("/marketfunds/provider"))
b, err := ds.Get(ctx, datastore.NewKey("/marketfunds/provider"))
if err != nil {
if xerrors.Is(err, datastore.ErrNotFound) {
return nil
@@ -330,7 +330,7 @@ func HandleMigrateProviderFunds(lc fx.Lifecycle, ds dtypes.MetadataDS, node api.
return nil
}
return ds.Delete(datastore.NewKey("/marketfunds/provider"))
return ds.Delete(ctx, datastore.NewKey("/marketfunds/provider"))
},
})
}
@@ -395,7 +395,7 @@ func StagingBlockstore(lc fx.Lifecycle, mctx helpers.MetricsCtx, r repo.LockedRe
// StagingGraphsync creates a graphsync instance which reads and writes blocks
// to the StagingBlockstore
func StagingGraphsync(parallelTransfersForStorage uint64, parallelTransfersForRetrieval uint64) func(mctx helpers.MetricsCtx, lc fx.Lifecycle, ibs dtypes.StagingBlockstore, h host.Host) dtypes.StagingGraphsync {
func StagingGraphsync(parallelTransfersForStorage uint64, parallelTransfersForStoragePerPeer uint64, parallelTransfersForRetrieval uint64) func(mctx helpers.MetricsCtx, lc fx.Lifecycle, ibs dtypes.StagingBlockstore, h host.Host) dtypes.StagingGraphsync {
return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, ibs dtypes.StagingBlockstore, h host.Host) dtypes.StagingGraphsync {
graphsyncNetwork := gsnet.NewFromLibp2pHost(h)
lsys := storeutil.LinkSystemForBlockstore(ibs)
@@ -404,9 +404,10 @@ func StagingGraphsync(parallelTransfersForStorage uint64, parallelTransfersForRe
lsys,
graphsync.RejectAllRequestsByDefault(),
graphsync.MaxInProgressIncomingRequests(parallelTransfersForRetrieval),
graphsync.MaxInProgressIncomingRequestsPerPeer(parallelTransfersForStoragePerPeer),
graphsync.MaxInProgressOutgoingRequests(parallelTransfersForStorage),
graphsyncimpl.MaxLinksPerIncomingRequests(config.MaxTraversalLinks),
graphsyncimpl.MaxLinksPerOutgoingRequests(config.MaxTraversalLinks))
graphsync.MaxLinksPerIncomingRequests(config.MaxTraversalLinks),
graphsync.MaxLinksPerOutgoingRequests(config.MaxTraversalLinks))
graphsyncStats(mctx, lc, gs)
@@ -683,6 +684,9 @@ func RetrievalProvider(
dagStore *dagstore.Wrapper,
) (retrievalmarket.RetrievalProvider, error) {
opt := retrievalimpl.DealDeciderOpt(retrievalimpl.DealDecider(userFilter))
retrievalmarket.DefaultPricePerByte = big.Zero() // todo: for whatever reason this is a global var in markets
return retrievalimpl.NewProvider(
address.Address(maddr),
adapter,
+1 -3
View File
@@ -11,8 +11,6 @@ import (
"golang.org/x/xerrors"
"github.com/filecoin-project/dagstore"
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
mdagstore "github.com/filecoin-project/lotus/markets/dagstore"
"github.com/filecoin-project/lotus/node/config"
"github.com/filecoin-project/lotus/node/modules/dtypes"
@@ -25,7 +23,7 @@ const (
)
// NewMinerAPI creates a new MinerAPI adaptor for the dagstore mounts.
func NewMinerAPI(lc fx.Lifecycle, r repo.LockedRepo, pieceStore dtypes.ProviderPieceStore, sa retrievalmarket.SectorAccessor) (mdagstore.MinerAPI, error) {
func NewMinerAPI(lc fx.Lifecycle, r repo.LockedRepo, pieceStore dtypes.ProviderPieceStore, sa mdagstore.SectorAccessor) (mdagstore.MinerAPI, error) {
cfg, err := extractDAGStoreConfig(r)
if err != nil {
return nil, err
+16 -8
View File
@@ -1,6 +1,7 @@
package imports
import (
"context"
"encoding/json"
"fmt"
"os"
@@ -107,6 +108,7 @@ type Meta struct {
// CreateImport initializes a new import, returning its ID and optionally a
// CAR path where to place the data, if requested.
func (m *Manager) CreateImport() (id ID, err error) {
ctx := context.TODO()
id = ID(m.counter.Next())
meta := &Meta{Labels: map[LabelKey]LabelValue{
@@ -118,7 +120,7 @@ func (m *Manager) CreateImport() (id ID, err error) {
return 0, xerrors.Errorf("marshaling store metadata: %w", err)
}
err = m.ds.Put(id.dsKey(), metajson)
err = m.ds.Put(ctx, id.dsKey(), metajson)
if err != nil {
return 0, xerrors.Errorf("failed to insert import metadata: %w", err)
}
@@ -129,7 +131,8 @@ func (m *Manager) CreateImport() (id ID, err error) {
// AllocateCAR creates a new CAR allocated to the supplied import under the
// root directory.
func (m *Manager) AllocateCAR(id ID) (path string, err error) {
meta, err := m.ds.Get(id.dsKey())
ctx := context.TODO()
meta, err := m.ds.Get(ctx, id.dsKey())
if err != nil {
return "", xerrors.Errorf("getting metadata form datastore: %w", err)
}
@@ -163,14 +166,15 @@ func (m *Manager) AllocateCAR(id ID) (path string, err error) {
return "", xerrors.Errorf("marshaling store metadata: %w", err)
}
err = m.ds.Put(id.dsKey(), meta)
err = m.ds.Put(ctx, id.dsKey(), meta)
return path, err
}
// AddLabel adds a label associated with an import, such as the source,
// car path, CID, etc.
func (m *Manager) AddLabel(id ID, key LabelKey, value LabelValue) error {
meta, err := m.ds.Get(id.dsKey())
ctx := context.TODO()
meta, err := m.ds.Get(ctx, id.dsKey())
if err != nil {
return xerrors.Errorf("getting metadata form datastore: %w", err)
}
@@ -187,14 +191,15 @@ func (m *Manager) AddLabel(id ID, key LabelKey, value LabelValue) error {
return xerrors.Errorf("marshaling store meta: %w", err)
}
return m.ds.Put(id.dsKey(), meta)
return m.ds.Put(ctx, id.dsKey(), meta)
}
// List returns all import IDs known by this Manager.
func (m *Manager) List() ([]ID, error) {
ctx := context.TODO()
var keys []ID
qres, err := m.ds.Query(query.Query{KeysOnly: true})
qres, err := m.ds.Query(ctx, query.Query{KeysOnly: true})
if err != nil {
return nil, xerrors.Errorf("query error: %w", err)
}
@@ -218,7 +223,9 @@ func (m *Manager) List() ([]ID, error) {
// Info returns the metadata known to this store for the specified import ID.
func (m *Manager) Info(id ID) (*Meta, error) {
meta, err := m.ds.Get(id.dsKey())
ctx := context.TODO()
meta, err := m.ds.Get(ctx, id.dsKey())
if err != nil {
return nil, xerrors.Errorf("getting metadata form datastore: %w", err)
}
@@ -233,7 +240,8 @@ func (m *Manager) Info(id ID) (*Meta, error) {
// Remove drops all data associated with the supplied import ID.
func (m *Manager) Remove(id ID) error {
if err := m.ds.Delete(id.dsKey()); err != nil {
ctx := context.TODO()
if err := m.ds.Delete(ctx, id.dsKey()); err != nil {
return xerrors.Errorf("removing import metadata: %w", err)
}
return nil
+37
View File
@@ -27,6 +27,7 @@ import (
"github.com/filecoin-project/lotus/metrics"
"github.com/filecoin-project/lotus/metrics/proxy"
"github.com/filecoin-project/lotus/node/impl"
"github.com/filecoin-project/lotus/node/impl/client"
)
var rpclog = logging.Logger("rpc")
@@ -89,14 +90,22 @@ func FullNodeHandler(a v1api.FullNode, permissioned bool, opts ...jsonrpc.Server
// Import handler
handleImportFunc := handleImport(a.(*impl.FullNodeAPI))
handleExportFunc := handleExport(a.(*impl.FullNodeAPI))
if permissioned {
importAH := &auth.Handler{
Verify: a.AuthVerify,
Next: handleImportFunc,
}
m.Handle("/rest/v0/import", importAH)
exportAH := &auth.Handler{
Verify: a.AuthVerify,
Next: handleExportFunc,
}
m.Handle("/rest/v0/export", exportAH)
} else {
m.HandleFunc("/rest/v0/import", handleImportFunc)
m.HandleFunc("/rest/v0/export", handleExportFunc)
}
// debugging
@@ -169,6 +178,34 @@ func handleImport(a *impl.FullNodeAPI) func(w http.ResponseWriter, r *http.Reque
}
}
func handleExport(a *impl.FullNodeAPI) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
w.WriteHeader(404)
return
}
if !auth.HasPerm(r.Context(), nil, api.PermWrite) {
w.WriteHeader(401)
_ = json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"})
return
}
var eref api.ExportRef
if err := json.Unmarshal([]byte(r.FormValue("export")), &eref); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
car := r.FormValue("car") == "true"
err := a.ClientExportInto(r.Context(), eref, car, client.ExportDest{Writer: w})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
}
func handleFractionOpt(name string, setter func(int)) http.HandlerFunc {
return func(rw http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {