Merge remote-tracking branch 'origin/master' into feat/stateless-offline-dealflow
This commit is contained in:
commit
b79be2a2c2
@ -358,6 +358,15 @@ jobs:
|
||||
command: |
|
||||
curl --location https://github.com/stedolan/jq/releases/download/jq-1.6/jq-osx-amd64 --output /usr/local/bin/jq
|
||||
chmod +x /usr/local/bin/jq
|
||||
- run:
|
||||
name: Install hwloc
|
||||
command: |
|
||||
mkdir ~/hwloc
|
||||
curl --location https://download.open-mpi.org/release/hwloc/v2.4/hwloc-2.4.1.tar.gz --output ~/hwloc/hwloc-2.4.1.tar.gz
|
||||
cd ~/hwloc
|
||||
tar -xvzpf hwloc-2.4.1.tar.gz
|
||||
cd hwloc-2.4.1
|
||||
./configure && make && sudo make install
|
||||
- restore_cache:
|
||||
name: restore cargo cache
|
||||
key: v3-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.sum" }}
|
||||
@ -408,9 +417,18 @@ jobs:
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run: zcat build/openrpc/full.json.gz | jq > ../pre-openrpc-full
|
||||
- run: zcat build/openrpc/miner.json.gz | jq > ../pre-openrpc-miner
|
||||
- run: zcat build/openrpc/worker.json.gz | jq > ../pre-openrpc-worker
|
||||
- run: make deps
|
||||
- run: make docsgen
|
||||
- run: zcat build/openrpc/full.json.gz | jq > ../post-openrpc-full
|
||||
- run: zcat build/openrpc/miner.json.gz | jq > ../post-openrpc-miner
|
||||
- run: zcat build/openrpc/worker.json.gz | jq > ../post-openrpc-worker
|
||||
- run: git --no-pager diff
|
||||
- run: diff ../pre-openrpc-full ../post-openrpc-full
|
||||
- run: diff ../pre-openrpc-miner ../post-openrpc-miner
|
||||
- run: diff ../pre-openrpc-worker ../post-openrpc-worker
|
||||
- run: git --no-pager diff --quiet
|
||||
|
||||
lint: &lint
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -14,6 +14,8 @@
|
||||
/lotus-pcr
|
||||
/lotus-wallet
|
||||
/lotus-keygen
|
||||
/docgen-md
|
||||
/docgen-openrpc
|
||||
/bench.json
|
||||
/lotuspond/front/node_modules
|
||||
/lotuspond/front/build
|
||||
|
@ -16,6 +16,12 @@ linters:
|
||||
- deadcode
|
||||
- scopelint
|
||||
|
||||
# We don't want to skip builtin/
|
||||
skip-dirs-use-default: false
|
||||
skip-dirs:
|
||||
- vendor$
|
||||
- testdata$
|
||||
- examples$
|
||||
|
||||
issues:
|
||||
exclude:
|
||||
|
@ -1,8 +1,8 @@
|
||||
# Lotus changelog
|
||||
|
||||
# 1.5.3-rc2 / 2021-03-17
|
||||
# 1.5.3 / 2021-03-24
|
||||
|
||||
This is the second release candidate for Lotus 1.5.3, which introduces small fixes to the Storage FSM.
|
||||
This is a patch release of Lotus that introduces small fixes to the Storage FSM.
|
||||
|
||||
## Changes
|
||||
|
||||
|
39
Makefile
39
Makefile
@ -325,12 +325,41 @@ type-gen:
|
||||
method-gen:
|
||||
(cd ./lotuspond/front/src/chain && go run ./methodgen.go)
|
||||
|
||||
gen: type-gen method-gen
|
||||
api-gen:
|
||||
go run ./gen/api > api/apistruct/struct.go
|
||||
goimports -w api/apistruct
|
||||
goimports -w api/apistruct
|
||||
.PHONY: api-gen
|
||||
|
||||
docsgen:
|
||||
go run ./api/docgen "api/api_full.go" "FullNode" > documentation/en/api-methods.md
|
||||
go run ./api/docgen "api/api_storage.go" "StorageMiner" > documentation/en/api-methods-miner.md
|
||||
go run ./api/docgen "api/api_worker.go" "WorkerAPI" > documentation/en/api-methods-worker.md
|
||||
docsgen: docsgen-md docsgen-openrpc
|
||||
|
||||
docsgen-md-bin:
|
||||
go build $(GOFLAGS) -o docgen-md ./api/docgen/cmd
|
||||
docsgen-openrpc-bin:
|
||||
go build $(GOFLAGS) -o docgen-openrpc ./api/docgen-openrpc/cmd
|
||||
|
||||
docsgen-md: docsgen-md-full docsgen-md-storage docsgen-md-worker
|
||||
|
||||
docsgen-md-full: docsgen-md-bin
|
||||
./docgen-md "api/api_full.go" "FullNode" > documentation/en/api-methods.md
|
||||
docsgen-md-storage: docsgen-md-bin
|
||||
./docgen-md "api/api_storage.go" "StorageMiner" > documentation/en/api-methods-miner.md
|
||||
docsgen-md-worker: docsgen-md-bin
|
||||
./docgen-md "api/api_worker.go" "Worker" > documentation/en/api-methods-worker.md
|
||||
|
||||
docsgen-openrpc: docsgen-openrpc-full docsgen-openrpc-storage docsgen-openrpc-worker
|
||||
|
||||
docsgen-openrpc-full: docsgen-openrpc-bin
|
||||
./docgen-openrpc "api/api_full.go" "FullNode" -gzip > build/openrpc/full.json.gz
|
||||
docsgen-openrpc-storage: docsgen-openrpc-bin
|
||||
./docgen-openrpc "api/api_storage.go" "StorageMiner" -gzip > build/openrpc/miner.json.gz
|
||||
docsgen-openrpc-worker: docsgen-openrpc-bin
|
||||
./docgen-openrpc "api/api_worker.go" "Worker" -gzip > build/openrpc/worker.json.gz
|
||||
|
||||
.PHONY: docsgen docsgen-md-bin docsgen-openrpc-bin
|
||||
|
||||
gen: type-gen method-gen docsgen api-gen
|
||||
.PHONY: gen
|
||||
|
||||
print-%:
|
||||
@echo $*=$($*)
|
||||
|
@ -11,63 +11,68 @@ import (
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
protocol "github.com/libp2p/go-libp2p-core/protocol"
|
||||
|
||||
apitypes "github.com/filecoin-project/lotus/api/types"
|
||||
)
|
||||
|
||||
type Common interface {
|
||||
|
||||
// MethodGroup: Auth
|
||||
|
||||
AuthVerify(ctx context.Context, token string) ([]auth.Permission, error)
|
||||
AuthNew(ctx context.Context, perms []auth.Permission) ([]byte, error)
|
||||
AuthVerify(ctx context.Context, token string) ([]auth.Permission, error) //perm:read
|
||||
AuthNew(ctx context.Context, perms []auth.Permission) ([]byte, error) //perm:admin
|
||||
|
||||
// MethodGroup: Net
|
||||
|
||||
NetConnectedness(context.Context, peer.ID) (network.Connectedness, error)
|
||||
NetPeers(context.Context) ([]peer.AddrInfo, error)
|
||||
NetConnect(context.Context, peer.AddrInfo) error
|
||||
NetAddrsListen(context.Context) (peer.AddrInfo, error)
|
||||
NetDisconnect(context.Context, peer.ID) error
|
||||
NetFindPeer(context.Context, peer.ID) (peer.AddrInfo, error)
|
||||
NetPubsubScores(context.Context) ([]PubsubScore, error)
|
||||
NetAutoNatStatus(context.Context) (NatInfo, error)
|
||||
NetAgentVersion(ctx context.Context, p peer.ID) (string, error)
|
||||
NetPeerInfo(context.Context, peer.ID) (*ExtendedPeerInfo, error)
|
||||
NetConnectedness(context.Context, peer.ID) (network.Connectedness, error) //perm:read
|
||||
NetPeers(context.Context) ([]peer.AddrInfo, error) //perm:read
|
||||
NetConnect(context.Context, peer.AddrInfo) error //perm:write
|
||||
NetAddrsListen(context.Context) (peer.AddrInfo, error) //perm:read
|
||||
NetDisconnect(context.Context, peer.ID) error //perm:write
|
||||
NetFindPeer(context.Context, peer.ID) (peer.AddrInfo, error) //perm:read
|
||||
NetPubsubScores(context.Context) ([]PubsubScore, error) //perm:read
|
||||
NetAutoNatStatus(context.Context) (NatInfo, error) //perm:read
|
||||
NetAgentVersion(ctx context.Context, p peer.ID) (string, error) //perm:read
|
||||
NetPeerInfo(context.Context, peer.ID) (*ExtendedPeerInfo, error) //perm:read
|
||||
|
||||
// NetBandwidthStats returns statistics about the nodes total bandwidth
|
||||
// usage and current rate across all peers and protocols.
|
||||
NetBandwidthStats(ctx context.Context) (metrics.Stats, error)
|
||||
NetBandwidthStats(ctx context.Context) (metrics.Stats, error) //perm:read
|
||||
|
||||
// NetBandwidthStatsByPeer returns statistics about the nodes bandwidth
|
||||
// usage and current rate per peer
|
||||
NetBandwidthStatsByPeer(ctx context.Context) (map[string]metrics.Stats, error)
|
||||
NetBandwidthStatsByPeer(ctx context.Context) (map[string]metrics.Stats, error) //perm:read
|
||||
|
||||
// NetBandwidthStatsByProtocol returns statistics about the nodes bandwidth
|
||||
// usage and current rate per protocol
|
||||
NetBandwidthStatsByProtocol(ctx context.Context) (map[protocol.ID]metrics.Stats, error)
|
||||
NetBandwidthStatsByProtocol(ctx context.Context) (map[protocol.ID]metrics.Stats, error) //perm:read
|
||||
|
||||
// ConnectionGater API
|
||||
NetBlockAdd(ctx context.Context, acl NetBlockList) error
|
||||
NetBlockRemove(ctx context.Context, acl NetBlockList) error
|
||||
NetBlockList(ctx context.Context) (NetBlockList, error)
|
||||
NetBlockAdd(ctx context.Context, acl NetBlockList) error //perm:admin
|
||||
NetBlockRemove(ctx context.Context, acl NetBlockList) error //perm:admin
|
||||
NetBlockList(ctx context.Context) (NetBlockList, error) //perm:read
|
||||
|
||||
// MethodGroup: Common
|
||||
|
||||
// Discover returns an OpenRPC document describing an RPC API.
|
||||
Discover(ctx context.Context) (apitypes.OpenRPCDocument, error) //perm:read
|
||||
|
||||
// ID returns peerID of libp2p node backing this API
|
||||
ID(context.Context) (peer.ID, error)
|
||||
ID(context.Context) (peer.ID, error) //perm:read
|
||||
|
||||
// Version provides information about API provider
|
||||
Version(context.Context) (APIVersion, error)
|
||||
Version(context.Context) (APIVersion, error) //perm:read
|
||||
|
||||
LogList(context.Context) ([]string, error)
|
||||
LogSetLevel(context.Context, string, string) error
|
||||
LogList(context.Context) ([]string, error) //perm:write
|
||||
LogSetLevel(context.Context, string, string) error //perm:write
|
||||
|
||||
// trigger graceful shutdown
|
||||
Shutdown(context.Context) error
|
||||
Shutdown(context.Context) error //perm:admin
|
||||
|
||||
// Session returns a random UUID of api provider session
|
||||
Session(context.Context) (uuid.UUID, error)
|
||||
Session(context.Context) (uuid.UUID, error) //perm:read
|
||||
|
||||
Closing(context.Context) (<-chan struct{}, error)
|
||||
Closing(context.Context) (<-chan struct{}, error) //perm:read
|
||||
}
|
||||
|
||||
// APIVersion provides various build-time information
|
||||
|
492
api/api_full.go
492
api/api_full.go
@ -6,14 +6,12 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||
"github.com/filecoin-project/go-multistore"
|
||||
@ -21,11 +19,12 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
|
||||
apitypes "github.com/filecoin-project/lotus/api/types"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
marketevents "github.com/filecoin-project/lotus/markets/loggers"
|
||||
@ -50,66 +49,78 @@ type FullNode interface {
|
||||
|
||||
// ChainNotify returns channel with chain head updates.
|
||||
// First message is guaranteed to be of len == 1, and type == 'current'.
|
||||
ChainNotify(context.Context) (<-chan []*HeadChange, error)
|
||||
ChainNotify(context.Context) (<-chan []*HeadChange, error) //perm:read
|
||||
|
||||
// ChainHead returns the current head of the chain.
|
||||
ChainHead(context.Context) (*types.TipSet, error)
|
||||
ChainHead(context.Context) (*types.TipSet, error) //perm:read
|
||||
|
||||
// ChainGetRandomnessFromTickets is used to sample the chain for randomness.
|
||||
ChainGetRandomnessFromTickets(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
|
||||
ChainGetRandomnessFromTickets(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) //perm:read
|
||||
|
||||
// ChainGetRandomnessFromBeacon is used to sample the beacon for randomness.
|
||||
ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
|
||||
ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) //perm:read
|
||||
|
||||
// ChainGetBlock returns the block specified by the given CID.
|
||||
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
|
||||
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error) //perm:read
|
||||
// ChainGetTipSet returns the tipset specified by the given TipSetKey.
|
||||
ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error)
|
||||
ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error) //perm:read
|
||||
|
||||
// ChainGetBlockMessages returns messages stored in the specified block.
|
||||
ChainGetBlockMessages(ctx context.Context, blockCid cid.Cid) (*BlockMessages, error)
|
||||
//
|
||||
// Note: If there are multiple blocks in a tipset, it's likely that some
|
||||
// messages will be duplicated. It's also possible for blocks in a tipset to have
|
||||
// different messages from the same sender at the same nonce. When that happens,
|
||||
// only the first message (in a block with lowest ticket) will be considered
|
||||
// for execution
|
||||
//
|
||||
// NOTE: THIS METHOD SHOULD ONLY BE USED FOR GETTING MESSAGES IN A SPECIFIC BLOCK
|
||||
//
|
||||
// DO NOT USE THIS METHOD TO GET MESSAGES INCLUDED IN A TIPSET
|
||||
// Use ChainGetParentMessages, which will perform correct message deduplication
|
||||
ChainGetBlockMessages(ctx context.Context, blockCid cid.Cid) (*BlockMessages, error) //perm:read
|
||||
|
||||
// ChainGetParentReceipts returns receipts for messages in parent tipset of
|
||||
// the specified block.
|
||||
ChainGetParentReceipts(ctx context.Context, blockCid cid.Cid) ([]*types.MessageReceipt, error)
|
||||
// the specified block. The receipts in the list returned is one-to-one with the
|
||||
// messages returned by a call to ChainGetParentMessages with the same blockCid.
|
||||
ChainGetParentReceipts(ctx context.Context, blockCid cid.Cid) ([]*types.MessageReceipt, error) //perm:read
|
||||
|
||||
// ChainGetParentMessages returns messages stored in parent tipset of the
|
||||
// specified block.
|
||||
ChainGetParentMessages(ctx context.Context, blockCid cid.Cid) ([]Message, error)
|
||||
ChainGetParentMessages(ctx context.Context, blockCid cid.Cid) ([]Message, error) //perm:read
|
||||
|
||||
// ChainGetTipSetByHeight looks back for a tipset at the specified epoch.
|
||||
// If there are no blocks at the specified epoch, a tipset at an earlier epoch
|
||||
// will be returned.
|
||||
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error)
|
||||
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) //perm:read
|
||||
|
||||
// ChainReadObj reads ipld nodes referenced by the specified CID from chain
|
||||
// blockstore and returns raw bytes.
|
||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error) //perm:read
|
||||
|
||||
// ChainDeleteObj deletes node referenced by the given CID
|
||||
ChainDeleteObj(context.Context, cid.Cid) error
|
||||
ChainDeleteObj(context.Context, cid.Cid) error //perm:admin
|
||||
|
||||
// ChainHasObj checks if a given CID exists in the chain blockstore.
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error) //perm:read
|
||||
|
||||
// ChainStatObj returns statistics about the graph referenced by 'obj'.
|
||||
// If 'base' is also specified, then the returned stat will be a diff
|
||||
// between the two objects.
|
||||
ChainStatObj(ctx context.Context, obj cid.Cid, base cid.Cid) (ObjStat, error)
|
||||
ChainStatObj(ctx context.Context, obj cid.Cid, base cid.Cid) (ObjStat, error) //perm:read
|
||||
|
||||
// ChainSetHead forcefully sets current chain head. Use with caution.
|
||||
ChainSetHead(context.Context, types.TipSetKey) error
|
||||
ChainSetHead(context.Context, types.TipSetKey) error //perm:admin
|
||||
|
||||
// ChainGetGenesis returns the genesis tipset.
|
||||
ChainGetGenesis(context.Context) (*types.TipSet, error)
|
||||
ChainGetGenesis(context.Context) (*types.TipSet, error) //perm:read
|
||||
|
||||
// ChainTipSetWeight computes weight for the specified tipset.
|
||||
ChainTipSetWeight(context.Context, types.TipSetKey) (types.BigInt, error)
|
||||
ChainGetNode(ctx context.Context, p string) (*IpldObject, error)
|
||||
ChainTipSetWeight(context.Context, types.TipSetKey) (types.BigInt, error) //perm:read
|
||||
ChainGetNode(ctx context.Context, p string) (*IpldObject, error) //perm:read
|
||||
|
||||
// ChainGetMessage reads a message referenced by the specified CID from the
|
||||
// chain blockstore.
|
||||
ChainGetMessage(context.Context, cid.Cid) (*types.Message, error)
|
||||
ChainGetMessage(context.Context, cid.Cid) (*types.Message, error) //perm:read
|
||||
|
||||
// ChainGetPath returns a set of revert/apply operations needed to get from
|
||||
// one tipset to another, for example:
|
||||
@ -124,14 +135,14 @@ type FullNode interface {
|
||||
// tRR
|
||||
//```
|
||||
// Would return `[revert(tBA), apply(tAB), apply(tAA)]`
|
||||
ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*HeadChange, error)
|
||||
ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*HeadChange, error) //perm:read
|
||||
|
||||
// ChainExport returns a stream of bytes with CAR dump of chain data.
|
||||
// The exported chain data includes the header chain from the given tipset
|
||||
// back to genesis, the entire genesis state, and the most recent 'nroots'
|
||||
// state trees.
|
||||
// If oldmsgskip is set, messages from before the requested roots are also not included.
|
||||
ChainExport(ctx context.Context, nroots abi.ChainEpoch, oldmsgskip bool, tsk types.TipSetKey) (<-chan []byte, error)
|
||||
ChainExport(ctx context.Context, nroots abi.ChainEpoch, oldmsgskip bool, tsk types.TipSetKey) (<-chan []byte, error) //perm:read
|
||||
|
||||
// MethodGroup: Beacon
|
||||
// The Beacon method group contains methods for interacting with the random beacon (DRAND)
|
||||
@ -139,74 +150,74 @@ type FullNode interface {
|
||||
// BeaconGetEntry returns the beacon entry for the given filecoin epoch. If
|
||||
// the entry has not yet been produced, the call will block until the entry
|
||||
// becomes available
|
||||
BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error)
|
||||
BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) //perm:read
|
||||
|
||||
// GasEstimateFeeCap estimates gas fee cap
|
||||
GasEstimateFeeCap(context.Context, *types.Message, int64, types.TipSetKey) (types.BigInt, error)
|
||||
GasEstimateFeeCap(context.Context, *types.Message, int64, types.TipSetKey) (types.BigInt, error) //perm:read
|
||||
|
||||
// GasEstimateGasLimit estimates gas used by the message and returns it.
|
||||
// It fails if message fails to execute.
|
||||
GasEstimateGasLimit(context.Context, *types.Message, types.TipSetKey) (int64, error)
|
||||
GasEstimateGasLimit(context.Context, *types.Message, types.TipSetKey) (int64, error) //perm:read
|
||||
|
||||
// GasEstimateGasPremium estimates what gas price should be used for a
|
||||
// message to have high likelihood of inclusion in `nblocksincl` epochs.
|
||||
|
||||
GasEstimateGasPremium(_ context.Context, nblocksincl uint64,
|
||||
sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error)
|
||||
sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error) //perm:read
|
||||
|
||||
// GasEstimateMessageGas estimates gas values for unset message gas fields
|
||||
GasEstimateMessageGas(context.Context, *types.Message, *MessageSendSpec, types.TipSetKey) (*types.Message, error)
|
||||
GasEstimateMessageGas(context.Context, *types.Message, *MessageSendSpec, types.TipSetKey) (*types.Message, error) //perm:read
|
||||
|
||||
// MethodGroup: Sync
|
||||
// The Sync method group contains methods for interacting with and
|
||||
// observing the lotus sync service.
|
||||
|
||||
// SyncState returns the current status of the lotus sync system.
|
||||
SyncState(context.Context) (*SyncState, error)
|
||||
SyncState(context.Context) (*SyncState, error) //perm:read
|
||||
|
||||
// SyncSubmitBlock can be used to submit a newly created block to the.
|
||||
// network through this node
|
||||
SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error
|
||||
SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error //perm:write
|
||||
|
||||
// SyncIncomingBlocks returns a channel streaming incoming, potentially not
|
||||
// yet synced block headers.
|
||||
SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error)
|
||||
SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error) //perm:read
|
||||
|
||||
// SyncCheckpoint marks a blocks as checkpointed, meaning that it won't ever fork away from it.
|
||||
SyncCheckpoint(ctx context.Context, tsk types.TipSetKey) error
|
||||
SyncCheckpoint(ctx context.Context, tsk types.TipSetKey) error //perm:admin
|
||||
|
||||
// SyncMarkBad marks a blocks as bad, meaning that it won't ever by synced.
|
||||
// Use with extreme caution.
|
||||
SyncMarkBad(ctx context.Context, bcid cid.Cid) error
|
||||
SyncMarkBad(ctx context.Context, bcid cid.Cid) error //perm:admin
|
||||
|
||||
// SyncUnmarkBad unmarks a blocks as bad, making it possible to be validated and synced again.
|
||||
SyncUnmarkBad(ctx context.Context, bcid cid.Cid) error
|
||||
SyncUnmarkBad(ctx context.Context, bcid cid.Cid) error //perm:admin
|
||||
|
||||
// SyncUnmarkAllBad purges bad block cache, making it possible to sync to chains previously marked as bad
|
||||
SyncUnmarkAllBad(ctx context.Context) error
|
||||
SyncUnmarkAllBad(ctx context.Context) error //perm:admin
|
||||
|
||||
// SyncCheckBad checks if a block was marked as bad, and if it was, returns
|
||||
// the reason.
|
||||
SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error)
|
||||
SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error) //perm:read
|
||||
|
||||
// SyncValidateTipset indicates whether the provided tipset is valid or not
|
||||
SyncValidateTipset(ctx context.Context, tsk types.TipSetKey) (bool, error)
|
||||
SyncValidateTipset(ctx context.Context, tsk types.TipSetKey) (bool, error) //perm:read
|
||||
|
||||
// MethodGroup: Mpool
|
||||
// The Mpool methods are for interacting with the message pool. The message pool
|
||||
// manages all incoming and outgoing 'messages' going over the network.
|
||||
|
||||
// MpoolPending returns pending mempool messages.
|
||||
MpoolPending(context.Context, types.TipSetKey) ([]*types.SignedMessage, error)
|
||||
MpoolPending(context.Context, types.TipSetKey) ([]*types.SignedMessage, error) //perm:read
|
||||
|
||||
// MpoolSelect returns a list of pending messages for inclusion in the next block
|
||||
MpoolSelect(context.Context, types.TipSetKey, float64) ([]*types.SignedMessage, error)
|
||||
MpoolSelect(context.Context, types.TipSetKey, float64) ([]*types.SignedMessage, error) //perm:read
|
||||
|
||||
// MpoolPush pushes a signed message to mempool.
|
||||
MpoolPush(context.Context, *types.SignedMessage) (cid.Cid, error)
|
||||
MpoolPush(context.Context, *types.SignedMessage) (cid.Cid, error) //perm:write
|
||||
|
||||
// MpoolPushUntrusted pushes a signed message to mempool from untrusted sources.
|
||||
MpoolPushUntrusted(context.Context, *types.SignedMessage) (cid.Cid, error)
|
||||
MpoolPushUntrusted(context.Context, *types.SignedMessage) (cid.Cid, error) //perm:write
|
||||
|
||||
// MpoolPushMessage atomically assigns a nonce, signs, and pushes a message
|
||||
// to mempool.
|
||||
@ -214,34 +225,34 @@ type FullNode interface {
|
||||
//
|
||||
// When maxFee is set to 0, MpoolPushMessage will guess appropriate fee
|
||||
// based on current chain conditions
|
||||
MpoolPushMessage(ctx context.Context, msg *types.Message, spec *MessageSendSpec) (*types.SignedMessage, error)
|
||||
MpoolPushMessage(ctx context.Context, msg *types.Message, spec *MessageSendSpec) (*types.SignedMessage, error) //perm:sign
|
||||
|
||||
// MpoolBatchPush batch pushes a signed message to mempool.
|
||||
MpoolBatchPush(context.Context, []*types.SignedMessage) ([]cid.Cid, error)
|
||||
MpoolBatchPush(context.Context, []*types.SignedMessage) ([]cid.Cid, error) //perm:write
|
||||
|
||||
// MpoolBatchPushUntrusted batch pushes a signed message to mempool from untrusted sources.
|
||||
MpoolBatchPushUntrusted(context.Context, []*types.SignedMessage) ([]cid.Cid, error)
|
||||
MpoolBatchPushUntrusted(context.Context, []*types.SignedMessage) ([]cid.Cid, error) //perm:write
|
||||
|
||||
// MpoolBatchPushMessage batch pushes a unsigned message to mempool.
|
||||
MpoolBatchPushMessage(context.Context, []*types.Message, *MessageSendSpec) ([]*types.SignedMessage, error)
|
||||
MpoolBatchPushMessage(context.Context, []*types.Message, *MessageSendSpec) ([]*types.SignedMessage, error) //perm:sign
|
||||
|
||||
// MpoolGetNonce gets next nonce for the specified sender.
|
||||
// Note that this method may not be atomic. Use MpoolPushMessage instead.
|
||||
MpoolGetNonce(context.Context, address.Address) (uint64, error)
|
||||
MpoolSub(context.Context) (<-chan MpoolUpdate, error)
|
||||
MpoolGetNonce(context.Context, address.Address) (uint64, error) //perm:read
|
||||
MpoolSub(context.Context) (<-chan MpoolUpdate, error) //perm:read
|
||||
|
||||
// MpoolClear clears pending messages from the mpool
|
||||
MpoolClear(context.Context, bool) error
|
||||
MpoolClear(context.Context, bool) error //perm:write
|
||||
|
||||
// MpoolGetConfig returns (a copy of) the current mpool config
|
||||
MpoolGetConfig(context.Context) (*types.MpoolConfig, error)
|
||||
MpoolGetConfig(context.Context) (*types.MpoolConfig, error) //perm:read
|
||||
// MpoolSetConfig sets the mpool config to (a copy of) the supplied config
|
||||
MpoolSetConfig(context.Context, *types.MpoolConfig) error
|
||||
MpoolSetConfig(context.Context, *types.MpoolConfig) error //perm:admin
|
||||
|
||||
// MethodGroup: Miner
|
||||
|
||||
MinerGetBaseInfo(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*MiningBaseInfo, error)
|
||||
MinerCreateBlock(context.Context, *BlockTemplate) (*types.BlockMsg, error)
|
||||
MinerGetBaseInfo(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*MiningBaseInfo, error) //perm:read
|
||||
MinerCreateBlock(context.Context, *BlockTemplate) (*types.BlockMsg, error) //perm:write
|
||||
|
||||
// // UX ?
|
||||
|
||||
@ -250,32 +261,32 @@ type FullNode interface {
|
||||
// WalletNew creates a new address in the wallet with the given sigType.
|
||||
// Available key types: bls, secp256k1, secp256k1-ledger
|
||||
// Support for numerical types: 1 - secp256k1, 2 - BLS is deprecated
|
||||
WalletNew(context.Context, types.KeyType) (address.Address, error)
|
||||
WalletNew(context.Context, types.KeyType) (address.Address, error) //perm:write
|
||||
// WalletHas indicates whether the given address is in the wallet.
|
||||
WalletHas(context.Context, address.Address) (bool, error)
|
||||
WalletHas(context.Context, address.Address) (bool, error) //perm:write
|
||||
// WalletList lists all the addresses in the wallet.
|
||||
WalletList(context.Context) ([]address.Address, error)
|
||||
WalletList(context.Context) ([]address.Address, error) //perm:write
|
||||
// WalletBalance returns the balance of the given address at the current head of the chain.
|
||||
WalletBalance(context.Context, address.Address) (types.BigInt, error)
|
||||
WalletBalance(context.Context, address.Address) (types.BigInt, error) //perm:read
|
||||
// WalletSign signs the given bytes using the given address.
|
||||
WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error)
|
||||
WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error) //perm:sign
|
||||
// WalletSignMessage signs the given message using the given address.
|
||||
WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error)
|
||||
WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) //perm:sign
|
||||
// WalletVerify takes an address, a signature, and some bytes, and indicates whether the signature is valid.
|
||||
// The address does not have to be in the wallet.
|
||||
WalletVerify(context.Context, address.Address, []byte, *crypto.Signature) (bool, error)
|
||||
WalletVerify(context.Context, address.Address, []byte, *crypto.Signature) (bool, error) //perm:read
|
||||
// WalletDefaultAddress returns the address marked as default in the wallet.
|
||||
WalletDefaultAddress(context.Context) (address.Address, error)
|
||||
WalletDefaultAddress(context.Context) (address.Address, error) //perm:write
|
||||
// WalletSetDefault marks the given address as as the default one.
|
||||
WalletSetDefault(context.Context, address.Address) error
|
||||
WalletSetDefault(context.Context, address.Address) error //perm:write
|
||||
// WalletExport returns the private key of an address in the wallet.
|
||||
WalletExport(context.Context, address.Address) (*types.KeyInfo, error)
|
||||
WalletExport(context.Context, address.Address) (*types.KeyInfo, error) //perm:admin
|
||||
// WalletImport receives a KeyInfo, which includes a private key, and imports it into the wallet.
|
||||
WalletImport(context.Context, *types.KeyInfo) (address.Address, error)
|
||||
WalletImport(context.Context, *types.KeyInfo) (address.Address, error) //perm:admin
|
||||
// WalletDelete deletes an address from the wallet.
|
||||
WalletDelete(context.Context, address.Address) error
|
||||
WalletDelete(context.Context, address.Address) error //perm:admin
|
||||
// WalletValidateAddress validates whether a given string can be decoded as a well-formed address
|
||||
WalletValidateAddress(context.Context, string) (address.Address, error)
|
||||
WalletValidateAddress(context.Context, string) (address.Address, error) //perm:read
|
||||
|
||||
// Other
|
||||
|
||||
@ -284,58 +295,61 @@ type FullNode interface {
|
||||
// retrieval markets as a client
|
||||
|
||||
// ClientImport imports file under the specified path into filestore.
|
||||
ClientImport(ctx context.Context, ref FileRef) (*ImportRes, error)
|
||||
ClientImport(ctx context.Context, ref FileRef) (*ImportRes, error) //perm:admin
|
||||
// ClientRemoveImport removes file import
|
||||
ClientRemoveImport(ctx context.Context, importID multistore.StoreID) error
|
||||
ClientRemoveImport(ctx context.Context, importID multistore.StoreID) error //perm:admin
|
||||
// ClientStartDeal proposes a deal with a miner.
|
||||
ClientStartDeal(ctx context.Context, params *StartDealParams) (*cid.Cid, error)
|
||||
ClientStartDeal(ctx context.Context, params *StartDealParams) (*cid.Cid, error) //perm:admin
|
||||
// ClientStatelessDeal fire-and-forget-proposes an offline deal to a miner without subsequent tracking.
|
||||
ClientStatelessDeal(ctx context.Context, params *StartDealParams) (*cid.Cid, error)
|
||||
ClientStatelessDeal(ctx context.Context, params *StartDealParams) (*cid.Cid, error) //perm:write
|
||||
// ClientGetDealInfo returns the latest information about a given deal.
|
||||
ClientGetDealInfo(context.Context, cid.Cid) (*DealInfo, error)
|
||||
ClientGetDealInfo(context.Context, cid.Cid) (*DealInfo, error) //perm:read
|
||||
// ClientListDeals returns information about the deals made by the local client.
|
||||
ClientListDeals(ctx context.Context) ([]DealInfo, error)
|
||||
ClientListDeals(ctx context.Context) ([]DealInfo, error) //perm:write
|
||||
// ClientGetDealUpdates returns the status of updated deals
|
||||
ClientGetDealUpdates(ctx context.Context) (<-chan DealInfo, error)
|
||||
ClientGetDealUpdates(ctx context.Context) (<-chan DealInfo, error) //perm:write
|
||||
// ClientGetDealStatus returns status given a code
|
||||
ClientGetDealStatus(ctx context.Context, statusCode uint64) (string, error)
|
||||
ClientGetDealStatus(ctx context.Context, statusCode uint64) (string, error) //perm:read
|
||||
// ClientHasLocal indicates whether a certain CID is locally stored.
|
||||
ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error)
|
||||
ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) //perm:write
|
||||
// ClientFindData identifies peers that have a certain file, and returns QueryOffers (one per peer).
|
||||
ClientFindData(ctx context.Context, root cid.Cid, piece *cid.Cid) ([]QueryOffer, error)
|
||||
ClientFindData(ctx context.Context, root cid.Cid, piece *cid.Cid) ([]QueryOffer, error) //perm:read
|
||||
// ClientMinerQueryOffer returns a QueryOffer for the specific miner and file.
|
||||
ClientMinerQueryOffer(ctx context.Context, miner address.Address, root cid.Cid, piece *cid.Cid) (QueryOffer, error)
|
||||
ClientMinerQueryOffer(ctx context.Context, miner address.Address, root cid.Cid, piece *cid.Cid) (QueryOffer, error) //perm:read
|
||||
// ClientRetrieve initiates the retrieval of a file, as specified in the order.
|
||||
ClientRetrieve(ctx context.Context, order RetrievalOrder, ref *FileRef) error
|
||||
ClientRetrieve(ctx context.Context, order RetrievalOrder, ref *FileRef) error //perm:admin
|
||||
// ClientRetrieveWithEvents initiates the retrieval of a file, as specified in the order, and provides a channel
|
||||
// of status updates.
|
||||
ClientRetrieveWithEvents(ctx context.Context, order RetrievalOrder, ref *FileRef) (<-chan marketevents.RetrievalEvent, error)
|
||||
ClientRetrieveWithEvents(ctx context.Context, order RetrievalOrder, ref *FileRef) (<-chan marketevents.RetrievalEvent, error) //perm:admin
|
||||
// ClientQueryAsk returns a signed StorageAsk from the specified miner.
|
||||
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error)
|
||||
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) //perm:read
|
||||
// ClientCalcCommP calculates the CommP and data size of the specified CID
|
||||
ClientDealPieceCID(ctx context.Context, root cid.Cid) (DataCIDSize, error)
|
||||
ClientDealPieceCID(ctx context.Context, root cid.Cid) (DataCIDSize, error) //perm:read
|
||||
// ClientCalcCommP calculates the CommP for a specified file
|
||||
ClientCalcCommP(ctx context.Context, inpath string) (*CommPRet, error)
|
||||
ClientCalcCommP(ctx context.Context, inpath string) (*CommPRet, error) //perm:write
|
||||
// ClientGenCar generates a CAR file for the specified file.
|
||||
ClientGenCar(ctx context.Context, ref FileRef, outpath string) error
|
||||
ClientGenCar(ctx context.Context, ref FileRef, outpath string) error //perm:write
|
||||
// ClientDealSize calculates real deal data size
|
||||
ClientDealSize(ctx context.Context, root cid.Cid) (DataSize, error)
|
||||
ClientDealSize(ctx context.Context, root cid.Cid) (DataSize, error) //perm:read
|
||||
// ClientListTransfers returns the status of all ongoing transfers of data
|
||||
ClientListDataTransfers(ctx context.Context) ([]DataTransferChannel, error)
|
||||
ClientDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error)
|
||||
ClientListDataTransfers(ctx context.Context) ([]DataTransferChannel, error) //perm:write
|
||||
ClientDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error) //perm:write
|
||||
// ClientRestartDataTransfer attempts to restart a data transfer with the given transfer ID and other peer
|
||||
ClientRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error
|
||||
ClientRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error //perm:write
|
||||
// ClientCancelDataTransfer cancels a data transfer with the given transfer ID and other peer
|
||||
ClientCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error
|
||||
ClientCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error //perm:write
|
||||
// ClientRetrieveTryRestartInsufficientFunds attempts to restart stalled retrievals on a given payment channel
|
||||
// which are stuck due to insufficient funds
|
||||
ClientRetrieveTryRestartInsufficientFunds(ctx context.Context, paymentChannel address.Address) error
|
||||
ClientRetrieveTryRestartInsufficientFunds(ctx context.Context, paymentChannel address.Address) error //perm:write
|
||||
|
||||
// ClientCancelRetrievalDeal cancels an ongoing retrieval deal based on DealID
|
||||
ClientCancelRetrievalDeal(ctx context.Context, dealid retrievalmarket.DealID) error //perm:write
|
||||
|
||||
// ClientUnimport removes references to the specified file from filestore
|
||||
//ClientUnimport(path string)
|
||||
|
||||
// ClientListImports lists imported files and their root CIDs
|
||||
ClientListImports(ctx context.Context) ([]Import, error)
|
||||
ClientListImports(ctx context.Context) ([]Import, error) //perm:write
|
||||
|
||||
//ClientListAsks() []Ask
|
||||
|
||||
@ -349,149 +363,258 @@ type FullNode interface {
|
||||
// StateCall applies the message to the tipset's parent state. The
|
||||
// message is not applied on-top-of the messages in the passed-in
|
||||
// tipset.
|
||||
StateCall(context.Context, *types.Message, types.TipSetKey) (*InvocResult, error)
|
||||
StateCall(context.Context, *types.Message, types.TipSetKey) (*InvocResult, error) //perm:read
|
||||
// StateReplay replays a given message, assuming it was included in a block in the specified tipset.
|
||||
// If no tipset key is provided, the appropriate tipset is looked up.
|
||||
StateReplay(context.Context, types.TipSetKey, cid.Cid) (*InvocResult, error)
|
||||
//
|
||||
// If a tipset key is provided, and a replacing message is found on chain,
|
||||
// the method will return an error saying that the message wasn't found
|
||||
//
|
||||
// If no tipset key is provided, the appropriate tipset is looked up, and if
|
||||
// the message was gas-repriced, the on-chain message will be replayed - in
|
||||
// that case the returned InvocResult.MsgCid will not match the Cid param
|
||||
//
|
||||
// If the caller wants to ensure that exactly the requested message was executed,
|
||||
// they MUST check that InvocResult.MsgCid is equal to the provided Cid.
|
||||
// Without this check both the requested and original message may appear as
|
||||
// successfully executed on-chain, which may look like a double-spend.
|
||||
//
|
||||
// A replacing message is a message with a different CID, any of Gas values, and
|
||||
// different signature, but with all other parameters matching (source/destination,
|
||||
// nonce, params, etc.)
|
||||
StateReplay(context.Context, types.TipSetKey, cid.Cid) (*InvocResult, error) //perm:read
|
||||
// StateGetActor returns the indicated actor's nonce and balance.
|
||||
StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error)
|
||||
StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) //perm:read
|
||||
// StateReadState returns the indicated actor's state.
|
||||
StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*ActorState, error)
|
||||
StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*ActorState, error) //perm:read
|
||||
// StateListMessages looks back and returns all messages with a matching to or from address, stopping at the given height.
|
||||
StateListMessages(ctx context.Context, match *MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error)
|
||||
StateListMessages(ctx context.Context, match *MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) //perm:read
|
||||
// StateDecodeParams attempts to decode the provided params, based on the recipient actor address and method number.
|
||||
StateDecodeParams(ctx context.Context, toAddr address.Address, method abi.MethodNum, params []byte, tsk types.TipSetKey) (interface{}, error)
|
||||
StateDecodeParams(ctx context.Context, toAddr address.Address, method abi.MethodNum, params []byte, tsk types.TipSetKey) (interface{}, error) //perm:read
|
||||
|
||||
// StateNetworkName returns the name of the network the node is synced to
|
||||
StateNetworkName(context.Context) (dtypes.NetworkName, error)
|
||||
StateNetworkName(context.Context) (dtypes.NetworkName, error) //perm:read
|
||||
// StateMinerSectors returns info about the given miner's sectors. If the filter bitfield is nil, all sectors are included.
|
||||
StateMinerSectors(context.Context, address.Address, *bitfield.BitField, types.TipSetKey) ([]*miner.SectorOnChainInfo, error)
|
||||
StateMinerSectors(context.Context, address.Address, *bitfield.BitField, types.TipSetKey) ([]*miner.SectorOnChainInfo, error) //perm:read
|
||||
// StateMinerActiveSectors returns info about sectors that a given miner is actively proving.
|
||||
StateMinerActiveSectors(context.Context, address.Address, types.TipSetKey) ([]*miner.SectorOnChainInfo, error)
|
||||
StateMinerActiveSectors(context.Context, address.Address, types.TipSetKey) ([]*miner.SectorOnChainInfo, error) //perm:read
|
||||
// StateMinerProvingDeadline calculates the deadline at some epoch for a proving period
|
||||
// and returns the deadline-related calculations.
|
||||
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error)
|
||||
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) //perm:read
|
||||
// StateMinerPower returns the power of the indicated miner
|
||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
|
||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error) //perm:read
|
||||
// StateMinerInfo returns info about the indicated miner
|
||||
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error)
|
||||
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) //perm:read
|
||||
// StateMinerDeadlines returns all the proving deadlines for the given miner
|
||||
StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) ([]Deadline, error)
|
||||
StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) ([]Deadline, error) //perm:read
|
||||
// StateMinerPartitions returns all partitions in the specified deadline
|
||||
StateMinerPartitions(ctx context.Context, m address.Address, dlIdx uint64, tsk types.TipSetKey) ([]Partition, error)
|
||||
StateMinerPartitions(ctx context.Context, m address.Address, dlIdx uint64, tsk types.TipSetKey) ([]Partition, error) //perm:read
|
||||
// StateMinerFaults returns a bitfield indicating the faulty sectors of the given miner
|
||||
StateMinerFaults(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error)
|
||||
StateMinerFaults(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) //perm:read
|
||||
// StateAllMinerFaults returns all non-expired Faults that occur within lookback epochs of the given tipset
|
||||
StateAllMinerFaults(ctx context.Context, lookback abi.ChainEpoch, ts types.TipSetKey) ([]*Fault, error)
|
||||
StateAllMinerFaults(ctx context.Context, lookback abi.ChainEpoch, ts types.TipSetKey) ([]*Fault, error) //perm:read
|
||||
// StateMinerRecoveries returns a bitfield indicating the recovering sectors of the given miner
|
||||
StateMinerRecoveries(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error)
|
||||
StateMinerRecoveries(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) //perm:read
|
||||
// StateMinerInitialPledgeCollateral returns the precommit deposit for the specified miner's sector
|
||||
StateMinerPreCommitDepositForPower(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error)
|
||||
StateMinerPreCommitDepositForPower(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) //perm:read
|
||||
// StateMinerInitialPledgeCollateral returns the initial pledge collateral for the specified miner's sector
|
||||
StateMinerInitialPledgeCollateral(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error)
|
||||
StateMinerInitialPledgeCollateral(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) //perm:read
|
||||
// StateMinerAvailableBalance returns the portion of a miner's balance that can be withdrawn or spent
|
||||
StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
||||
StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) //perm:read
|
||||
// StateMinerSectorAllocated checks if a sector is allocated
|
||||
StateMinerSectorAllocated(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (bool, error)
|
||||
StateMinerSectorAllocated(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (bool, error) //perm:read
|
||||
// StateSectorPreCommitInfo returns the PreCommit info for the specified miner's sector
|
||||
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error)
|
||||
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) //perm:read
|
||||
// StateSectorGetInfo returns the on-chain info for the specified miner's sector. Returns null in case the sector info isn't found
|
||||
// NOTE: returned info.Expiration may not be accurate in some cases, use StateSectorExpiration to get accurate
|
||||
// expiration epoch
|
||||
StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
||||
StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error) //perm:read
|
||||
// StateSectorExpiration returns epoch at which given sector will expire
|
||||
StateSectorExpiration(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorExpiration, error)
|
||||
StateSectorExpiration(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorExpiration, error) //perm:read
|
||||
// StateSectorPartition finds deadline/partition with the specified sector
|
||||
StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*miner.SectorLocation, error)
|
||||
StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*miner.SectorLocation, error) //perm:read
|
||||
// StateSearchMsg searches for a message in the chain, and returns its receipt and the tipset where it was executed
|
||||
StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error)
|
||||
//
|
||||
// NOTE: If a replacing message is found on chain, this method will return
|
||||
// a MsgLookup for the replacing message - the MsgLookup.Message will be a different
|
||||
// CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the
|
||||
// result of the execution of the replacing message.
|
||||
//
|
||||
// If the caller wants to ensure that exactly the requested message was executed,
|
||||
// they MUST check that MsgLookup.Message is equal to the provided 'cid'.
|
||||
// Without this check both the requested and original message may appear as
|
||||
// successfully executed on-chain, which may look like a double-spend.
|
||||
//
|
||||
// A replacing message is a message with a different CID, any of Gas values, and
|
||||
// different signature, but with all other parameters matching (source/destination,
|
||||
// nonce, params, etc.)
|
||||
StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error) //perm:read
|
||||
// StateSearchMsgLimited looks back up to limit epochs in the chain for a message, and returns its receipt and the tipset where it was executed
|
||||
StateSearchMsgLimited(ctx context.Context, msg cid.Cid, limit abi.ChainEpoch) (*MsgLookup, error)
|
||||
//
|
||||
// NOTE: If a replacing message is found on chain, this method will return
|
||||
// a MsgLookup for the replacing message - the MsgLookup.Message will be a different
|
||||
// CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the
|
||||
// result of the execution of the replacing message.
|
||||
//
|
||||
// If the caller wants to ensure that exactly the requested message was executed,
|
||||
// they MUST check that MsgLookup.Message is equal to the provided 'cid'.
|
||||
// Without this check both the requested and original message may appear as
|
||||
// successfully executed on-chain, which may look like a double-spend.
|
||||
//
|
||||
// A replacing message is a message with a different CID, any of Gas values, and
|
||||
// different signature, but with all other parameters matching (source/destination,
|
||||
// nonce, params, etc.)
|
||||
StateSearchMsgLimited(ctx context.Context, msg cid.Cid, limit abi.ChainEpoch) (*MsgLookup, error) //perm:read
|
||||
// StateWaitMsg looks back in the chain for a message. If not found, it blocks until the
|
||||
// message arrives on chain, and gets to the indicated confidence depth.
|
||||
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*MsgLookup, error)
|
||||
//
|
||||
// NOTE: If a replacing message is found on chain, this method will return
|
||||
// a MsgLookup for the replacing message - the MsgLookup.Message will be a different
|
||||
// CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the
|
||||
// result of the execution of the replacing message.
|
||||
//
|
||||
// If the caller wants to ensure that exactly the requested message was executed,
|
||||
// they MUST check that MsgLookup.Message is equal to the provided 'cid'.
|
||||
// Without this check both the requested and original message may appear as
|
||||
// successfully executed on-chain, which may look like a double-spend.
|
||||
//
|
||||
// A replacing message is a message with a different CID, any of Gas values, and
|
||||
// different signature, but with all other parameters matching (source/destination,
|
||||
// nonce, params, etc.)
|
||||
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*MsgLookup, error) //perm:read
|
||||
// StateWaitMsgLimited looks back up to limit epochs in the chain for a message.
|
||||
// If not found, it blocks until the message arrives on chain, and gets to the
|
||||
// indicated confidence depth.
|
||||
StateWaitMsgLimited(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch) (*MsgLookup, error)
|
||||
//
|
||||
// NOTE: If a replacing message is found on chain, this method will return
|
||||
// a MsgLookup for the replacing message - the MsgLookup.Message will be a different
|
||||
// CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the
|
||||
// result of the execution of the replacing message.
|
||||
//
|
||||
// If the caller wants to ensure that exactly the requested message was executed,
|
||||
// they MUST check that MsgLookup.Message is equal to the provided 'cid'.
|
||||
// Without this check both the requested and original message may appear as
|
||||
// successfully executed on-chain, which may look like a double-spend.
|
||||
//
|
||||
// A replacing message is a message with a different CID, any of Gas values, and
|
||||
// different signature, but with all other parameters matching (source/destination,
|
||||
// nonce, params, etc.)
|
||||
StateWaitMsgLimited(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch) (*MsgLookup, error) //perm:read
|
||||
// StateListMiners returns the addresses of every miner that has claimed power in the Power Actor
|
||||
StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error)
|
||||
StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error) //perm:read
|
||||
// StateListActors returns the addresses of every actor in the state
|
||||
StateListActors(context.Context, types.TipSetKey) ([]address.Address, error)
|
||||
StateListActors(context.Context, types.TipSetKey) ([]address.Address, error) //perm:read
|
||||
// StateMarketBalance looks up the Escrow and Locked balances of the given address in the Storage Market
|
||||
StateMarketBalance(context.Context, address.Address, types.TipSetKey) (MarketBalance, error)
|
||||
StateMarketBalance(context.Context, address.Address, types.TipSetKey) (MarketBalance, error) //perm:read
|
||||
// StateMarketParticipants returns the Escrow and Locked balances of every participant in the Storage Market
|
||||
StateMarketParticipants(context.Context, types.TipSetKey) (map[string]MarketBalance, error)
|
||||
StateMarketParticipants(context.Context, types.TipSetKey) (map[string]MarketBalance, error) //perm:read
|
||||
// StateMarketDeals returns information about every deal in the Storage Market
|
||||
StateMarketDeals(context.Context, types.TipSetKey) (map[string]MarketDeal, error)
|
||||
StateMarketDeals(context.Context, types.TipSetKey) (map[string]MarketDeal, error) //perm:read
|
||||
// StateMarketStorageDeal returns information about the indicated deal
|
||||
StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*MarketDeal, error)
|
||||
StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*MarketDeal, error) //perm:read
|
||||
// StateLookupID retrieves the ID address of the given address
|
||||
StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error)
|
||||
StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error) //perm:read
|
||||
// StateAccountKey returns the public key address of the given ID address
|
||||
StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error)
|
||||
StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error) //perm:read
|
||||
// StateChangedActors returns all the actors whose states change between the two given state CIDs
|
||||
// TODO: Should this take tipset keys instead?
|
||||
StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error)
|
||||
// StateGetReceipt returns the message receipt for the given message
|
||||
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
|
||||
StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) //perm:read
|
||||
// StateGetReceipt returns the message receipt for the given message or for a
|
||||
// matching gas-repriced replacing message
|
||||
//
|
||||
// NOTE: If the requested message was replaced, this method will return the receipt
|
||||
// for the replacing message - if the caller needs the receipt for exactly the
|
||||
// requested message, use StateSearchMsg().Receipt, and check that MsgLookup.Message
|
||||
// is matching the requested CID
|
||||
//
|
||||
// DEPRECATED: Use StateSearchMsg, this method won't be supported in v1 API
|
||||
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) //perm:read
|
||||
// StateMinerSectorCount returns the number of sectors in a miner's sector set and proving set
|
||||
StateMinerSectorCount(context.Context, address.Address, types.TipSetKey) (MinerSectors, error)
|
||||
StateMinerSectorCount(context.Context, address.Address, types.TipSetKey) (MinerSectors, error) //perm:read
|
||||
// StateCompute is a flexible command that applies the given messages on the given tipset.
|
||||
// The messages are run as though the VM were at the provided height.
|
||||
StateCompute(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*ComputeStateOutput, error)
|
||||
//
|
||||
// When called, StateCompute will:
|
||||
// - Load the provided tipset, or use the current chain head if not provided
|
||||
// - Compute the tipset state of the provided tipset on top of the parent state
|
||||
// - (note that this step runs before vmheight is applied to the execution)
|
||||
// - Execute state upgrade if any were scheduled at the epoch, or in null
|
||||
// blocks preceding the tipset
|
||||
// - Call the cron actor on null blocks preceding the tipset
|
||||
// - For each block in the tipset
|
||||
// - Apply messages in blocks in the specified
|
||||
// - Award block reward by calling the reward actor
|
||||
// - Call the cron actor for the current epoch
|
||||
// - If the specified vmheight is higher than the current epoch, apply any
|
||||
// needed state upgrades to the state
|
||||
// - Apply the specified messages to the state
|
||||
//
|
||||
// The vmheight parameter sets VM execution epoch, and can be used to simulate
|
||||
// message execution in different network versions. If the specified vmheight
|
||||
// epoch is higher than the epoch of the specified tipset, any state upgrades
|
||||
// until the vmheight will be executed on the state before applying messages
|
||||
// specified by the user.
|
||||
//
|
||||
// Note that the initial tipset state computation is not affected by the
|
||||
// vmheight parameter - only the messages in the `apply` set are
|
||||
//
|
||||
// If the caller wants to simply compute the state, vmheight should be set to
|
||||
// the epoch of the specified tipset.
|
||||
//
|
||||
// Messages in the `apply` parameter must have the correct nonces, and gas
|
||||
// values set.
|
||||
StateCompute(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*ComputeStateOutput, error) //perm:read
|
||||
// StateVerifierStatus returns the data cap for the given address.
|
||||
// Returns nil if there is no entry in the data cap table for the
|
||||
// address.
|
||||
StateVerifierStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
||||
StateVerifierStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) //perm:read
|
||||
// StateVerifiedClientStatus returns the data cap for the given address.
|
||||
// Returns nil if there is no entry in the data cap table for the
|
||||
// address.
|
||||
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
||||
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) //perm:read
|
||||
// StateVerifiedClientStatus returns the address of the Verified Registry's root key
|
||||
StateVerifiedRegistryRootKey(ctx context.Context, tsk types.TipSetKey) (address.Address, error)
|
||||
StateVerifiedRegistryRootKey(ctx context.Context, tsk types.TipSetKey) (address.Address, error) //perm:read
|
||||
// StateDealProviderCollateralBounds returns the min and max collateral a storage provider
|
||||
// can issue. It takes the deal size and verified status as parameters.
|
||||
StateDealProviderCollateralBounds(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (DealCollateralBounds, error)
|
||||
StateDealProviderCollateralBounds(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (DealCollateralBounds, error) //perm:read
|
||||
|
||||
// StateCirculatingSupply returns the exact circulating supply of Filecoin at the given tipset.
|
||||
// This is not used anywhere in the protocol itself, and is only for external consumption.
|
||||
StateCirculatingSupply(context.Context, types.TipSetKey) (abi.TokenAmount, error)
|
||||
StateCirculatingSupply(context.Context, types.TipSetKey) (abi.TokenAmount, error) //perm:read
|
||||
// StateVMCirculatingSupplyInternal returns an approximation of the circulating supply of Filecoin at the given tipset.
|
||||
// This is the value reported by the runtime interface to actors code.
|
||||
StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (CirculatingSupply, error)
|
||||
StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (CirculatingSupply, error) //perm:read
|
||||
// StateNetworkVersion returns the network version at the given tipset
|
||||
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
||||
StateNetworkVersion(context.Context, types.TipSetKey) (apitypes.NetworkVersion, error) //perm:read
|
||||
|
||||
// MethodGroup: Msig
|
||||
// The Msig methods are used to interact with multisig wallets on the
|
||||
// filecoin network
|
||||
|
||||
// MsigGetAvailableBalance returns the portion of a multisig's balance that can be withdrawn or spent
|
||||
MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
||||
MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) //perm:read
|
||||
// MsigGetVestingSchedule returns the vesting details of a given multisig.
|
||||
MsigGetVestingSchedule(context.Context, address.Address, types.TipSetKey) (MsigVesting, error)
|
||||
MsigGetVestingSchedule(context.Context, address.Address, types.TipSetKey) (MsigVesting, error) //perm:read
|
||||
// MsigGetVested returns the amount of FIL that vested in a multisig in a certain period.
|
||||
// It takes the following params: <multisig address>, <start epoch>, <end epoch>
|
||||
MsigGetVested(context.Context, address.Address, types.TipSetKey, types.TipSetKey) (types.BigInt, error)
|
||||
MsigGetVested(context.Context, address.Address, types.TipSetKey, types.TipSetKey) (types.BigInt, error) //perm:read
|
||||
|
||||
//MsigGetPending returns pending transactions for the given multisig
|
||||
//wallet. Once pending transactions are fully approved, they will no longer
|
||||
//appear here.
|
||||
MsigGetPending(context.Context, address.Address, types.TipSetKey) ([]*MsigTransaction, error)
|
||||
MsigGetPending(context.Context, address.Address, types.TipSetKey) ([]*MsigTransaction, error) //perm:read
|
||||
|
||||
// MsigCreate creates a multisig wallet
|
||||
// It takes the following params: <required number of senders>, <approving addresses>, <unlock duration>
|
||||
//<initial balance>, <sender address of the create msg>, <gas price>
|
||||
MsigCreate(context.Context, uint64, []address.Address, abi.ChainEpoch, types.BigInt, address.Address, types.BigInt) (cid.Cid, error)
|
||||
MsigCreate(context.Context, uint64, []address.Address, abi.ChainEpoch, types.BigInt, address.Address, types.BigInt) (cid.Cid, error) //perm:sign
|
||||
// MsigPropose proposes a multisig message
|
||||
// It takes the following params: <multisig address>, <recipient address>, <value to transfer>,
|
||||
// <sender address of the propose msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
||||
MsigPropose(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error)
|
||||
MsigPropose(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign
|
||||
|
||||
// MsigApprove approves a previously-proposed multisig message by transaction ID
|
||||
// It takes the following params: <multisig address>, <proposed transaction ID> <signer address>
|
||||
MsigApprove(context.Context, address.Address, uint64, address.Address) (cid.Cid, error)
|
||||
MsigApprove(context.Context, address.Address, uint64, address.Address) (cid.Cid, error) //perm:sign
|
||||
|
||||
// MsigApproveTxnHash approves a previously-proposed multisig message, specified
|
||||
// using both transaction ID and a hash of the parameters used in the
|
||||
@ -499,80 +622,80 @@ type FullNode interface {
|
||||
// exactly the transaction you think you are.
|
||||
// It takes the following params: <multisig address>, <proposed message ID>, <proposer address>, <recipient address>, <value to transfer>,
|
||||
// <sender address of the approve msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
||||
MsigApproveTxnHash(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error)
|
||||
MsigApproveTxnHash(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign
|
||||
|
||||
// MsigCancel cancels a previously-proposed multisig message
|
||||
// It takes the following params: <multisig address>, <proposed transaction ID>, <recipient address>, <value to transfer>,
|
||||
// <sender address of the cancel msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
||||
MsigCancel(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error)
|
||||
MsigCancel(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign
|
||||
// MsigAddPropose proposes adding a signer in the multisig
|
||||
// It takes the following params: <multisig address>, <sender address of the propose msg>,
|
||||
// <new signer>, <whether the number of required signers should be increased>
|
||||
MsigAddPropose(context.Context, address.Address, address.Address, address.Address, bool) (cid.Cid, error)
|
||||
MsigAddPropose(context.Context, address.Address, address.Address, address.Address, bool) (cid.Cid, error) //perm:sign
|
||||
// MsigAddApprove approves a previously proposed AddSigner message
|
||||
// It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
||||
// <proposer address>, <new signer>, <whether the number of required signers should be increased>
|
||||
MsigAddApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, bool) (cid.Cid, error)
|
||||
MsigAddApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, bool) (cid.Cid, error) //perm:sign
|
||||
// MsigAddCancel cancels a previously proposed AddSigner message
|
||||
// It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
||||
// <new signer>, <whether the number of required signers should be increased>
|
||||
MsigAddCancel(context.Context, address.Address, address.Address, uint64, address.Address, bool) (cid.Cid, error)
|
||||
MsigAddCancel(context.Context, address.Address, address.Address, uint64, address.Address, bool) (cid.Cid, error) //perm:sign
|
||||
// MsigSwapPropose proposes swapping 2 signers in the multisig
|
||||
// It takes the following params: <multisig address>, <sender address of the propose msg>,
|
||||
// <old signer>, <new signer>
|
||||
MsigSwapPropose(context.Context, address.Address, address.Address, address.Address, address.Address) (cid.Cid, error)
|
||||
MsigSwapPropose(context.Context, address.Address, address.Address, address.Address, address.Address) (cid.Cid, error) //perm:sign
|
||||
// MsigSwapApprove approves a previously proposed SwapSigner
|
||||
// It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
||||
// <proposer address>, <old signer>, <new signer>
|
||||
MsigSwapApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (cid.Cid, error)
|
||||
MsigSwapApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (cid.Cid, error) //perm:sign
|
||||
// MsigSwapCancel cancels a previously proposed SwapSigner message
|
||||
// It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
||||
// <old signer>, <new signer>
|
||||
MsigSwapCancel(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error)
|
||||
MsigSwapCancel(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error) //perm:sign
|
||||
|
||||
// MsigRemoveSigner proposes the removal of a signer from the multisig.
|
||||
// It accepts the multisig to make the change on, the proposer address to
|
||||
// send the message from, the address to be removed, and a boolean
|
||||
// indicating whether or not the signing threshold should be lowered by one
|
||||
// along with the address removal.
|
||||
MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error)
|
||||
MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error) //perm:sign
|
||||
|
||||
// MarketAddBalance adds funds to the market actor
|
||||
MarketAddBalance(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error)
|
||||
MarketAddBalance(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error) //perm:sign
|
||||
// MarketGetReserved gets the amount of funds that are currently reserved for the address
|
||||
MarketGetReserved(ctx context.Context, addr address.Address) (types.BigInt, error)
|
||||
MarketGetReserved(ctx context.Context, addr address.Address) (types.BigInt, error) //perm:sign
|
||||
// MarketReserveFunds reserves funds for a deal
|
||||
MarketReserveFunds(ctx context.Context, wallet address.Address, addr address.Address, amt types.BigInt) (cid.Cid, error)
|
||||
MarketReserveFunds(ctx context.Context, wallet address.Address, addr address.Address, amt types.BigInt) (cid.Cid, error) //perm:sign
|
||||
// MarketReleaseFunds releases funds reserved by MarketReserveFunds
|
||||
MarketReleaseFunds(ctx context.Context, addr address.Address, amt types.BigInt) error
|
||||
MarketReleaseFunds(ctx context.Context, addr address.Address, amt types.BigInt) error //perm:sign
|
||||
// MarketWithdraw withdraws unlocked funds from the market actor
|
||||
MarketWithdraw(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error)
|
||||
MarketWithdraw(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error) //perm:sign
|
||||
|
||||
// MethodGroup: Paych
|
||||
// The Paych methods are for interacting with and managing payment channels
|
||||
|
||||
PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt) (*ChannelInfo, error)
|
||||
PaychGetWaitReady(context.Context, cid.Cid) (address.Address, error)
|
||||
PaychAvailableFunds(ctx context.Context, ch address.Address) (*ChannelAvailableFunds, error)
|
||||
PaychAvailableFundsByFromTo(ctx context.Context, from, to address.Address) (*ChannelAvailableFunds, error)
|
||||
PaychList(context.Context) ([]address.Address, error)
|
||||
PaychStatus(context.Context, address.Address) (*PaychStatus, error)
|
||||
PaychSettle(context.Context, address.Address) (cid.Cid, error)
|
||||
PaychCollect(context.Context, address.Address) (cid.Cid, error)
|
||||
PaychAllocateLane(ctx context.Context, ch address.Address) (uint64, error)
|
||||
PaychNewPayment(ctx context.Context, from, to address.Address, vouchers []VoucherSpec) (*PaymentInfo, error)
|
||||
PaychVoucherCheckValid(context.Context, address.Address, *paych.SignedVoucher) error
|
||||
PaychVoucherCheckSpendable(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error)
|
||||
PaychVoucherCreate(context.Context, address.Address, types.BigInt, uint64) (*VoucherCreateResult, error)
|
||||
PaychVoucherAdd(context.Context, address.Address, *paych.SignedVoucher, []byte, types.BigInt) (types.BigInt, error)
|
||||
PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error)
|
||||
PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error)
|
||||
PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt) (*ChannelInfo, error) //perm:sign
|
||||
PaychGetWaitReady(context.Context, cid.Cid) (address.Address, error) //perm:sign
|
||||
PaychAvailableFunds(ctx context.Context, ch address.Address) (*ChannelAvailableFunds, error) //perm:sign
|
||||
PaychAvailableFundsByFromTo(ctx context.Context, from, to address.Address) (*ChannelAvailableFunds, error) //perm:sign
|
||||
PaychList(context.Context) ([]address.Address, error) //perm:read
|
||||
PaychStatus(context.Context, address.Address) (*PaychStatus, error) //perm:read
|
||||
PaychSettle(context.Context, address.Address) (cid.Cid, error) //perm:sign
|
||||
PaychCollect(context.Context, address.Address) (cid.Cid, error) //perm:sign
|
||||
PaychAllocateLane(ctx context.Context, ch address.Address) (uint64, error) //perm:sign
|
||||
PaychNewPayment(ctx context.Context, from, to address.Address, vouchers []VoucherSpec) (*PaymentInfo, error) //perm:sign
|
||||
PaychVoucherCheckValid(context.Context, address.Address, *paych.SignedVoucher) error //perm:read
|
||||
PaychVoucherCheckSpendable(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error) //perm:read
|
||||
PaychVoucherCreate(context.Context, address.Address, types.BigInt, uint64) (*VoucherCreateResult, error) //perm:sign
|
||||
PaychVoucherAdd(context.Context, address.Address, *paych.SignedVoucher, []byte, types.BigInt) (types.BigInt, error) //perm:write
|
||||
PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error) //perm:write
|
||||
PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error) //perm:sign
|
||||
|
||||
// CreateBackup creates node backup onder the specified file name. The
|
||||
// method requires that the lotus daemon is running with the
|
||||
// LOTUS_BACKUP_BASE_PATH environment variable set to some path, and that
|
||||
// the path specified when calling CreateBackup is within the base path
|
||||
CreateBackup(ctx context.Context, fpath string) error
|
||||
CreateBackup(ctx context.Context, fpath string) error //perm:admin
|
||||
}
|
||||
|
||||
type FileRef struct {
|
||||
@ -607,6 +730,7 @@ type DealInfo struct {
|
||||
ProposalCid cid.Cid
|
||||
State storagemarket.StorageDealStatus
|
||||
Message string // more information about deal state, particularly errors
|
||||
DealStages *storagemarket.DealStages
|
||||
Provider address.Address
|
||||
|
||||
DataRef *storagemarket.DataRef
|
||||
@ -762,7 +886,7 @@ func (o *QueryOffer) Order(client address.Address) RetrievalOrder {
|
||||
Client: client,
|
||||
|
||||
Miner: o.Miner,
|
||||
MinerPeer: o.MinerPeer,
|
||||
MinerPeer: &o.MinerPeer,
|
||||
}
|
||||
}
|
||||
|
||||
@ -781,6 +905,8 @@ type RetrievalOrder struct {
|
||||
Root cid.Cid
|
||||
Piece *cid.Cid
|
||||
Size uint64
|
||||
|
||||
LocalStore *multistore.StoreID // if specified, get data from local store
|
||||
// TODO: support offset
|
||||
Total types.BigInt
|
||||
UnsealPrice types.BigInt
|
||||
@ -788,7 +914,7 @@ type RetrievalOrder struct {
|
||||
PaymentIntervalIncrease uint64
|
||||
Client address.Address
|
||||
Miner address.Address
|
||||
MinerPeer retrievalmarket.RetrievalPeer
|
||||
MinerPeer *retrievalmarket.RetrievalPeer
|
||||
}
|
||||
|
||||
type InvocResult struct {
|
||||
|
@ -8,13 +8,13 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
apitypes "github.com/filecoin-project/lotus/api/types"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
type GatewayAPI interface {
|
||||
type Gateway interface {
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||
ChainHead(ctx context.Context) (*types.TipSet, error)
|
||||
ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error)
|
||||
@ -39,7 +39,7 @@ type GatewayAPI interface {
|
||||
StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error)
|
||||
StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error)
|
||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
|
||||
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
||||
StateNetworkVersion(context.Context, types.TipSetKey) (apitypes.NetworkVersion, error)
|
||||
StateSearchMsg(ctx context.Context, msg cid.Cid) (*MsgLookup, error)
|
||||
StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
||||
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
||||
|
@ -5,6 +5,8 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
@ -28,124 +30,150 @@ import (
|
||||
type StorageMiner interface {
|
||||
Common
|
||||
|
||||
ActorAddress(context.Context) (address.Address, error)
|
||||
ActorAddress(context.Context) (address.Address, error) //perm:read
|
||||
|
||||
ActorSectorSize(context.Context, address.Address) (abi.SectorSize, error)
|
||||
ActorAddressConfig(ctx context.Context) (AddressConfig, error)
|
||||
ActorSectorSize(context.Context, address.Address) (abi.SectorSize, error) //perm:read
|
||||
ActorAddressConfig(ctx context.Context) (AddressConfig, error) //perm:read
|
||||
|
||||
MiningBase(context.Context) (*types.TipSet, error)
|
||||
MiningBase(context.Context) (*types.TipSet, error) //perm:read
|
||||
|
||||
// Temp api for testing
|
||||
PledgeSector(context.Context) (abi.SectorID, error)
|
||||
PledgeSector(context.Context) (abi.SectorID, error) //perm:write
|
||||
|
||||
// Get the status of a given sector by ID
|
||||
SectorsStatus(ctx context.Context, sid abi.SectorNumber, showOnChainInfo bool) (SectorInfo, error)
|
||||
SectorsStatus(ctx context.Context, sid abi.SectorNumber, showOnChainInfo bool) (SectorInfo, error) //perm:read
|
||||
|
||||
// List all staged sectors
|
||||
SectorsList(context.Context) ([]abi.SectorNumber, error)
|
||||
SectorsList(context.Context) ([]abi.SectorNumber, error) //perm:read
|
||||
|
||||
// Get summary info of sectors
|
||||
SectorsSummary(ctx context.Context) (map[SectorState]int, error)
|
||||
SectorsSummary(ctx context.Context) (map[SectorState]int, error) //perm:read
|
||||
|
||||
// List sectors in particular states
|
||||
SectorsListInStates(context.Context, []SectorState) ([]abi.SectorNumber, error)
|
||||
SectorsListInStates(context.Context, []SectorState) ([]abi.SectorNumber, error) //perm:read
|
||||
|
||||
SectorsRefs(context.Context) (map[string][]SealedRef, error)
|
||||
SectorsRefs(context.Context) (map[string][]SealedRef, error) //perm:read
|
||||
|
||||
// SectorStartSealing can be called on sectors in Empty or WaitDeals states
|
||||
// to trigger sealing early
|
||||
SectorStartSealing(context.Context, abi.SectorNumber) error
|
||||
SectorStartSealing(context.Context, abi.SectorNumber) error //perm:write
|
||||
// SectorSetSealDelay sets the time that a newly-created sector
|
||||
// waits for more deals before it starts sealing
|
||||
SectorSetSealDelay(context.Context, time.Duration) error
|
||||
SectorSetSealDelay(context.Context, time.Duration) error //perm:write
|
||||
// SectorGetSealDelay gets the time that a newly-created sector
|
||||
// waits for more deals before it starts sealing
|
||||
SectorGetSealDelay(context.Context) (time.Duration, error)
|
||||
SectorGetSealDelay(context.Context) (time.Duration, error) //perm:read
|
||||
// SectorSetExpectedSealDuration sets the expected time for a sector to seal
|
||||
SectorSetExpectedSealDuration(context.Context, time.Duration) error
|
||||
SectorSetExpectedSealDuration(context.Context, time.Duration) error //perm:write
|
||||
// SectorGetExpectedSealDuration gets the expected time for a sector to seal
|
||||
SectorGetExpectedSealDuration(context.Context) (time.Duration, error)
|
||||
SectorsUpdate(context.Context, abi.SectorNumber, SectorState) error
|
||||
SectorGetExpectedSealDuration(context.Context) (time.Duration, error) //perm:read
|
||||
SectorsUpdate(context.Context, abi.SectorNumber, SectorState) error //perm:admin
|
||||
// SectorRemove removes the sector from storage. It doesn't terminate it on-chain, which can
|
||||
// be done with SectorTerminate. Removing and not terminating live sectors will cause additional penalties.
|
||||
SectorRemove(context.Context, abi.SectorNumber) error
|
||||
SectorRemove(context.Context, abi.SectorNumber) error //perm:admin
|
||||
// SectorTerminate terminates the sector on-chain (adding it to a termination batch first), then
|
||||
// automatically removes it from storage
|
||||
SectorTerminate(context.Context, abi.SectorNumber) error
|
||||
SectorTerminate(context.Context, abi.SectorNumber) error //perm:admin
|
||||
// SectorTerminateFlush immediately sends a terminate message with sectors batched for termination.
|
||||
// Returns null if message wasn't sent
|
||||
SectorTerminateFlush(ctx context.Context) (*cid.Cid, error)
|
||||
SectorTerminateFlush(ctx context.Context) (*cid.Cid, error) //perm:admin
|
||||
// SectorTerminatePending returns a list of pending sector terminations to be sent in the next batch message
|
||||
SectorTerminatePending(ctx context.Context) ([]abi.SectorID, error)
|
||||
SectorMarkForUpgrade(ctx context.Context, id abi.SectorNumber) error
|
||||
|
||||
StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error)
|
||||
StorageLocal(ctx context.Context) (map[stores.ID]string, error)
|
||||
StorageStat(ctx context.Context, id stores.ID) (fsutil.FsStat, error)
|
||||
SectorTerminatePending(ctx context.Context) ([]abi.SectorID, error) //perm:admin
|
||||
SectorMarkForUpgrade(ctx context.Context, id abi.SectorNumber) error //perm:admin
|
||||
|
||||
// WorkerConnect tells the node to connect to workers RPC
|
||||
WorkerConnect(context.Context, string) error
|
||||
WorkerStats(context.Context) (map[uuid.UUID]storiface.WorkerStats, error)
|
||||
WorkerJobs(context.Context) (map[uuid.UUID][]storiface.WorkerJob, error)
|
||||
storiface.WorkerReturn
|
||||
WorkerConnect(context.Context, string) error //perm:admin retry:true
|
||||
WorkerStats(context.Context) (map[uuid.UUID]storiface.WorkerStats, error) //perm:admin
|
||||
WorkerJobs(context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) //perm:admin
|
||||
|
||||
//storiface.WorkerReturn
|
||||
ReturnAddPiece(ctx context.Context, callID storiface.CallID, pi abi.PieceInfo, err *storiface.CallError) error //perm:admin retry:true
|
||||
ReturnSealPreCommit1(ctx context.Context, callID storiface.CallID, p1o storage.PreCommit1Out, err *storiface.CallError) error //perm:admin retry:true
|
||||
ReturnSealPreCommit2(ctx context.Context, callID storiface.CallID, sealed storage.SectorCids, err *storiface.CallError) error //perm:admin retry:true
|
||||
ReturnSealCommit1(ctx context.Context, callID storiface.CallID, out storage.Commit1Out, err *storiface.CallError) error //perm:admin retry:true
|
||||
ReturnSealCommit2(ctx context.Context, callID storiface.CallID, proof storage.Proof, err *storiface.CallError) error //perm:admin retry:true
|
||||
ReturnFinalizeSector(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error //perm:admin retry:true
|
||||
ReturnReleaseUnsealed(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error //perm:admin retry:true
|
||||
ReturnMoveStorage(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error //perm:admin retry:true
|
||||
ReturnUnsealPiece(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error //perm:admin retry:true
|
||||
ReturnReadPiece(ctx context.Context, callID storiface.CallID, ok bool, err *storiface.CallError) error //perm:admin retry:true
|
||||
ReturnFetch(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error //perm:admin retry:true
|
||||
|
||||
// SealingSchedDiag dumps internal sealing scheduler state
|
||||
SealingSchedDiag(ctx context.Context, doSched bool) (interface{}, error)
|
||||
SealingAbort(ctx context.Context, call storiface.CallID) error
|
||||
SealingSchedDiag(ctx context.Context, doSched bool) (interface{}, error) //perm:admin
|
||||
SealingAbort(ctx context.Context, call storiface.CallID) error //perm:admin
|
||||
|
||||
stores.SectorIndex
|
||||
//stores.SectorIndex
|
||||
StorageAttach(context.Context, stores.StorageInfo, fsutil.FsStat) error //perm:admin
|
||||
StorageInfo(context.Context, stores.ID) (stores.StorageInfo, error) //perm:admin
|
||||
StorageReportHealth(context.Context, stores.ID, stores.HealthReport) error //perm:admin
|
||||
StorageDeclareSector(ctx context.Context, storageID stores.ID, s abi.SectorID, ft storiface.SectorFileType, primary bool) error //perm:admin
|
||||
StorageDropSector(ctx context.Context, storageID stores.ID, s abi.SectorID, ft storiface.SectorFileType) error //perm:admin
|
||||
StorageFindSector(ctx context.Context, sector abi.SectorID, ft storiface.SectorFileType, ssize abi.SectorSize, allowFetch bool) ([]stores.SectorStorageInfo, error) //perm:admin
|
||||
StorageBestAlloc(ctx context.Context, allocate storiface.SectorFileType, ssize abi.SectorSize, pathType storiface.PathType) ([]stores.StorageInfo, error) //perm:admin
|
||||
StorageLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) error //perm:admin
|
||||
StorageTryLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) (bool, error) //perm:admin
|
||||
|
||||
MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error
|
||||
MarketListDeals(ctx context.Context) ([]MarketDeal, error)
|
||||
MarketListRetrievalDeals(ctx context.Context) ([]retrievalmarket.ProviderDealState, error)
|
||||
MarketGetDealUpdates(ctx context.Context) (<-chan storagemarket.MinerDeal, error)
|
||||
MarketListIncompleteDeals(ctx context.Context) ([]storagemarket.MinerDeal, error)
|
||||
MarketSetAsk(ctx context.Context, price types.BigInt, verifiedPrice types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error
|
||||
MarketGetAsk(ctx context.Context) (*storagemarket.SignedStorageAsk, error)
|
||||
MarketSetRetrievalAsk(ctx context.Context, rask *retrievalmarket.Ask) error
|
||||
MarketGetRetrievalAsk(ctx context.Context) (*retrievalmarket.Ask, error)
|
||||
MarketListDataTransfers(ctx context.Context) ([]DataTransferChannel, error)
|
||||
MarketDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error)
|
||||
StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error) //perm:admin
|
||||
StorageLocal(ctx context.Context) (map[stores.ID]string, error) //perm:admin
|
||||
StorageStat(ctx context.Context, id stores.ID) (fsutil.FsStat, error) //perm:admin
|
||||
|
||||
MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error //perm:write
|
||||
MarketListDeals(ctx context.Context) ([]MarketDeal, error) //perm:read
|
||||
MarketListRetrievalDeals(ctx context.Context) ([]retrievalmarket.ProviderDealState, error) //perm:read
|
||||
MarketGetDealUpdates(ctx context.Context) (<-chan storagemarket.MinerDeal, error) //perm:read
|
||||
MarketListIncompleteDeals(ctx context.Context) ([]storagemarket.MinerDeal, error) //perm:read
|
||||
MarketSetAsk(ctx context.Context, price types.BigInt, verifiedPrice types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error //perm:admin
|
||||
MarketGetAsk(ctx context.Context) (*storagemarket.SignedStorageAsk, error) //perm:read
|
||||
MarketSetRetrievalAsk(ctx context.Context, rask *retrievalmarket.Ask) error //perm:admin
|
||||
MarketGetRetrievalAsk(ctx context.Context) (*retrievalmarket.Ask, error) //perm:read
|
||||
MarketListDataTransfers(ctx context.Context) ([]DataTransferChannel, error) //perm:write
|
||||
MarketDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error) //perm:write
|
||||
// MarketRestartDataTransfer attempts to restart a data transfer with the given transfer ID and other peer
|
||||
MarketRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error
|
||||
MarketRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error //perm:write
|
||||
// MarketCancelDataTransfer cancels a data transfer with the given transfer ID and other peer
|
||||
MarketCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error
|
||||
MarketPendingDeals(ctx context.Context) (PendingDealInfo, error)
|
||||
MarketPublishPendingDeals(ctx context.Context) error
|
||||
MarketCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error //perm:write
|
||||
MarketPendingDeals(ctx context.Context) (PendingDealInfo, error) //perm:write
|
||||
MarketPublishPendingDeals(ctx context.Context) error //perm:admin
|
||||
|
||||
DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error
|
||||
DealsList(ctx context.Context) ([]MarketDeal, error)
|
||||
DealsConsiderOnlineStorageDeals(context.Context) (bool, error)
|
||||
DealsSetConsiderOnlineStorageDeals(context.Context, bool) error
|
||||
DealsConsiderOnlineRetrievalDeals(context.Context) (bool, error)
|
||||
DealsSetConsiderOnlineRetrievalDeals(context.Context, bool) error
|
||||
DealsPieceCidBlocklist(context.Context) ([]cid.Cid, error)
|
||||
DealsSetPieceCidBlocklist(context.Context, []cid.Cid) error
|
||||
DealsConsiderOfflineStorageDeals(context.Context) (bool, error)
|
||||
DealsSetConsiderOfflineStorageDeals(context.Context, bool) error
|
||||
DealsConsiderOfflineRetrievalDeals(context.Context) (bool, error)
|
||||
DealsSetConsiderOfflineRetrievalDeals(context.Context, bool) error
|
||||
DealsConsiderVerifiedStorageDeals(context.Context) (bool, error)
|
||||
DealsSetConsiderVerifiedStorageDeals(context.Context, bool) error
|
||||
DealsConsiderUnverifiedStorageDeals(context.Context) (bool, error)
|
||||
DealsSetConsiderUnverifiedStorageDeals(context.Context, bool) error
|
||||
DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error //perm:admin
|
||||
DealsList(ctx context.Context) ([]MarketDeal, error) //perm:admin
|
||||
DealsConsiderOnlineStorageDeals(context.Context) (bool, error) //perm:admin
|
||||
DealsSetConsiderOnlineStorageDeals(context.Context, bool) error //perm:admin
|
||||
DealsConsiderOnlineRetrievalDeals(context.Context) (bool, error) //perm:admin
|
||||
DealsSetConsiderOnlineRetrievalDeals(context.Context, bool) error //perm:admin
|
||||
DealsPieceCidBlocklist(context.Context) ([]cid.Cid, error) //perm:admin
|
||||
DealsSetPieceCidBlocklist(context.Context, []cid.Cid) error //perm:admin
|
||||
DealsConsiderOfflineStorageDeals(context.Context) (bool, error) //perm:admin
|
||||
DealsSetConsiderOfflineStorageDeals(context.Context, bool) error //perm:admin
|
||||
DealsConsiderOfflineRetrievalDeals(context.Context) (bool, error) //perm:admin
|
||||
DealsSetConsiderOfflineRetrievalDeals(context.Context, bool) error //perm:admin
|
||||
DealsConsiderVerifiedStorageDeals(context.Context) (bool, error) //perm:admin
|
||||
DealsSetConsiderVerifiedStorageDeals(context.Context, bool) error //perm:admin
|
||||
DealsConsiderUnverifiedStorageDeals(context.Context) (bool, error) //perm:admin
|
||||
DealsSetConsiderUnverifiedStorageDeals(context.Context, bool) error //perm:admin
|
||||
|
||||
StorageAddLocal(ctx context.Context, path string) error
|
||||
StorageAddLocal(ctx context.Context, path string) error //perm:admin
|
||||
|
||||
PiecesListPieces(ctx context.Context) ([]cid.Cid, error)
|
||||
PiecesListCidInfos(ctx context.Context) ([]cid.Cid, error)
|
||||
PiecesGetPieceInfo(ctx context.Context, pieceCid cid.Cid) (*piecestore.PieceInfo, error)
|
||||
PiecesGetCIDInfo(ctx context.Context, payloadCid cid.Cid) (*piecestore.CIDInfo, error)
|
||||
PiecesListPieces(ctx context.Context) ([]cid.Cid, error) //perm:read
|
||||
PiecesListCidInfos(ctx context.Context) ([]cid.Cid, error) //perm:read
|
||||
PiecesGetPieceInfo(ctx context.Context, pieceCid cid.Cid) (*piecestore.PieceInfo, error) //perm:read
|
||||
PiecesGetCIDInfo(ctx context.Context, payloadCid cid.Cid) (*piecestore.CIDInfo, error) //perm:read
|
||||
|
||||
// CreateBackup creates node backup onder the specified file name. The
|
||||
// method requires that the lotus-miner is running with the
|
||||
// LOTUS_BACKUP_BASE_PATH environment variable set to some path, and that
|
||||
// the path specified when calling CreateBackup is within the base path
|
||||
CreateBackup(ctx context.Context, fpath string) error
|
||||
CreateBackup(ctx context.Context, fpath string) error //perm:admin
|
||||
|
||||
CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storage.SectorRef, expensive bool) (map[abi.SectorNumber]string, error)
|
||||
CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storage.SectorRef, expensive bool) (map[abi.SectorNumber]string, error) //perm:admin
|
||||
|
||||
ComputeProof(ctx context.Context, ssi []builtin.SectorInfo, rand abi.PoStRandomness) ([]builtin.PoStProof, error) //perm:read
|
||||
}
|
||||
|
||||
var _ storiface.WorkerReturn = *new(StorageMiner)
|
||||
var _ stores.SectorIndex = *new(StorageMiner)
|
||||
|
||||
type SealRes struct {
|
||||
Err string
|
||||
GoErr error `json:"-"`
|
||||
|
@ -37,6 +37,18 @@ func TestDoesntDependOnFFI(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDoesntDependOnBuild(t *testing.T) {
|
||||
deps, err := exec.Command(goCmd(), "list", "-deps", "github.com/filecoin-project/lotus/api").Output()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, pkg := range strings.Fields(string(deps)) {
|
||||
if pkg == "github.com/filecoin-project/build" {
|
||||
t.Fatal("api depends on filecoin-ffi")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestReturnTypes(t *testing.T) {
|
||||
errType := reflect.TypeOf(new(error)).Elem()
|
||||
bareIface := reflect.TypeOf(new(interface{})).Elem()
|
||||
@ -99,5 +111,5 @@ func TestReturnTypes(t *testing.T) {
|
||||
t.Run("common", tst(new(Common)))
|
||||
t.Run("full", tst(new(FullNode)))
|
||||
t.Run("miner", tst(new(StorageMiner)))
|
||||
t.Run("worker", tst(new(WorkerAPI)))
|
||||
t.Run("worker", tst(new(Worker)))
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ type MsgMeta struct {
|
||||
Extra []byte
|
||||
}
|
||||
|
||||
type WalletAPI interface {
|
||||
type Wallet interface {
|
||||
WalletNew(context.Context, types.KeyType) (address.Address, error)
|
||||
WalletHas(context.Context, address.Address) (bool, error)
|
||||
WalletList(context.Context) ([]address.Address, error)
|
||||
|
@ -2,46 +2,62 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
||||
"github.com/filecoin-project/specs-storage/storage"
|
||||
)
|
||||
|
||||
type WorkerAPI interface {
|
||||
Version(context.Context) (Version, error)
|
||||
// TODO: Info() (name, ...) ?
|
||||
type Worker interface {
|
||||
Version(context.Context) (Version, error) //perm:admin
|
||||
|
||||
TaskTypes(context.Context) (map[sealtasks.TaskType]struct{}, error) // TaskType -> Weight
|
||||
Paths(context.Context) ([]stores.StoragePath, error)
|
||||
Info(context.Context) (storiface.WorkerInfo, error)
|
||||
// TaskType -> Weight
|
||||
TaskTypes(context.Context) (map[sealtasks.TaskType]struct{}, error) //perm:admin
|
||||
Paths(context.Context) ([]stores.StoragePath, error) //perm:admin
|
||||
Info(context.Context) (storiface.WorkerInfo, error) //perm:admin
|
||||
|
||||
storiface.WorkerCalls
|
||||
// storiface.WorkerCalls
|
||||
AddPiece(ctx context.Context, sector storage.SectorRef, pieceSizes []abi.UnpaddedPieceSize, newPieceSize abi.UnpaddedPieceSize, pieceData storage.Data) (storiface.CallID, error) //perm:admin
|
||||
SealPreCommit1(ctx context.Context, sector storage.SectorRef, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storiface.CallID, error) //perm:admin
|
||||
SealPreCommit2(ctx context.Context, sector storage.SectorRef, pc1o storage.PreCommit1Out) (storiface.CallID, error) //perm:admin
|
||||
SealCommit1(ctx context.Context, sector storage.SectorRef, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storiface.CallID, error) //perm:admin
|
||||
SealCommit2(ctx context.Context, sector storage.SectorRef, c1o storage.Commit1Out) (storiface.CallID, error) //perm:admin
|
||||
FinalizeSector(ctx context.Context, sector storage.SectorRef, keepUnsealed []storage.Range) (storiface.CallID, error) //perm:admin
|
||||
ReleaseUnsealed(ctx context.Context, sector storage.SectorRef, safeToFree []storage.Range) (storiface.CallID, error) //perm:admin
|
||||
MoveStorage(ctx context.Context, sector storage.SectorRef, types storiface.SectorFileType) (storiface.CallID, error) //perm:admin
|
||||
UnsealPiece(context.Context, storage.SectorRef, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) (storiface.CallID, error) //perm:admin
|
||||
ReadPiece(context.Context, io.Writer, storage.SectorRef, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) (storiface.CallID, error) //perm:admin
|
||||
Fetch(context.Context, storage.SectorRef, storiface.SectorFileType, storiface.PathType, storiface.AcquireMode) (storiface.CallID, error) //perm:admin
|
||||
|
||||
TaskDisable(ctx context.Context, tt sealtasks.TaskType) error
|
||||
TaskEnable(ctx context.Context, tt sealtasks.TaskType) error
|
||||
TaskDisable(ctx context.Context, tt sealtasks.TaskType) error //perm:admin
|
||||
TaskEnable(ctx context.Context, tt sealtasks.TaskType) error //perm:admin
|
||||
|
||||
// Storage / Other
|
||||
Remove(ctx context.Context, sector abi.SectorID) error
|
||||
Remove(ctx context.Context, sector abi.SectorID) error //perm:admin
|
||||
|
||||
StorageAddLocal(ctx context.Context, path string) error
|
||||
StorageAddLocal(ctx context.Context, path string) error //perm:admin
|
||||
|
||||
// SetEnabled marks the worker as enabled/disabled. Not that this setting
|
||||
// may take a few seconds to propagate to task scheduler
|
||||
SetEnabled(ctx context.Context, enabled bool) error
|
||||
SetEnabled(ctx context.Context, enabled bool) error //perm:admin
|
||||
|
||||
Enabled(ctx context.Context) (bool, error)
|
||||
Enabled(ctx context.Context) (bool, error) //perm:admin
|
||||
|
||||
// WaitQuiet blocks until there are no tasks running
|
||||
WaitQuiet(ctx context.Context) error
|
||||
WaitQuiet(ctx context.Context) error //perm:admin
|
||||
|
||||
// returns a random UUID of worker session, generated randomly when worker
|
||||
// process starts
|
||||
ProcessSession(context.Context) (uuid.UUID, error)
|
||||
ProcessSession(context.Context) (uuid.UUID, error) //perm:admin
|
||||
|
||||
// Like ProcessSession, but returns an error when worker is disabled
|
||||
Session(context.Context) (uuid.UUID, error)
|
||||
Session(context.Context) (uuid.UUID, error) //perm:admin
|
||||
}
|
||||
|
||||
var _ storiface.WorkerCalls = *new(Worker)
|
||||
|
@ -31,13 +31,13 @@ func PermissionedFullAPI(a api.FullNode) api.FullNode {
|
||||
return &out
|
||||
}
|
||||
|
||||
func PermissionedWorkerAPI(a api.WorkerAPI) api.WorkerAPI {
|
||||
func PermissionedWorkerAPI(a api.Worker) api.Worker {
|
||||
var out WorkerStruct
|
||||
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal)
|
||||
return &out
|
||||
}
|
||||
|
||||
func PermissionedWalletAPI(a api.WalletAPI) api.WalletAPI {
|
||||
func PermissionedWalletAPI(a api.Wallet) api.Wallet {
|
||||
var out WalletStruct
|
||||
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal)
|
||||
return &out
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -54,7 +54,7 @@ func NewStorageMinerRPC(ctx context.Context, addr string, requestHeader http.Hea
|
||||
return &res, closer, err
|
||||
}
|
||||
|
||||
func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) (api.WorkerAPI, jsonrpc.ClientCloser, error) {
|
||||
func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) (api.Worker, jsonrpc.ClientCloser, error) {
|
||||
u, err := url.Parse(addr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@ -84,7 +84,7 @@ func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) (
|
||||
}
|
||||
|
||||
// NewGatewayRPC creates a new http jsonrpc client for a gateway node.
|
||||
func NewGatewayRPC(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.GatewayAPI, jsonrpc.ClientCloser, error) {
|
||||
func NewGatewayRPC(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.Gateway, jsonrpc.ClientCloser, error) {
|
||||
var res apistruct.GatewayStruct
|
||||
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
|
||||
[]interface{}{
|
||||
@ -97,7 +97,7 @@ func NewGatewayRPC(ctx context.Context, addr string, requestHeader http.Header,
|
||||
return &res, closer, err
|
||||
}
|
||||
|
||||
func NewWalletRPC(ctx context.Context, addr string, requestHeader http.Header) (api.WalletAPI, jsonrpc.ClientCloser, error) {
|
||||
func NewWalletRPC(ctx context.Context, addr string, requestHeader http.Header) (api.Wallet, jsonrpc.ClientCloser, error) {
|
||||
var res apistruct.WalletStruct
|
||||
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
|
||||
[]interface{}{
|
||||
|
77
api/docgen-openrpc/cmd/docgen_openrpc.go
Normal file
77
api/docgen-openrpc/cmd/docgen_openrpc.go
Normal file
@ -0,0 +1,77 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/filecoin-project/lotus/api/apistruct"
|
||||
docgen_openrpc "github.com/filecoin-project/lotus/api/docgen-openrpc"
|
||||
)
|
||||
|
||||
/*
|
||||
main defines a small program that writes an OpenRPC document describing
|
||||
a Lotus API to stdout.
|
||||
|
||||
If the first argument is "miner", the document will describe the StorageMiner API.
|
||||
If not (no, or any other args), the document will describe the Full API.
|
||||
|
||||
Use:
|
||||
|
||||
go run ./api/openrpc/cmd ["api/api_full.go"|"api/api_storage.go"|"api/api_worker.go"] ["FullNode"|"StorageMiner"|"Worker"]
|
||||
|
||||
With gzip compression: a '-gzip' flag is made available as an optional third argument. Note that position matters.
|
||||
|
||||
go run ./api/openrpc/cmd ["api/api_full.go"|"api/api_storage.go"|"api/api_worker.go"] ["FullNode"|"StorageMiner"|"Worker"] -gzip
|
||||
|
||||
*/
|
||||
|
||||
func main() {
|
||||
doc := docgen_openrpc.NewLotusOpenRPCDocument()
|
||||
|
||||
switch os.Args[2] {
|
||||
case "FullNode":
|
||||
doc.RegisterReceiverName("Filecoin", &apistruct.FullNodeStruct{})
|
||||
case "StorageMiner":
|
||||
doc.RegisterReceiverName("Filecoin", &apistruct.StorageMinerStruct{})
|
||||
case "Worker":
|
||||
doc.RegisterReceiverName("Filecoin", &apistruct.WorkerStruct{})
|
||||
}
|
||||
|
||||
out, err := doc.Discover()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
var jsonOut []byte
|
||||
var writer io.WriteCloser
|
||||
|
||||
// Use os.Args to handle a somewhat hacky flag for the gzip option.
|
||||
// Could use flags package to handle this more cleanly, but that requires changes elsewhere
|
||||
// the scope of which just isn't warranted by this one use case which will usually be run
|
||||
// programmatically anyways.
|
||||
if len(os.Args) > 3 && os.Args[3] == "-gzip" {
|
||||
jsonOut, err = json.Marshal(out)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
writer = gzip.NewWriter(os.Stdout)
|
||||
} else {
|
||||
jsonOut, err = json.MarshalIndent(out, "", " ")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
writer = os.Stdout
|
||||
}
|
||||
|
||||
_, err = writer.Write(jsonOut)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
err = writer.Close()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
172
api/docgen-openrpc/openrpc.go
Normal file
172
api/docgen-openrpc/openrpc.go
Normal file
@ -0,0 +1,172 @@
|
||||
package docgenopenrpc
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"go/ast"
|
||||
"net"
|
||||
"os"
|
||||
"reflect"
|
||||
|
||||
"github.com/alecthomas/jsonschema"
|
||||
go_openrpc_reflect "github.com/etclabscore/go-openrpc-reflect"
|
||||
"github.com/filecoin-project/lotus/api/docgen"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/ipfs/go-cid"
|
||||
meta_schema "github.com/open-rpc/meta-schema"
|
||||
)
|
||||
|
||||
// Comments holds API method comments collected by AST parsing.
|
||||
var Comments map[string]string
|
||||
|
||||
// GroupDocs holds documentation for documentation groups.
|
||||
var GroupDocs map[string]string
|
||||
|
||||
func init() {
|
||||
Comments, GroupDocs = docgen.ParseApiASTInfo(os.Args[1], os.Args[2])
|
||||
}
|
||||
|
||||
// schemaDictEntry represents a type association passed to the jsonschema reflector.
|
||||
type schemaDictEntry struct {
|
||||
example interface{}
|
||||
rawJson string
|
||||
}
|
||||
|
||||
const integerD = `{
|
||||
"title": "number",
|
||||
"type": "number",
|
||||
"description": "Number is a number"
|
||||
}`
|
||||
|
||||
const cidCidD = `{"title": "Content Identifier", "type": "string", "description": "Cid represents a self-describing content addressed identifier. It is formed by a Version, a Codec (which indicates a multicodec-packed content type) and a Multihash."}`
|
||||
|
||||
func OpenRPCSchemaTypeMapper(ty reflect.Type) *jsonschema.Type {
|
||||
unmarshalJSONToJSONSchemaType := func(input string) *jsonschema.Type {
|
||||
var js jsonschema.Type
|
||||
err := json.Unmarshal([]byte(input), &js)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &js
|
||||
}
|
||||
|
||||
if ty.Kind() == reflect.Ptr {
|
||||
ty = ty.Elem()
|
||||
}
|
||||
|
||||
if ty == reflect.TypeOf((*interface{})(nil)).Elem() {
|
||||
return &jsonschema.Type{Type: "object", AdditionalProperties: []byte("true")}
|
||||
}
|
||||
|
||||
// Second, handle other types.
|
||||
// Use a slice instead of a map because it preserves order, as a logic safeguard/fallback.
|
||||
dict := []schemaDictEntry{
|
||||
{cid.Cid{}, cidCidD},
|
||||
}
|
||||
|
||||
for _, d := range dict {
|
||||
if reflect.TypeOf(d.example) == ty {
|
||||
tt := unmarshalJSONToJSONSchemaType(d.rawJson)
|
||||
|
||||
return tt
|
||||
}
|
||||
}
|
||||
|
||||
// Handle primitive types in case there are generic cases
|
||||
// specific to our services.
|
||||
switch ty.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
// Return all integer types as the hex representation integer schemea.
|
||||
ret := unmarshalJSONToJSONSchemaType(integerD)
|
||||
return ret
|
||||
case reflect.Uintptr:
|
||||
return &jsonschema.Type{Type: "number", Title: "uintptr-title"}
|
||||
case reflect.Struct:
|
||||
case reflect.Map:
|
||||
case reflect.Slice, reflect.Array:
|
||||
case reflect.Float32, reflect.Float64:
|
||||
case reflect.Bool:
|
||||
case reflect.String:
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
default:
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewLotusOpenRPCDocument defines application-specific documentation and configuration for its OpenRPC document.
|
||||
func NewLotusOpenRPCDocument() *go_openrpc_reflect.Document {
|
||||
d := &go_openrpc_reflect.Document{}
|
||||
|
||||
// Register "Meta" document fields.
|
||||
// These include getters for
|
||||
// - Servers object
|
||||
// - Info object
|
||||
// - ExternalDocs object
|
||||
//
|
||||
// These objects represent server-specific data that cannot be
|
||||
// reflected.
|
||||
d.WithMeta(&go_openrpc_reflect.MetaT{
|
||||
GetServersFn: func() func(listeners []net.Listener) (*meta_schema.Servers, error) {
|
||||
return func(listeners []net.Listener) (*meta_schema.Servers, error) {
|
||||
return nil, nil
|
||||
}
|
||||
},
|
||||
GetInfoFn: func() (info *meta_schema.InfoObject) {
|
||||
info = &meta_schema.InfoObject{}
|
||||
title := "Lotus RPC API"
|
||||
info.Title = (*meta_schema.InfoObjectProperties)(&title)
|
||||
|
||||
version := build.BuildVersion
|
||||
info.Version = (*meta_schema.InfoObjectVersion)(&version)
|
||||
return info
|
||||
},
|
||||
GetExternalDocsFn: func() (exdocs *meta_schema.ExternalDocumentationObject) {
|
||||
return nil // FIXME
|
||||
},
|
||||
})
|
||||
|
||||
// Use a provided Ethereum default configuration as a base.
|
||||
appReflector := &go_openrpc_reflect.EthereumReflectorT{}
|
||||
|
||||
// Install overrides for the json schema->type map fn used by the jsonschema reflect package.
|
||||
appReflector.FnSchemaTypeMap = func() func(ty reflect.Type) *jsonschema.Type {
|
||||
return OpenRPCSchemaTypeMapper
|
||||
}
|
||||
|
||||
appReflector.FnIsMethodEligible = func(m reflect.Method) bool {
|
||||
for i := 0; i < m.Func.Type().NumOut(); i++ {
|
||||
if m.Func.Type().Out(i).Kind() == reflect.Chan {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return go_openrpc_reflect.EthereumReflector.IsMethodEligible(m)
|
||||
}
|
||||
appReflector.FnGetMethodName = func(moduleName string, r reflect.Value, m reflect.Method, funcDecl *ast.FuncDecl) (string, error) {
|
||||
if m.Name == "ID" {
|
||||
return moduleName + "_ID", nil
|
||||
}
|
||||
if moduleName == "rpc" && m.Name == "Discover" {
|
||||
return "rpc.discover", nil
|
||||
}
|
||||
|
||||
return moduleName + "." + m.Name, nil
|
||||
}
|
||||
|
||||
appReflector.FnGetMethodSummary = func(r reflect.Value, m reflect.Method, funcDecl *ast.FuncDecl) (string, error) {
|
||||
if v, ok := Comments[m.Name]; ok {
|
||||
return v, nil
|
||||
}
|
||||
return "", nil // noComment
|
||||
}
|
||||
|
||||
appReflector.FnSchemaExamples = func(ty reflect.Type) (examples *meta_schema.Examples, err error) {
|
||||
v := docgen.ExampleValue("unknown", ty, ty) // This isn't ideal, but seems to work well enough.
|
||||
return &meta_schema.Examples{
|
||||
meta_schema.AlwaysTrue(v),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Finally, register the configured reflector to the document.
|
||||
d.WithReflector(appReflector)
|
||||
return d
|
||||
}
|
137
api/docgen/cmd/docgen.go
Normal file
137
api/docgen/cmd/docgen.go
Normal file
@ -0,0 +1,137 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/api/apistruct"
|
||||
"github.com/filecoin-project/lotus/api/docgen"
|
||||
)
|
||||
|
||||
func main() {
|
||||
comments, groupComments := docgen.ParseApiASTInfo(os.Args[1], os.Args[2])
|
||||
|
||||
groups := make(map[string]*docgen.MethodGroup)
|
||||
|
||||
var t reflect.Type
|
||||
var permStruct, commonPermStruct reflect.Type
|
||||
|
||||
switch os.Args[2] {
|
||||
case "FullNode":
|
||||
t = reflect.TypeOf(new(struct{ api.FullNode })).Elem()
|
||||
permStruct = reflect.TypeOf(apistruct.FullNodeStruct{}.Internal)
|
||||
commonPermStruct = reflect.TypeOf(apistruct.CommonStruct{}.Internal)
|
||||
case "StorageMiner":
|
||||
t = reflect.TypeOf(new(struct{ api.StorageMiner })).Elem()
|
||||
permStruct = reflect.TypeOf(apistruct.StorageMinerStruct{}.Internal)
|
||||
commonPermStruct = reflect.TypeOf(apistruct.CommonStruct{}.Internal)
|
||||
case "Worker":
|
||||
t = reflect.TypeOf(new(struct{ api.Worker })).Elem()
|
||||
permStruct = reflect.TypeOf(apistruct.WorkerStruct{}.Internal)
|
||||
commonPermStruct = reflect.TypeOf(apistruct.WorkerStruct{}.Internal)
|
||||
default:
|
||||
panic("unknown type")
|
||||
}
|
||||
|
||||
for i := 0; i < t.NumMethod(); i++ {
|
||||
m := t.Method(i)
|
||||
|
||||
groupName := docgen.MethodGroupFromName(m.Name)
|
||||
|
||||
g, ok := groups[groupName]
|
||||
if !ok {
|
||||
g = new(docgen.MethodGroup)
|
||||
g.Header = groupComments[groupName]
|
||||
g.GroupName = groupName
|
||||
groups[groupName] = g
|
||||
}
|
||||
|
||||
var args []interface{}
|
||||
ft := m.Func.Type()
|
||||
for j := 2; j < ft.NumIn(); j++ {
|
||||
inp := ft.In(j)
|
||||
args = append(args, docgen.ExampleValue(m.Name, inp, nil))
|
||||
}
|
||||
|
||||
v, err := json.MarshalIndent(args, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
outv := docgen.ExampleValue(m.Name, ft.Out(0), nil)
|
||||
|
||||
ov, err := json.MarshalIndent(outv, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
g.Methods = append(g.Methods, &docgen.Method{
|
||||
Name: m.Name,
|
||||
Comment: comments[m.Name],
|
||||
InputExample: string(v),
|
||||
ResponseExample: string(ov),
|
||||
})
|
||||
}
|
||||
|
||||
var groupslice []*docgen.MethodGroup
|
||||
for _, g := range groups {
|
||||
groupslice = append(groupslice, g)
|
||||
}
|
||||
|
||||
sort.Slice(groupslice, func(i, j int) bool {
|
||||
return groupslice[i].GroupName < groupslice[j].GroupName
|
||||
})
|
||||
|
||||
fmt.Printf("# Groups\n")
|
||||
|
||||
for _, g := range groupslice {
|
||||
fmt.Printf("* [%s](#%s)\n", g.GroupName, g.GroupName)
|
||||
for _, method := range g.Methods {
|
||||
fmt.Printf(" * [%s](#%s)\n", method.Name, method.Name)
|
||||
}
|
||||
}
|
||||
|
||||
for _, g := range groupslice {
|
||||
g := g
|
||||
fmt.Printf("## %s\n", g.GroupName)
|
||||
fmt.Printf("%s\n\n", g.Header)
|
||||
|
||||
sort.Slice(g.Methods, func(i, j int) bool {
|
||||
return g.Methods[i].Name < g.Methods[j].Name
|
||||
})
|
||||
|
||||
for _, m := range g.Methods {
|
||||
fmt.Printf("### %s\n", m.Name)
|
||||
fmt.Printf("%s\n\n", m.Comment)
|
||||
|
||||
meth, ok := permStruct.FieldByName(m.Name)
|
||||
if !ok {
|
||||
meth, ok = commonPermStruct.FieldByName(m.Name)
|
||||
if !ok {
|
||||
panic("no perms for method: " + m.Name)
|
||||
}
|
||||
}
|
||||
|
||||
perms := meth.Tag.Get("perm")
|
||||
|
||||
fmt.Printf("Perms: %s\n\n", perms)
|
||||
|
||||
if strings.Count(m.InputExample, "\n") > 0 {
|
||||
fmt.Printf("Inputs:\n```json\n%s\n```\n\n", m.InputExample)
|
||||
} else {
|
||||
fmt.Printf("Inputs: `%s`\n\n", m.InputExample)
|
||||
}
|
||||
|
||||
if strings.Count(m.ResponseExample, "\n") > 0 {
|
||||
fmt.Printf("Response:\n```json\n%s\n```\n\n", m.ResponseExample)
|
||||
} else {
|
||||
fmt.Printf("Response: `%s`\n\n", m.ResponseExample)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +1,18 @@
|
||||
package main
|
||||
package docgen
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
"github.com/google/uuid"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-filestore"
|
||||
@ -23,8 +23,6 @@ import (
|
||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
filestore2 "github.com/filecoin-project/go-fil-markets/filestore"
|
||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
@ -36,7 +34,7 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/api/apistruct"
|
||||
apitypes "github.com/filecoin-project/lotus/api/types"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
||||
@ -89,6 +87,8 @@ func init() {
|
||||
addExample(pid)
|
||||
addExample(&pid)
|
||||
|
||||
multistoreIDExample := multistore.StoreID(50)
|
||||
|
||||
addExample(bitfield.NewFromSet([]uint64{5}))
|
||||
addExample(abi.RegisteredSealProof_StackedDrg32GiBV1_1)
|
||||
addExample(abi.RegisteredPoStProof_StackedDrgWindow32GiBV1)
|
||||
@ -118,7 +118,8 @@ func init() {
|
||||
addExample(time.Minute)
|
||||
addExample(datatransfer.TransferID(3))
|
||||
addExample(datatransfer.Ongoing)
|
||||
addExample(multistore.StoreID(50))
|
||||
addExample(multistoreIDExample)
|
||||
addExample(&multistoreIDExample)
|
||||
addExample(retrievalmarket.ClientEventDealAccepted)
|
||||
addExample(retrievalmarket.DealStatusNew)
|
||||
addExample(network.ReachabilityPublic)
|
||||
@ -126,17 +127,17 @@ func init() {
|
||||
addExample(map[string]int{"name": 42})
|
||||
addExample(map[string]time.Time{"name": time.Unix(1615243938, 0).UTC()})
|
||||
addExample(&types.ExecutionTrace{
|
||||
Msg: exampleValue("init", reflect.TypeOf(&types.Message{}), nil).(*types.Message),
|
||||
MsgRct: exampleValue("init", reflect.TypeOf(&types.MessageReceipt{}), nil).(*types.MessageReceipt),
|
||||
Msg: ExampleValue("init", reflect.TypeOf(&types.Message{}), nil).(*types.Message),
|
||||
MsgRct: ExampleValue("init", reflect.TypeOf(&types.MessageReceipt{}), nil).(*types.MessageReceipt),
|
||||
})
|
||||
addExample(map[string]types.Actor{
|
||||
"t01236": exampleValue("init", reflect.TypeOf(types.Actor{}), nil).(types.Actor),
|
||||
"t01236": ExampleValue("init", reflect.TypeOf(types.Actor{}), nil).(types.Actor),
|
||||
})
|
||||
addExample(map[string]api.MarketDeal{
|
||||
"t026363": exampleValue("init", reflect.TypeOf(api.MarketDeal{}), nil).(api.MarketDeal),
|
||||
"t026363": ExampleValue("init", reflect.TypeOf(api.MarketDeal{}), nil).(api.MarketDeal),
|
||||
})
|
||||
addExample(map[string]api.MarketBalance{
|
||||
"t026363": exampleValue("init", reflect.TypeOf(api.MarketBalance{}), nil).(api.MarketBalance),
|
||||
"t026363": ExampleValue("init", reflect.TypeOf(api.MarketBalance{}), nil).(api.MarketBalance),
|
||||
})
|
||||
addExample(map[string]*pubsub.TopicScoreSnapshot{
|
||||
"/blocks": {
|
||||
@ -251,9 +252,17 @@ func init() {
|
||||
sealtasks.TTPreCommit2: {},
|
||||
})
|
||||
addExample(sealtasks.TTCommit2)
|
||||
addExample(apitypes.OpenRPCDocument{
|
||||
"openrpc": "1.2.6",
|
||||
"info": map[string]interface{}{
|
||||
"title": "Lotus RPC API",
|
||||
"version": "1.2.1/generated=2020-11-22T08:22:42-06:00",
|
||||
},
|
||||
"methods": []interface{}{}},
|
||||
)
|
||||
}
|
||||
|
||||
func exampleValue(method string, t, parent reflect.Type) interface{} {
|
||||
func ExampleValue(method string, t, parent reflect.Type) interface{} {
|
||||
v, ok := ExampleValues[t]
|
||||
if ok {
|
||||
return v
|
||||
@ -262,10 +271,10 @@ func exampleValue(method string, t, parent reflect.Type) interface{} {
|
||||
switch t.Kind() {
|
||||
case reflect.Slice:
|
||||
out := reflect.New(t).Elem()
|
||||
reflect.Append(out, reflect.ValueOf(exampleValue(method, t.Elem(), t)))
|
||||
reflect.Append(out, reflect.ValueOf(ExampleValue(method, t.Elem(), t)))
|
||||
return out.Interface()
|
||||
case reflect.Chan:
|
||||
return exampleValue(method, t.Elem(), nil)
|
||||
return ExampleValue(method, t.Elem(), nil)
|
||||
case reflect.Struct:
|
||||
es := exampleStruct(method, t, parent)
|
||||
v := reflect.ValueOf(es).Elem().Interface()
|
||||
@ -274,7 +283,7 @@ func exampleValue(method string, t, parent reflect.Type) interface{} {
|
||||
case reflect.Array:
|
||||
out := reflect.New(t).Elem()
|
||||
for i := 0; i < t.Len(); i++ {
|
||||
out.Index(i).Set(reflect.ValueOf(exampleValue(method, t.Elem(), t)))
|
||||
out.Index(i).Set(reflect.ValueOf(ExampleValue(method, t.Elem(), t)))
|
||||
}
|
||||
return out.Interface()
|
||||
|
||||
@ -299,7 +308,7 @@ func exampleStruct(method string, t, parent reflect.Type) interface{} {
|
||||
continue
|
||||
}
|
||||
if strings.Title(f.Name) == f.Name {
|
||||
ns.Elem().Field(i).Set(reflect.ValueOf(exampleValue(method, f.Type, t)))
|
||||
ns.Elem().Field(i).Set(reflect.ValueOf(ExampleValue(method, f.Type, t)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -331,13 +340,24 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor {
|
||||
return v
|
||||
}
|
||||
|
||||
const noComment = "There are not yet any comments for this method."
|
||||
const NoComment = "There are not yet any comments for this method."
|
||||
|
||||
func parseApiASTInfo(apiFile, iface string) (map[string]string, map[string]string) { //nolint:golint
|
||||
func ParseApiASTInfo(apiFile, iface string) (comments map[string]string, groupDocs map[string]string) { //nolint:golint
|
||||
fset := token.NewFileSet()
|
||||
pkgs, err := parser.ParseDir(fset, "./api", nil, parser.AllErrors|parser.ParseComments)
|
||||
apiDir, err := filepath.Abs("./api")
|
||||
if err != nil {
|
||||
fmt.Println("./api filepath absolute error: ", err)
|
||||
return
|
||||
}
|
||||
apiFile, err = filepath.Abs(apiFile)
|
||||
if err != nil {
|
||||
fmt.Println("filepath absolute error: ", err, "file:", apiFile)
|
||||
return
|
||||
}
|
||||
pkgs, err := parser.ParseDir(fset, apiDir, nil, parser.AllErrors|parser.ParseComments)
|
||||
if err != nil {
|
||||
fmt.Println("parse error: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
ap := pkgs["api"]
|
||||
@ -349,14 +369,14 @@ func parseApiASTInfo(apiFile, iface string) (map[string]string, map[string]strin
|
||||
v := &Visitor{iface, make(map[string]ast.Node)}
|
||||
ast.Walk(v, pkgs["api"])
|
||||
|
||||
groupDocs := make(map[string]string)
|
||||
out := make(map[string]string)
|
||||
comments = make(map[string]string)
|
||||
groupDocs = make(map[string]string)
|
||||
for mn, node := range v.Methods {
|
||||
cs := cmap.Filter(node).Comments()
|
||||
if len(cs) == 0 {
|
||||
out[mn] = noComment
|
||||
filteredComments := cmap.Filter(node).Comments()
|
||||
if len(filteredComments) == 0 {
|
||||
comments[mn] = NoComment
|
||||
} else {
|
||||
for _, c := range cs {
|
||||
for _, c := range filteredComments {
|
||||
if strings.HasPrefix(c.Text(), "MethodGroup:") {
|
||||
parts := strings.Split(c.Text(), "\n")
|
||||
groupName := strings.TrimSpace(parts[0][12:])
|
||||
@ -367,15 +387,19 @@ func parseApiASTInfo(apiFile, iface string) (map[string]string, map[string]strin
|
||||
}
|
||||
}
|
||||
|
||||
last := cs[len(cs)-1].Text()
|
||||
l := len(filteredComments) - 1
|
||||
if len(filteredComments) > 1 {
|
||||
l = len(filteredComments) - 2
|
||||
}
|
||||
last := filteredComments[l].Text()
|
||||
if !strings.HasPrefix(last, "MethodGroup:") {
|
||||
out[mn] = last
|
||||
comments[mn] = last
|
||||
} else {
|
||||
out[mn] = noComment
|
||||
comments[mn] = NoComment
|
||||
}
|
||||
}
|
||||
}
|
||||
return out, groupDocs
|
||||
return comments, groupDocs
|
||||
}
|
||||
|
||||
type MethodGroup struct {
|
||||
@ -391,7 +415,7 @@ type Method struct {
|
||||
ResponseExample string
|
||||
}
|
||||
|
||||
func methodGroupFromName(mn string) string {
|
||||
func MethodGroupFromName(mn string) string {
|
||||
i := strings.IndexFunc(mn[1:], func(r rune) bool {
|
||||
return unicode.IsUpper(r)
|
||||
})
|
||||
@ -400,126 +424,3 @@ func methodGroupFromName(mn string) string {
|
||||
}
|
||||
return mn[:i+1]
|
||||
}
|
||||
|
||||
func main() {
|
||||
comments, groupComments := parseApiASTInfo(os.Args[1], os.Args[2])
|
||||
|
||||
groups := make(map[string]*MethodGroup)
|
||||
|
||||
var t reflect.Type
|
||||
var permStruct, commonPermStruct reflect.Type
|
||||
|
||||
switch os.Args[2] {
|
||||
case "FullNode":
|
||||
t = reflect.TypeOf(new(struct{ api.FullNode })).Elem()
|
||||
permStruct = reflect.TypeOf(apistruct.FullNodeStruct{}.Internal)
|
||||
commonPermStruct = reflect.TypeOf(apistruct.CommonStruct{}.Internal)
|
||||
case "StorageMiner":
|
||||
t = reflect.TypeOf(new(struct{ api.StorageMiner })).Elem()
|
||||
permStruct = reflect.TypeOf(apistruct.StorageMinerStruct{}.Internal)
|
||||
commonPermStruct = reflect.TypeOf(apistruct.CommonStruct{}.Internal)
|
||||
case "WorkerAPI":
|
||||
t = reflect.TypeOf(new(struct{ api.WorkerAPI })).Elem()
|
||||
permStruct = reflect.TypeOf(apistruct.WorkerStruct{}.Internal)
|
||||
commonPermStruct = reflect.TypeOf(apistruct.WorkerStruct{}.Internal)
|
||||
default:
|
||||
panic("unknown type")
|
||||
}
|
||||
|
||||
for i := 0; i < t.NumMethod(); i++ {
|
||||
m := t.Method(i)
|
||||
|
||||
groupName := methodGroupFromName(m.Name)
|
||||
|
||||
g, ok := groups[groupName]
|
||||
if !ok {
|
||||
g = new(MethodGroup)
|
||||
g.Header = groupComments[groupName]
|
||||
g.GroupName = groupName
|
||||
groups[groupName] = g
|
||||
}
|
||||
|
||||
var args []interface{}
|
||||
ft := m.Func.Type()
|
||||
for j := 2; j < ft.NumIn(); j++ {
|
||||
inp := ft.In(j)
|
||||
args = append(args, exampleValue(m.Name, inp, nil))
|
||||
}
|
||||
|
||||
v, err := json.MarshalIndent(args, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
outv := exampleValue(m.Name, ft.Out(0), nil)
|
||||
|
||||
ov, err := json.MarshalIndent(outv, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
g.Methods = append(g.Methods, &Method{
|
||||
Name: m.Name,
|
||||
Comment: comments[m.Name],
|
||||
InputExample: string(v),
|
||||
ResponseExample: string(ov),
|
||||
})
|
||||
}
|
||||
|
||||
var groupslice []*MethodGroup
|
||||
for _, g := range groups {
|
||||
groupslice = append(groupslice, g)
|
||||
}
|
||||
|
||||
sort.Slice(groupslice, func(i, j int) bool {
|
||||
return groupslice[i].GroupName < groupslice[j].GroupName
|
||||
})
|
||||
|
||||
fmt.Printf("# Groups\n")
|
||||
|
||||
for _, g := range groupslice {
|
||||
fmt.Printf("* [%s](#%s)\n", g.GroupName, g.GroupName)
|
||||
for _, method := range g.Methods {
|
||||
fmt.Printf(" * [%s](#%s)\n", method.Name, method.Name)
|
||||
}
|
||||
}
|
||||
|
||||
for _, g := range groupslice {
|
||||
g := g
|
||||
fmt.Printf("## %s\n", g.GroupName)
|
||||
fmt.Printf("%s\n\n", g.Header)
|
||||
|
||||
sort.Slice(g.Methods, func(i, j int) bool {
|
||||
return g.Methods[i].Name < g.Methods[j].Name
|
||||
})
|
||||
|
||||
for _, m := range g.Methods {
|
||||
fmt.Printf("### %s\n", m.Name)
|
||||
fmt.Printf("%s\n\n", m.Comment)
|
||||
|
||||
meth, ok := permStruct.FieldByName(m.Name)
|
||||
if !ok {
|
||||
meth, ok = commonPermStruct.FieldByName(m.Name)
|
||||
if !ok {
|
||||
panic("no perms for method: " + m.Name)
|
||||
}
|
||||
}
|
||||
|
||||
perms := meth.Tag.Get("perm")
|
||||
|
||||
fmt.Printf("Perms: %s\n\n", perms)
|
||||
|
||||
if strings.Count(m.InputExample, "\n") > 0 {
|
||||
fmt.Printf("Inputs:\n```json\n%s\n```\n\n", m.InputExample)
|
||||
} else {
|
||||
fmt.Printf("Inputs: `%s`\n\n", m.InputExample)
|
||||
}
|
||||
|
||||
if strings.Count(m.ResponseExample, "\n") > 0 {
|
||||
fmt.Printf("Response:\n```json\n%s\n```\n\n", m.ResponseExample)
|
||||
} else {
|
||||
fmt.Printf("Response: `%s`\n\n", m.ResponseExample)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
address "github.com/filecoin-project/go-address"
|
||||
bitfield "github.com/filecoin-project/go-bitfield"
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
retrievalmarket "github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
storagemarket "github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||
auth "github.com/filecoin-project/go-jsonrpc/auth"
|
||||
multistore "github.com/filecoin-project/go-multistore"
|
||||
@ -18,6 +19,7 @@ import (
|
||||
dline "github.com/filecoin-project/go-state-types/dline"
|
||||
network "github.com/filecoin-project/go-state-types/network"
|
||||
api "github.com/filecoin-project/lotus/api"
|
||||
apitypes "github.com/filecoin-project/lotus/api/types"
|
||||
miner "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
types "github.com/filecoin-project/lotus/chain/types"
|
||||
marketevents "github.com/filecoin-project/lotus/markets/loggers"
|
||||
@ -444,6 +446,20 @@ func (mr *MockFullNodeMockRecorder) ClientCancelDataTransfer(arg0, arg1, arg2, a
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientCancelDataTransfer", reflect.TypeOf((*MockFullNode)(nil).ClientCancelDataTransfer), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// ClientCancelRetrievalDeal mocks base method
|
||||
func (m *MockFullNode) ClientCancelRetrievalDeal(arg0 context.Context, arg1 retrievalmarket.DealID) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ClientCancelRetrievalDeal", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ClientCancelRetrievalDeal indicates an expected call of ClientCancelRetrievalDeal
|
||||
func (mr *MockFullNodeMockRecorder) ClientCancelRetrievalDeal(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientCancelRetrievalDeal", reflect.TypeOf((*MockFullNode)(nil).ClientCancelRetrievalDeal), arg0, arg1)
|
||||
}
|
||||
|
||||
// ClientDataTransferUpdates mocks base method
|
||||
func (m *MockFullNode) ClientDataTransferUpdates(arg0 context.Context) (<-chan api.DataTransferChannel, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@ -754,6 +770,21 @@ func (mr *MockFullNodeMockRecorder) ClientStartDeal(arg0, arg1 interface{}) *gom
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientStartDeal", reflect.TypeOf((*MockFullNode)(nil).ClientStartDeal), arg0, arg1)
|
||||
}
|
||||
|
||||
// ClientStatelessDeal mocks base method
|
||||
func (m *MockFullNode) ClientStatelessDeal(arg0 context.Context, arg1 *api.StartDealParams) (*cid.Cid, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ClientStatelessDeal", arg0, arg1)
|
||||
ret0, _ := ret[0].(*cid.Cid)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ClientStatelessDeal indicates an expected call of ClientStatelessDeal
|
||||
func (mr *MockFullNodeMockRecorder) ClientStatelessDeal(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientStatelessDeal", reflect.TypeOf((*MockFullNode)(nil).ClientStatelessDeal), arg0, arg1)
|
||||
}
|
||||
|
||||
// Closing mocks base method
|
||||
func (m *MockFullNode) Closing(arg0 context.Context) (<-chan struct{}, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@ -783,6 +814,21 @@ func (mr *MockFullNodeMockRecorder) CreateBackup(arg0, arg1 interface{}) *gomock
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateBackup", reflect.TypeOf((*MockFullNode)(nil).CreateBackup), arg0, arg1)
|
||||
}
|
||||
|
||||
// Discover mocks base method
|
||||
func (m *MockFullNode) Discover(arg0 context.Context) (apitypes.OpenRPCDocument, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Discover", arg0)
|
||||
ret0, _ := ret[0].(apitypes.OpenRPCDocument)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Discover indicates an expected call of Discover
|
||||
func (mr *MockFullNodeMockRecorder) Discover(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Discover", reflect.TypeOf((*MockFullNode)(nil).Discover), arg0)
|
||||
}
|
||||
|
||||
// GasEstimateFeeCap mocks base method
|
||||
func (m *MockFullNode) GasEstimateFeeCap(arg0 context.Context, arg1 *types.Message, arg2 int64, arg3 types.TipSetKey) (big.Int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
@ -23,9 +23,11 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
||||
"github.com/filecoin-project/lotus/extern/storage-sealing/sealiface"
|
||||
"github.com/filecoin-project/lotus/markets/storageadapter"
|
||||
"github.com/filecoin-project/lotus/node"
|
||||
"github.com/filecoin-project/lotus/node/impl"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
|
||||
ipld "github.com/ipfs/go-ipld-format"
|
||||
dag "github.com/ipfs/go-merkledag"
|
||||
@ -183,6 +185,71 @@ func TestPublishDealsBatching(t *testing.T, b APIBuilder, blocktime time.Duratio
|
||||
}
|
||||
}
|
||||
|
||||
func TestBatchDealInput(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) {
|
||||
publishPeriod := 10 * time.Second
|
||||
maxDealsPerMsg := uint64(4)
|
||||
|
||||
// Set max deals per publish deals message to maxDealsPerMsg
|
||||
minerDef := []StorageMiner{{
|
||||
Full: 0,
|
||||
Opts: node.Options(
|
||||
node.Override(
|
||||
new(*storageadapter.DealPublisher),
|
||||
storageadapter.NewDealPublisher(nil, storageadapter.PublishMsgConfig{
|
||||
Period: publishPeriod,
|
||||
MaxDealsPerMsg: maxDealsPerMsg,
|
||||
})),
|
||||
node.Override(new(dtypes.GetSealingConfigFunc), func() (dtypes.GetSealingConfigFunc, error) {
|
||||
return func() (sealiface.Config, error) {
|
||||
return sealiface.Config{
|
||||
MaxWaitDealsSectors: 1,
|
||||
MaxSealingSectors: 1,
|
||||
MaxSealingSectorsForDeals: 2,
|
||||
AlwaysKeepUnsealedCopy: true,
|
||||
}, nil
|
||||
}, nil
|
||||
}),
|
||||
),
|
||||
Preseal: PresealGenesis,
|
||||
}}
|
||||
|
||||
// Create a connect client and miner node
|
||||
n, sn := b(t, OneFull, minerDef)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
s := connectAndStartMining(t, b, blocktime, client, miner)
|
||||
defer s.blockMiner.Stop()
|
||||
|
||||
// Starts a deal and waits until it's published
|
||||
runDealTillSeal := func(rseed int) {
|
||||
res, _, err := CreateClientFile(s.ctx, s.client, rseed)
|
||||
require.NoError(t, err)
|
||||
|
||||
dc := startDeal(t, s.ctx, s.miner, s.client, res.Root, false, startEpoch)
|
||||
waitDealSealed(t, s.ctx, s.miner, s.client, dc, false)
|
||||
}
|
||||
|
||||
// Run maxDealsPerMsg+1 deals in parallel
|
||||
done := make(chan struct{}, maxDealsPerMsg+1)
|
||||
for rseed := 1; rseed <= int(maxDealsPerMsg+1); rseed++ {
|
||||
rseed := rseed
|
||||
go func() {
|
||||
runDealTillSeal(rseed)
|
||||
done <- struct{}{}
|
||||
}()
|
||||
}
|
||||
|
||||
// Wait for maxDealsPerMsg of the deals to be published
|
||||
for i := 0; i < int(maxDealsPerMsg); i++ {
|
||||
<-done
|
||||
}
|
||||
|
||||
sl, err := sn[0].SectorsList(s.ctx)
|
||||
require.NoError(t, err)
|
||||
require.GreaterOrEqual(t, len(sl), 4)
|
||||
require.LessOrEqual(t, len(sl), 5)
|
||||
}
|
||||
|
||||
func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) {
|
||||
s := setupOneClientOneMiner(t, b, blocktime)
|
||||
defer s.blockMiner.Stop()
|
||||
|
@ -61,6 +61,7 @@ type DataTransferChannel struct {
|
||||
Message string
|
||||
OtherPeer peer.ID
|
||||
Transferred uint64
|
||||
Stages *datatransfer.ChannelStages
|
||||
}
|
||||
|
||||
// NewDataTransferChannel constructs an API DataTransferChannel type from full channel state snapshot and a host id
|
||||
|
5
api/types/actors.go
Normal file
5
api/types/actors.go
Normal file
@ -0,0 +1,5 @@
|
||||
package apitypes
|
||||
|
||||
import "github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
type NetworkVersion = network.Version
|
3
api/types/openrpc.go
Normal file
3
api/types/openrpc.go
Normal file
@ -0,0 +1,3 @@
|
||||
package apitypes
|
||||
|
||||
type OpenRPCDocument map[string]interface{}
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/dgraph-io/badger/v2"
|
||||
@ -84,11 +85,11 @@ const (
|
||||
// operation calls after Close() has returned, but it may not happen for
|
||||
// operations in progress. Those are likely to fail with a different error.
|
||||
type Blockstore struct {
|
||||
DB *badger.DB
|
||||
|
||||
// state is guarded by atomic.
|
||||
// state is accessed atomically
|
||||
state int64
|
||||
|
||||
DB *badger.DB
|
||||
|
||||
prefixing bool
|
||||
prefix []byte
|
||||
prefixLen int
|
||||
@ -150,6 +151,20 @@ func (b *Blockstore) CollectGarbage() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Compact runs a synchronous compaction
|
||||
func (b *Blockstore) Compact() error {
|
||||
if atomic.LoadInt64(&b.state) != stateOpen {
|
||||
return ErrBlockstoreClosed
|
||||
}
|
||||
|
||||
nworkers := runtime.NumCPU() / 2
|
||||
if nworkers < 2 {
|
||||
nworkers = 2
|
||||
}
|
||||
|
||||
return b.DB.Flatten(nworkers)
|
||||
}
|
||||
|
||||
// View implements blockstore.Viewer, which leverages zero-copy read-only
|
||||
// access to values.
|
||||
func (b *Blockstore) View(cid cid.Cid, fn func([]byte) error) error {
|
||||
@ -288,9 +303,6 @@ func (b *Blockstore) PutMany(blocks []blocks.Block) error {
|
||||
return ErrBlockstoreClosed
|
||||
}
|
||||
|
||||
batch := b.DB.NewWriteBatch()
|
||||
defer batch.Cancel()
|
||||
|
||||
// toReturn tracks the byte slices to return to the pool, if we're using key
|
||||
// prefixing. we can't return each slice to the pool after each Set, because
|
||||
// badger holds on to the slice.
|
||||
@ -304,6 +316,9 @@ func (b *Blockstore) PutMany(blocks []blocks.Block) error {
|
||||
}()
|
||||
}
|
||||
|
||||
batch := b.DB.NewWriteBatch()
|
||||
defer batch.Cancel()
|
||||
|
||||
for _, block := range blocks {
|
||||
k, pooled := b.PooledStorageKey(block.Cid())
|
||||
if pooled {
|
||||
@ -342,9 +357,6 @@ func (b *Blockstore) DeleteMany(cids []cid.Cid) error {
|
||||
return ErrBlockstoreClosed
|
||||
}
|
||||
|
||||
batch := b.DB.NewWriteBatch()
|
||||
defer batch.Cancel()
|
||||
|
||||
// toReturn tracks the byte slices to return to the pool, if we're using key
|
||||
// prefixing. we can't return each slice to the pool after each Set, because
|
||||
// badger holds on to the slice.
|
||||
@ -358,6 +370,9 @@ func (b *Blockstore) DeleteMany(cids []cid.Cid) error {
|
||||
}()
|
||||
}
|
||||
|
||||
batch := b.DB.NewWriteBatch()
|
||||
defer batch.Cancel()
|
||||
|
||||
for _, cid := range cids {
|
||||
k, pooled := b.PooledStorageKey(cid)
|
||||
if pooled {
|
||||
|
@ -798,15 +798,26 @@ func (s *SplitStore) purgeTracking(cids []cid.Cid) error {
|
||||
}
|
||||
|
||||
func (s *SplitStore) gcHotstore() {
|
||||
if compact, ok := s.hot.(interface{ Compact() error }); ok {
|
||||
log.Infof("compacting hotstore")
|
||||
startCompact := time.Now()
|
||||
err := compact.Compact()
|
||||
if err != nil {
|
||||
log.Warnf("error compacting hotstore: %s", err)
|
||||
return
|
||||
}
|
||||
log.Infow("hotstore compaction done", "took", time.Since(startCompact))
|
||||
}
|
||||
|
||||
if gc, ok := s.hot.(interface{ CollectGarbage() error }); ok {
|
||||
log.Infof("garbage collecting hotstore")
|
||||
startGC := time.Now()
|
||||
err := gc.CollectGarbage()
|
||||
if err != nil {
|
||||
log.Warnf("error garbage collecting hotstore: %s", err)
|
||||
} else {
|
||||
log.Infow("garbage collection done", "took", time.Since(startGC))
|
||||
return
|
||||
}
|
||||
log.Infow("hotstore garbage collection done", "took", time.Since(startGC))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,13 +103,20 @@ func (t *TimedCacheBlockstore) PutMany(bs []blocks.Block) error {
|
||||
}
|
||||
|
||||
func (t *TimedCacheBlockstore) View(k cid.Cid, callback func([]byte) error) error {
|
||||
// The underlying blockstore is always a "mem" blockstore so there's no difference,
|
||||
// from a performance perspective, between view & get. So we call Get to avoid
|
||||
// calling an arbitrary callback while holding a lock.
|
||||
t.mu.RLock()
|
||||
defer t.mu.RUnlock()
|
||||
err := t.active.View(k, callback)
|
||||
block, err := t.active.Get(k)
|
||||
if err == ErrNotFound {
|
||||
err = t.inactive.View(k, callback)
|
||||
block, err = t.inactive.Get(k)
|
||||
}
|
||||
return err
|
||||
t.mu.RUnlock()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return callback(block.RawData())
|
||||
}
|
||||
|
||||
func (t *TimedCacheBlockstore) Get(k cid.Cid) (blocks.Block, error) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
/dns4/bootstrap-6.mainnet.filops.net/tcp/1347/p2p/12D3KooWP5MwCiqdMETF9ub1P3MbCvQCcfconnYHbWg6sUJcDRQQ
|
||||
/dns4/bootstrap-7.mainnet.filops.net/tcp/1347/p2p/12D3KooWRs3aY1p3juFjPy8gPN95PEQChm2QKGUCAdcDCC4EBMKf
|
||||
/dns4/bootstrap-8.mainnet.filops.net/tcp/1347/p2p/12D3KooWScFR7385LTyR4zU1bYdzSiiAb5rnNABfVahPvVSzyTkR
|
||||
/dns4/lotus-bootstrap.forceup.cn/tcp/41778/p2p/12D3KooWFQsv3nRMUevZNWWsY1Wu6NUzUbawnWU5NcRhgKuJA37C
|
||||
/dns4/lotus-bootstrap.ipfsforce.com/tcp/41778/p2p/12D3KooWGhufNmZHF3sv48aQeS13ng5XVJZ9E6qy2Ms4VzqeUsHk
|
||||
/dns4/bootstrap-0.starpool.in/tcp/12757/p2p/12D3KooWGHpBMeZbestVEWkfdnC9u7p6uFHXL1n7m1ZBqsEmiUzz
|
||||
/dns4/bootstrap-1.starpool.in/tcp/12757/p2p/12D3KooWQZrGH1PxSNZPum99M1zNvjNFM33d1AAu5DcvdHptuU7u
|
||||
/dns4/node.glif.io/tcp/1235/p2p/12D3KooWBF8cpp65hp2u9LK5mh19x67ftAam84z9LsfaquTDSBpt
|
||||
|
43
build/openrpc.go
Normal file
43
build/openrpc.go
Normal file
@ -0,0 +1,43 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"encoding/json"
|
||||
|
||||
rice "github.com/GeertJohan/go.rice"
|
||||
|
||||
apitypes "github.com/filecoin-project/lotus/api/types"
|
||||
)
|
||||
|
||||
func mustReadGzippedOpenRPCDocument(data []byte) apitypes.OpenRPCDocument {
|
||||
zr, err := gzip.NewReader(bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
m := apitypes.OpenRPCDocument{}
|
||||
err = json.NewDecoder(zr).Decode(&m)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = zr.Close()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func OpenRPCDiscoverJSON_Full() apitypes.OpenRPCDocument {
|
||||
data := rice.MustFindBox("openrpc").MustBytes("full.json.gz")
|
||||
return mustReadGzippedOpenRPCDocument(data)
|
||||
}
|
||||
|
||||
func OpenRPCDiscoverJSON_Miner() apitypes.OpenRPCDocument {
|
||||
data := rice.MustFindBox("openrpc").MustBytes("miner.json.gz")
|
||||
return mustReadGzippedOpenRPCDocument(data)
|
||||
}
|
||||
|
||||
func OpenRPCDiscoverJSON_Worker() apitypes.OpenRPCDocument {
|
||||
data := rice.MustFindBox("openrpc").MustBytes("worker.json.gz")
|
||||
return mustReadGzippedOpenRPCDocument(data)
|
||||
}
|
BIN
build/openrpc/full.json.gz
Normal file
BIN
build/openrpc/full.json.gz
Normal file
Binary file not shown.
BIN
build/openrpc/miner.json.gz
Normal file
BIN
build/openrpc/miner.json.gz
Normal file
Binary file not shown.
BIN
build/openrpc/worker.json.gz
Normal file
BIN
build/openrpc/worker.json.gz
Normal file
Binary file not shown.
23
build/openrpc_test.go
Normal file
23
build/openrpc_test.go
Normal file
@ -0,0 +1,23 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
apitypes "github.com/filecoin-project/lotus/api/types"
|
||||
)
|
||||
|
||||
func TestOpenRPCDiscoverJSON_Version(t *testing.T) {
|
||||
// openRPCDocVersion is the current OpenRPC version of the API docs.
|
||||
openRPCDocVersion := "1.2.6"
|
||||
|
||||
for i, docFn := range []func() apitypes.OpenRPCDocument{
|
||||
OpenRPCDiscoverJSON_Full,
|
||||
OpenRPCDiscoverJSON_Miner,
|
||||
OpenRPCDiscoverJSON_Worker,
|
||||
} {
|
||||
doc := docFn()
|
||||
if got, ok := doc["openrpc"]; !ok || got != openRPCDocVersion {
|
||||
t.Fatalf("case: %d, want: %s, got: %v, doc: %v", i, openRPCDocVersion, got, doc)
|
||||
}
|
||||
}
|
||||
}
|
@ -37,6 +37,7 @@ func init() {
|
||||
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
|
||||
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
|
||||
policy.SetPreCommitChallengeDelay(abi.ChainEpoch(10))
|
||||
|
||||
BuildType |= Build2k
|
||||
}
|
||||
|
@ -118,5 +118,5 @@ const PackingEfficiencyNum = 4
|
||||
const PackingEfficiencyDenom = 5
|
||||
|
||||
// Actor consts
|
||||
// TODO: Pull from actors when its made not private
|
||||
var MinDealDuration = abi.ChainEpoch(180 * builtin2.EpochsInDay)
|
||||
// TODO: pieceSize unused from actors
|
||||
var MinDealDuration, MaxDealDuration = policy.DealDurationBounds(0)
|
||||
|
@ -72,8 +72,8 @@ var (
|
||||
}()
|
||||
|
||||
// Actor consts
|
||||
// TODO: Pull from actors when its made not private
|
||||
MinDealDuration = abi.ChainEpoch(180 * builtin2.EpochsInDay)
|
||||
// TODO: pieceSize unused from actors
|
||||
MinDealDuration, MaxDealDuration = policy.DealDurationBounds(0)
|
||||
|
||||
PackingEfficiencyNum int64 = 4
|
||||
PackingEfficiencyDenom int64 = 5
|
||||
|
@ -29,7 +29,7 @@ func buildType() string {
|
||||
}
|
||||
|
||||
// BuildVersion is the local build version, set by build system
|
||||
const BuildVersion = "1.5.3"
|
||||
const BuildVersion = "1.7.0-dev"
|
||||
|
||||
func UserVersion() string {
|
||||
return BuildVersion + buildType() + CurrentCommit
|
||||
|
@ -52,7 +52,7 @@ type PoStProof = proof0.PoStProof
|
||||
type FilterEstimate = smoothing0.FilterEstimate
|
||||
|
||||
func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate {
|
||||
return (FilterEstimate)(v0)
|
||||
return (FilterEstimate)(v0) //nolint:unconvert
|
||||
}
|
||||
|
||||
// Doesn't change between actors v0, v2, and v3.
|
||||
|
@ -61,6 +61,7 @@ type State interface {
|
||||
VerifyDealsForActivation(
|
||||
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
|
||||
) (weight, verifiedWeight abi.DealWeight, err error)
|
||||
NextID() (abi.DealID, error)
|
||||
}
|
||||
|
||||
type BalanceTable interface {
|
||||
|
@ -105,6 +105,10 @@ func (s *state0) VerifyDealsForActivation(
|
||||
return market0.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch)
|
||||
}
|
||||
|
||||
func (s *state0) NextID() (abi.DealID, error) {
|
||||
return s.State.NextID, nil
|
||||
}
|
||||
|
||||
type balanceTable0 struct {
|
||||
*adt0.BalanceTable
|
||||
}
|
||||
|
@ -106,6 +106,10 @@ func (s *state2) VerifyDealsForActivation(
|
||||
return w, vw, err
|
||||
}
|
||||
|
||||
func (s *state2) NextID() (abi.DealID, error) {
|
||||
return s.State.NextID, nil
|
||||
}
|
||||
|
||||
type balanceTable2 struct {
|
||||
*adt2.BalanceTable
|
||||
}
|
||||
|
@ -106,6 +106,10 @@ func (s *state3) VerifyDealsForActivation(
|
||||
return w, vw, err
|
||||
}
|
||||
|
||||
func (s *state3) NextID() (abi.DealID, error) {
|
||||
return s.State.NextID, nil
|
||||
}
|
||||
|
||||
type balanceTable3 struct {
|
||||
*adt3.BalanceTable
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ func (s *state0) ForEachPendingTxn(cb func(id int64, txn Transaction) error) err
|
||||
if n <= 0 {
|
||||
return xerrors.Errorf("invalid pending transaction key: %v", key)
|
||||
}
|
||||
return cb(txid, (Transaction)(out))
|
||||
return cb(txid, (Transaction)(out)) //nolint:unconvert
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ func (s *state2) ForEachPendingTxn(cb func(id int64, txn Transaction) error) err
|
||||
if n <= 0 {
|
||||
return xerrors.Errorf("invalid pending transaction key: %v", key)
|
||||
}
|
||||
return cb(txid, (Transaction)(out))
|
||||
return cb(txid, (Transaction)(out)) //nolint:unconvert
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ func (s *state3) ForEachPendingTxn(cb func(id int64, txn Transaction) error) err
|
||||
if n <= 0 {
|
||||
return xerrors.Errorf("invalid pending transaction key: %v", key)
|
||||
}
|
||||
return cb(txid, (Transaction)(out))
|
||||
return cb(txid, (Transaction)(out)) //nolint:unconvert
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -25,9 +25,10 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
ChainFinality = miner3.ChainFinality
|
||||
SealRandomnessLookback = ChainFinality
|
||||
PaychSettleDelay = paych3.SettleDelay
|
||||
ChainFinality = miner3.ChainFinality
|
||||
SealRandomnessLookback = ChainFinality
|
||||
PaychSettleDelay = paych3.SettleDelay
|
||||
MaxPreCommitRandomnessLookback = builtin3.EpochsInDay + SealRandomnessLookback
|
||||
)
|
||||
|
||||
// SetSupportedProofTypes sets supported proof types, across all actor versions.
|
||||
@ -136,6 +137,10 @@ func DealProviderCollateralBounds(
|
||||
}
|
||||
}
|
||||
|
||||
func DealDurationBounds(pieceSize abi.PaddedPieceSize) (min, max abi.ChainEpoch) {
|
||||
return market2.DealDurationBounds(pieceSize)
|
||||
}
|
||||
|
||||
// Sets the challenge window and scales the proving period to match (such that
|
||||
// there are always 48 challenge windows in a proving period).
|
||||
func SetWPoStChallengeWindow(period abi.ChainEpoch) {
|
||||
|
@ -55,11 +55,11 @@ type Events struct {
|
||||
|
||||
heightEvents
|
||||
*hcEvents
|
||||
|
||||
observers []TipSetObserver
|
||||
}
|
||||
|
||||
func NewEvents(ctx context.Context, api eventAPI) *Events {
|
||||
gcConfidence := 2 * build.ForkLengthThreshold
|
||||
|
||||
func NewEventsWithConfidence(ctx context.Context, api eventAPI, gcConfidence abi.ChainEpoch) *Events {
|
||||
tsc := newTSCache(gcConfidence, api)
|
||||
|
||||
e := &Events{
|
||||
@ -77,8 +77,9 @@ func NewEvents(ctx context.Context, api eventAPI) *Events {
|
||||
htHeights: map[abi.ChainEpoch][]uint64{},
|
||||
},
|
||||
|
||||
hcEvents: newHCEvents(ctx, api, tsc, uint64(gcConfidence)),
|
||||
ready: make(chan struct{}),
|
||||
hcEvents: newHCEvents(ctx, api, tsc, uint64(gcConfidence)),
|
||||
ready: make(chan struct{}),
|
||||
observers: []TipSetObserver{},
|
||||
}
|
||||
|
||||
go e.listenHeadChanges(ctx)
|
||||
@ -92,6 +93,11 @@ func NewEvents(ctx context.Context, api eventAPI) *Events {
|
||||
return e
|
||||
}
|
||||
|
||||
func NewEvents(ctx context.Context, api eventAPI) *Events {
|
||||
gcConfidence := 2 * build.ForkLengthThreshold
|
||||
return NewEventsWithConfidence(ctx, api, gcConfidence)
|
||||
}
|
||||
|
||||
func (e *Events) listenHeadChanges(ctx context.Context) {
|
||||
for {
|
||||
if err := e.listenHeadChangesOnce(ctx); err != nil {
|
||||
@ -164,7 +170,7 @@ func (e *Events) listenHeadChangesOnce(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := e.headChange(rev, app); err != nil {
|
||||
if err := e.headChange(ctx, rev, app); err != nil {
|
||||
log.Warnf("headChange failed: %s", err)
|
||||
}
|
||||
|
||||
@ -177,7 +183,7 @@ func (e *Events) listenHeadChangesOnce(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Events) headChange(rev, app []*types.TipSet) error {
|
||||
func (e *Events) headChange(ctx context.Context, rev, app []*types.TipSet) error {
|
||||
if len(app) == 0 {
|
||||
return xerrors.New("events.headChange expected at least one applied tipset")
|
||||
}
|
||||
@ -189,5 +195,39 @@ func (e *Events) headChange(rev, app []*types.TipSet) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := e.observeChanges(ctx, rev, app); err != nil {
|
||||
return err
|
||||
}
|
||||
return e.processHeadChangeEvent(rev, app)
|
||||
}
|
||||
|
||||
// A TipSetObserver receives notifications of tipsets
|
||||
type TipSetObserver interface {
|
||||
Apply(ctx context.Context, ts *types.TipSet) error
|
||||
Revert(ctx context.Context, ts *types.TipSet) error
|
||||
}
|
||||
|
||||
// TODO: add a confidence level so we can have observers with difference levels of confidence
|
||||
func (e *Events) Observe(obs TipSetObserver) error {
|
||||
e.lk.Lock()
|
||||
defer e.lk.Unlock()
|
||||
e.observers = append(e.observers, obs)
|
||||
return nil
|
||||
}
|
||||
|
||||
// observeChanges expects caller to hold e.lk
|
||||
func (e *Events) observeChanges(ctx context.Context, rev, app []*types.TipSet) error {
|
||||
for _, ts := range rev {
|
||||
for _, o := range e.observers {
|
||||
_ = o.Revert(ctx, ts)
|
||||
}
|
||||
}
|
||||
|
||||
for _, ts := range app {
|
||||
for _, o := range e.observers {
|
||||
_ = o.Apply(ctx, ts)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -133,9 +133,22 @@ func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesi
|
||||
}
|
||||
}
|
||||
|
||||
err := setupMsig(remainder.Meta)
|
||||
if err != nil {
|
||||
return 0, nil, nil, xerrors.Errorf("setting up remainder msig: %w", err)
|
||||
if remainder.Type == genesis.TAccount {
|
||||
var ainfo genesis.AccountMeta
|
||||
if err := json.Unmarshal(remainder.Meta, &ainfo); err != nil {
|
||||
return 0, nil, nil, xerrors.Errorf("unmarshaling account meta: %w", err)
|
||||
}
|
||||
|
||||
// TODO: Use builtin.ReserveAddress...
|
||||
value := cbg.CborInt(90)
|
||||
if err := amap.Put(abi.AddrKey(ainfo.Owner), &value); err != nil {
|
||||
return 0, nil, nil, err
|
||||
}
|
||||
} else if remainder.Type == genesis.TMultisig {
|
||||
err := setupMsig(remainder.Meta)
|
||||
if err != nil {
|
||||
return 0, nil, nil, xerrors.Errorf("setting up remainder msig: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
amapaddr, err := amap.Root()
|
||||
|
@ -330,24 +330,18 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
if err := json.Unmarshal(template.RemainderAccount.Meta, &ainfo); err != nil {
|
||||
return nil, nil, xerrors.Errorf("unmarshaling account meta: %w", err)
|
||||
}
|
||||
st, err := cst.Put(ctx, &account0.State{Address: ainfo.Owner})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
_, ok := keyIDs[ainfo.Owner]
|
||||
if ok {
|
||||
return nil, nil, fmt.Errorf("remainder account has already been declared, cannot be assigned 90: %s", ainfo.Owner)
|
||||
}
|
||||
|
||||
err = state.SetActor(builtin.ReserveAddress, &types.Actor{
|
||||
Code: builtin0.AccountActorCodeID,
|
||||
Balance: template.RemainderAccount.Balance,
|
||||
Head: st,
|
||||
})
|
||||
keyIDs[ainfo.Owner] = builtin.ReserveAddress
|
||||
err = createAccountActor(ctx, cst, state, template.RemainderAccount, keyIDs)
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("setting remainder account: %w", err)
|
||||
return nil, nil, xerrors.Errorf("creating remainder acct: %w", err)
|
||||
}
|
||||
|
||||
case genesis.TMultisig:
|
||||
if err = createMultisigAccount(ctx, bs, cst, state, builtin.ReserveAddress, template.RemainderAccount, keyIDs); err != nil {
|
||||
return nil, nil, xerrors.Errorf("failed to set up remainder: %w", err)
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w api.WalletAPI, bt *api.BlockTemplate) (*types.FullBlock, error) {
|
||||
func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w api.Wallet, bt *api.BlockTemplate) (*types.FullBlock, error) {
|
||||
|
||||
pts, err := sm.ChainStore().LoadTipSet(bt.Parents)
|
||||
if err != nil {
|
||||
|
@ -1333,7 +1333,7 @@ readLoop:
|
||||
}
|
||||
|
||||
actorMap := make(map[address.Address]address.Address)
|
||||
actorWallets := make(map[address.Address]api.WalletAPI)
|
||||
actorWallets := make(map[address.Address]api.Wallet)
|
||||
|
||||
for _, m := range msgs {
|
||||
baseNonce := baseNonces[m.Message.From]
|
||||
|
@ -29,13 +29,13 @@ type MpoolNonceAPI interface {
|
||||
// MessageSigner keeps track of nonces per address, and increments the nonce
|
||||
// when signing a message
|
||||
type MessageSigner struct {
|
||||
wallet api.WalletAPI
|
||||
wallet api.Wallet
|
||||
lk sync.Mutex
|
||||
mpool MpoolNonceAPI
|
||||
ds datastore.Batching
|
||||
}
|
||||
|
||||
func NewMessageSigner(wallet api.WalletAPI, mpool MpoolNonceAPI, ds dtypes.MetadataDS) *MessageSigner {
|
||||
func NewMessageSigner(wallet api.Wallet, mpool MpoolNonceAPI, ds dtypes.MetadataDS) *MessageSigner {
|
||||
ds = namespace.Wrap(ds, datastore.NewKey("/message-signer/"))
|
||||
return &MessageSigner{
|
||||
wallet: wallet,
|
||||
|
@ -255,7 +255,7 @@ func (sm *StateManager) Replay(ctx context.Context, ts *types.TipSet, mcid cid.C
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil && err != errHaltExecution {
|
||||
if err != nil && !xerrors.Is(err, errHaltExecution) {
|
||||
return nil, nil, xerrors.Errorf("unexpected error during execution: %w", err)
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package modules
|
||||
package rpcstmgr
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -16,11 +16,11 @@ import (
|
||||
)
|
||||
|
||||
type RPCStateManager struct {
|
||||
gapi api.GatewayAPI
|
||||
gapi api.Gateway
|
||||
cstore *cbor.BasicIpldStore
|
||||
}
|
||||
|
||||
func NewRPCStateManager(api api.GatewayAPI) *RPCStateManager {
|
||||
func NewRPCStateManager(api api.Gateway) *RPCStateManager {
|
||||
cstore := cbor.NewCborStore(blockstore.NewAPIBlockstore(api))
|
||||
return &RPCStateManager{gapi: api, cstore: cstore}
|
||||
}
|
@ -36,7 +36,7 @@ type LedgerKeyInfo struct {
|
||||
Path []uint32
|
||||
}
|
||||
|
||||
var _ api.WalletAPI = (*LedgerWallet)(nil)
|
||||
var _ api.Wallet = (*LedgerWallet)(nil)
|
||||
|
||||
func (lw LedgerWallet) WalletSign(ctx context.Context, signer address.Address, toSign []byte, meta api.MsgMeta) (*crypto.Signature, error) {
|
||||
ki, err := lw.getKeyInfo(signer)
|
||||
@ -227,7 +227,7 @@ func (lw LedgerWallet) WalletNew(ctx context.Context, t types.KeyType) (address.
|
||||
return lw.importKey(lki)
|
||||
}
|
||||
|
||||
func (lw *LedgerWallet) Get() api.WalletAPI {
|
||||
func (lw *LedgerWallet) Get() api.Wallet {
|
||||
if lw == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -24,13 +24,13 @@ type MultiWallet struct {
|
||||
}
|
||||
|
||||
type getif interface {
|
||||
api.WalletAPI
|
||||
api.Wallet
|
||||
|
||||
// workaround for the fact that iface(*struct(nil)) != nil
|
||||
Get() api.WalletAPI
|
||||
Get() api.Wallet
|
||||
}
|
||||
|
||||
func firstNonNil(wallets ...getif) api.WalletAPI {
|
||||
func firstNonNil(wallets ...getif) api.Wallet {
|
||||
for _, w := range wallets {
|
||||
if w.Get() != nil {
|
||||
return w
|
||||
@ -40,8 +40,8 @@ func firstNonNil(wallets ...getif) api.WalletAPI {
|
||||
return nil
|
||||
}
|
||||
|
||||
func nonNil(wallets ...getif) []api.WalletAPI {
|
||||
var out []api.WalletAPI
|
||||
func nonNil(wallets ...getif) []api.Wallet {
|
||||
var out []api.Wallet
|
||||
for _, w := range wallets {
|
||||
if w.Get() == nil {
|
||||
continue
|
||||
@ -53,7 +53,7 @@ func nonNil(wallets ...getif) []api.WalletAPI {
|
||||
return out
|
||||
}
|
||||
|
||||
func (m MultiWallet) find(ctx context.Context, address address.Address, wallets ...getif) (api.WalletAPI, error) {
|
||||
func (m MultiWallet) find(ctx context.Context, address address.Address, wallets ...getif) (api.Wallet, error) {
|
||||
ws := nonNil(wallets...)
|
||||
|
||||
for _, w := range ws {
|
||||
@ -167,4 +167,4 @@ func (m MultiWallet) WalletDelete(ctx context.Context, address address.Address)
|
||||
}
|
||||
}
|
||||
|
||||
var _ api.WalletAPI = MultiWallet{}
|
||||
var _ api.Wallet = MultiWallet{}
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
type RemoteWallet struct {
|
||||
api.WalletAPI
|
||||
api.Wallet
|
||||
}
|
||||
|
||||
func SetupRemoteWallet(info string) func(mctx helpers.MetricsCtx, lc fx.Lifecycle) (*RemoteWallet, error) {
|
||||
@ -41,7 +41,7 @@ func SetupRemoteWallet(info string) func(mctx helpers.MetricsCtx, lc fx.Lifecycl
|
||||
}
|
||||
}
|
||||
|
||||
func (w *RemoteWallet) Get() api.WalletAPI {
|
||||
func (w *RemoteWallet) Get() api.Wallet {
|
||||
if w == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ func (w *LocalWallet) WalletDelete(ctx context.Context, addr address.Address) er
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *LocalWallet) Get() api.WalletAPI {
|
||||
func (w *LocalWallet) Get() api.Wallet {
|
||||
if w == nil {
|
||||
return nil
|
||||
}
|
||||
@ -337,7 +337,7 @@ func (w *LocalWallet) Get() api.WalletAPI {
|
||||
return w
|
||||
}
|
||||
|
||||
var _ api.WalletAPI = &LocalWallet{}
|
||||
var _ api.Wallet = &LocalWallet{}
|
||||
|
||||
func swapMainnetForTestnetPrefix(addr string) (string, error) {
|
||||
aChars := []rune(addr)
|
||||
|
12
cli/auth.go
12
cli/auth.go
@ -13,16 +13,16 @@ import (
|
||||
"github.com/filecoin-project/lotus/node/repo"
|
||||
)
|
||||
|
||||
var authCmd = &cli.Command{
|
||||
var AuthCmd = &cli.Command{
|
||||
Name: "auth",
|
||||
Usage: "Manage RPC permissions",
|
||||
Subcommands: []*cli.Command{
|
||||
authCreateAdminToken,
|
||||
authApiInfoToken,
|
||||
AuthCreateAdminToken,
|
||||
AuthApiInfoToken,
|
||||
},
|
||||
}
|
||||
|
||||
var authCreateAdminToken = &cli.Command{
|
||||
var AuthCreateAdminToken = &cli.Command{
|
||||
Name: "create-token",
|
||||
Usage: "Create token",
|
||||
Flags: []cli.Flag{
|
||||
@ -70,7 +70,7 @@ var authCreateAdminToken = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var authApiInfoToken = &cli.Command{
|
||||
var AuthApiInfoToken = &cli.Command{
|
||||
Name: "api-info",
|
||||
Usage: "Get token with API info required to connect to this node",
|
||||
Flags: []cli.Flag{
|
||||
@ -90,7 +90,7 @@ var authApiInfoToken = &cli.Command{
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
if !cctx.IsSet("perm") {
|
||||
return xerrors.New("--perm flag not set")
|
||||
return xerrors.New("--perm flag not set, use with one of: read, write, sign, admin")
|
||||
}
|
||||
|
||||
perm := cctx.String("perm")
|
||||
|
68
cli/chain.go
68
cli/chain.go
@ -38,31 +38,31 @@ import (
|
||||
types "github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
var chainCmd = &cli.Command{
|
||||
var ChainCmd = &cli.Command{
|
||||
Name: "chain",
|
||||
Usage: "Interact with filecoin blockchain",
|
||||
Subcommands: []*cli.Command{
|
||||
chainHeadCmd,
|
||||
chainGetBlock,
|
||||
chainReadObjCmd,
|
||||
chainDeleteObjCmd,
|
||||
chainStatObjCmd,
|
||||
chainGetMsgCmd,
|
||||
chainSetHeadCmd,
|
||||
chainListCmd,
|
||||
chainGetCmd,
|
||||
chainBisectCmd,
|
||||
chainExportCmd,
|
||||
slashConsensusFault,
|
||||
chainGasPriceCmd,
|
||||
chainInspectUsage,
|
||||
chainDecodeCmd,
|
||||
chainEncodeCmd,
|
||||
chainDisputeSetCmd,
|
||||
ChainHeadCmd,
|
||||
ChainGetBlock,
|
||||
ChainReadObjCmd,
|
||||
ChainDeleteObjCmd,
|
||||
ChainStatObjCmd,
|
||||
ChainGetMsgCmd,
|
||||
ChainSetHeadCmd,
|
||||
ChainListCmd,
|
||||
ChainGetCmd,
|
||||
ChainBisectCmd,
|
||||
ChainExportCmd,
|
||||
SlashConsensusFault,
|
||||
ChainGasPriceCmd,
|
||||
ChainInspectUsage,
|
||||
ChainDecodeCmd,
|
||||
ChainEncodeCmd,
|
||||
ChainDisputeSetCmd,
|
||||
},
|
||||
}
|
||||
|
||||
var chainHeadCmd = &cli.Command{
|
||||
var ChainHeadCmd = &cli.Command{
|
||||
Name: "head",
|
||||
Usage: "Print chain head",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
@ -85,7 +85,7 @@ var chainHeadCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var chainGetBlock = &cli.Command{
|
||||
var ChainGetBlock = &cli.Command{
|
||||
Name: "getblock",
|
||||
Usage: "Get a block and print its details",
|
||||
ArgsUsage: "[blockCid]",
|
||||
@ -176,7 +176,7 @@ func apiMsgCids(in []lapi.Message) []cid.Cid {
|
||||
return out
|
||||
}
|
||||
|
||||
var chainReadObjCmd = &cli.Command{
|
||||
var ChainReadObjCmd = &cli.Command{
|
||||
Name: "read-obj",
|
||||
Usage: "Read the raw bytes of an object",
|
||||
ArgsUsage: "[objectCid]",
|
||||
@ -203,7 +203,7 @@ var chainReadObjCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var chainDeleteObjCmd = &cli.Command{
|
||||
var ChainDeleteObjCmd = &cli.Command{
|
||||
Name: "delete-obj",
|
||||
Usage: "Delete an object from the chain blockstore",
|
||||
Description: "WARNING: Removing wrong objects from the chain blockstore may lead to sync issues",
|
||||
@ -240,7 +240,7 @@ var chainDeleteObjCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var chainStatObjCmd = &cli.Command{
|
||||
var ChainStatObjCmd = &cli.Command{
|
||||
Name: "stat-obj",
|
||||
Usage: "Collect size and ipld link counts for objs",
|
||||
ArgsUsage: "[cid]",
|
||||
@ -287,7 +287,7 @@ var chainStatObjCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var chainGetMsgCmd = &cli.Command{
|
||||
var ChainGetMsgCmd = &cli.Command{
|
||||
Name: "getmessage",
|
||||
Usage: "Get and print a message by its cid",
|
||||
ArgsUsage: "[messageCid]",
|
||||
@ -335,7 +335,7 @@ var chainGetMsgCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var chainSetHeadCmd = &cli.Command{
|
||||
var ChainSetHeadCmd = &cli.Command{
|
||||
Name: "sethead",
|
||||
Usage: "manually set the local nodes head tipset (Caution: normally only used for recovery)",
|
||||
ArgsUsage: "[tipsetkey]",
|
||||
@ -384,7 +384,7 @@ var chainSetHeadCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var chainInspectUsage = &cli.Command{
|
||||
var ChainInspectUsage = &cli.Command{
|
||||
Name: "inspect-usage",
|
||||
Usage: "Inspect block space usage of a given tipset",
|
||||
Flags: []cli.Flag{
|
||||
@ -529,7 +529,7 @@ var chainInspectUsage = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var chainListCmd = &cli.Command{
|
||||
var ChainListCmd = &cli.Command{
|
||||
Name: "list",
|
||||
Aliases: []string{"love"},
|
||||
Usage: "View a segment of the chain",
|
||||
@ -658,7 +658,7 @@ var chainListCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var chainGetCmd = &cli.Command{
|
||||
var ChainGetCmd = &cli.Command{
|
||||
Name: "get",
|
||||
Usage: "Get chain DAG node by path",
|
||||
ArgsUsage: "[path]",
|
||||
@ -905,7 +905,7 @@ func printTipSet(format string, ts *types.TipSet) {
|
||||
fmt.Println(format)
|
||||
}
|
||||
|
||||
var chainBisectCmd = &cli.Command{
|
||||
var ChainBisectCmd = &cli.Command{
|
||||
Name: "bisect",
|
||||
Usage: "bisect chain for an event",
|
||||
ArgsUsage: "[minHeight maxHeight path shellCommand <shellCommandArgs (if any)>]",
|
||||
@ -1028,7 +1028,7 @@ var chainBisectCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var chainExportCmd = &cli.Command{
|
||||
var ChainExportCmd = &cli.Command{
|
||||
Name: "export",
|
||||
Usage: "export chain to a car file",
|
||||
ArgsUsage: "[outputPath]",
|
||||
@ -1106,7 +1106,7 @@ var chainExportCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var slashConsensusFault = &cli.Command{
|
||||
var SlashConsensusFault = &cli.Command{
|
||||
Name: "slash-consensus",
|
||||
Usage: "Report consensus fault",
|
||||
ArgsUsage: "[blockCid1 blockCid2]",
|
||||
@ -1227,7 +1227,7 @@ var slashConsensusFault = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var chainGasPriceCmd = &cli.Command{
|
||||
var ChainGasPriceCmd = &cli.Command{
|
||||
Name: "gas-price",
|
||||
Usage: "Estimate gas prices",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
@ -1254,7 +1254,7 @@ var chainGasPriceCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var chainDecodeCmd = &cli.Command{
|
||||
var ChainDecodeCmd = &cli.Command{
|
||||
Name: "decode",
|
||||
Usage: "decode various types",
|
||||
Subcommands: []*cli.Command{
|
||||
@ -1334,7 +1334,7 @@ var chainDecodeParamsCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var chainEncodeCmd = &cli.Command{
|
||||
var ChainEncodeCmd = &cli.Command{
|
||||
Name: "encode",
|
||||
Usage: "encode various types",
|
||||
Subcommands: []*cli.Command{
|
||||
|
343
cli/client.go
343
cli/client.go
@ -83,12 +83,14 @@ var clientCmd = &cli.Command{
|
||||
WithCategory("storage", clientGetDealCmd),
|
||||
WithCategory("storage", clientListAsksCmd),
|
||||
WithCategory("storage", clientDealStatsCmd),
|
||||
WithCategory("storage", clientInspectDealCmd),
|
||||
WithCategory("data", clientImportCmd),
|
||||
WithCategory("data", clientDropCmd),
|
||||
WithCategory("data", clientLocalCmd),
|
||||
WithCategory("data", clientStat),
|
||||
WithCategory("retrieval", clientFindCmd),
|
||||
WithCategory("retrieval", clientRetrieveCmd),
|
||||
WithCategory("retrieval", clientCancelRetrievalDealCmd),
|
||||
WithCategory("util", clientCommPCmd),
|
||||
WithCategory("util", clientCarGenCmd),
|
||||
WithCategory("util", clientBalancesCmd),
|
||||
@ -391,6 +393,9 @@ var clientDealCmd = &cli.Command{
|
||||
if abi.ChainEpoch(dur) < build.MinDealDuration {
|
||||
return xerrors.Errorf("minimum deal duration is %d blocks", build.MinDealDuration)
|
||||
}
|
||||
if abi.ChainEpoch(dur) > build.MaxDealDuration {
|
||||
return xerrors.Errorf("maximum deal duration is %d blocks", build.MaxDealDuration)
|
||||
}
|
||||
|
||||
var a address.Address
|
||||
if from := cctx.String("from"); from != "" {
|
||||
@ -513,9 +518,10 @@ func interactiveDeal(cctx *cli.Context) error {
|
||||
var ds lapi.DataCIDSize
|
||||
|
||||
// find
|
||||
var candidateAsks []*storagemarket.StorageAsk
|
||||
var candidateAsks []QueriedAsk
|
||||
var budget types.FIL
|
||||
var dealCount int64
|
||||
var medianPing, maxAcceptablePing time.Duration
|
||||
|
||||
var a address.Address
|
||||
if from := cctx.String("from"); from != "" {
|
||||
@ -675,6 +681,18 @@ uiLoop:
|
||||
return err
|
||||
}
|
||||
|
||||
if len(asks) == 0 {
|
||||
printErr(xerrors.Errorf("no asks found"))
|
||||
continue uiLoop
|
||||
}
|
||||
|
||||
medianPing = asks[len(asks)/2].Ping
|
||||
var avgPing time.Duration
|
||||
for _, ask := range asks {
|
||||
avgPing += ask.Ping
|
||||
}
|
||||
avgPing /= time.Duration(len(asks))
|
||||
|
||||
for _, ask := range asks {
|
||||
if ask.Ask.MinPieceSize > ds.PieceSize {
|
||||
continue
|
||||
@ -682,10 +700,48 @@ uiLoop:
|
||||
if ask.Ask.MaxPieceSize < ds.PieceSize {
|
||||
continue
|
||||
}
|
||||
candidateAsks = append(candidateAsks, ask.Ask)
|
||||
candidateAsks = append(candidateAsks, ask)
|
||||
}
|
||||
|
||||
afmt.Printf("Found %d candidate asks\n", len(candidateAsks))
|
||||
afmt.Printf("Average network latency: %s; Median latency: %s\n", avgPing.Truncate(time.Millisecond), medianPing.Truncate(time.Millisecond))
|
||||
state = "max-ping"
|
||||
case "max-ping":
|
||||
maxAcceptablePing = medianPing
|
||||
|
||||
afmt.Printf("Maximum network latency (default: %s) (ms): ", maxAcceptablePing.Truncate(time.Millisecond))
|
||||
_latStr, _, err := rl.ReadLine()
|
||||
latStr := string(_latStr)
|
||||
if err != nil {
|
||||
printErr(xerrors.Errorf("reading maximum latency: %w", err))
|
||||
continue
|
||||
}
|
||||
|
||||
if latStr != "" {
|
||||
maxMs, err := strconv.ParseInt(latStr, 10, 64)
|
||||
if err != nil {
|
||||
printErr(xerrors.Errorf("parsing FIL: %w", err))
|
||||
continue uiLoop
|
||||
}
|
||||
|
||||
maxAcceptablePing = time.Millisecond * time.Duration(maxMs)
|
||||
}
|
||||
|
||||
var goodAsks []QueriedAsk
|
||||
for _, candidateAsk := range candidateAsks {
|
||||
if candidateAsk.Ping < maxAcceptablePing {
|
||||
goodAsks = append(goodAsks, candidateAsk)
|
||||
}
|
||||
}
|
||||
|
||||
if len(goodAsks) == 0 {
|
||||
afmt.Printf("no asks left after filtering for network latency\n")
|
||||
continue uiLoop
|
||||
}
|
||||
|
||||
afmt.Printf("%d asks left after filtering for network latency\n", len(goodAsks))
|
||||
candidateAsks = goodAsks
|
||||
|
||||
state = "find-budget"
|
||||
case "find-budget":
|
||||
afmt.Printf("Proposing from %s, Current Balance: %s\n", a, types.FIL(fromBal))
|
||||
@ -704,11 +760,11 @@ uiLoop:
|
||||
continue uiLoop
|
||||
}
|
||||
|
||||
var goodAsks []*storagemarket.StorageAsk
|
||||
var goodAsks []QueriedAsk
|
||||
for _, ask := range candidateAsks {
|
||||
p := ask.Price
|
||||
p := ask.Ask.Price
|
||||
if verified {
|
||||
p = ask.VerifiedPrice
|
||||
p = ask.Ask.VerifiedPrice
|
||||
}
|
||||
|
||||
epochPrice := types.BigDiv(types.BigMul(p, types.NewInt(uint64(ds.PieceSize))), gib)
|
||||
@ -748,9 +804,9 @@ uiLoop:
|
||||
pickedAsks = []*storagemarket.StorageAsk{}
|
||||
|
||||
for _, ask := range candidateAsks {
|
||||
p := ask.Price
|
||||
p := ask.Ask.Price
|
||||
if verified {
|
||||
p = ask.VerifiedPrice
|
||||
p = ask.Ask.VerifiedPrice
|
||||
}
|
||||
|
||||
epochPrice := types.BigDiv(types.BigMul(p, types.NewInt(uint64(ds.PieceSize))), gib)
|
||||
@ -760,7 +816,7 @@ uiLoop:
|
||||
continue
|
||||
}
|
||||
|
||||
pickedAsks = append(pickedAsks, ask)
|
||||
pickedAsks = append(pickedAsks, ask.Ask)
|
||||
remainingBudget = big.Sub(remainingBudget, totalPrice)
|
||||
|
||||
if len(pickedAsks) == int(dealCount) {
|
||||
@ -960,7 +1016,7 @@ var clientFindCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
const DefaultMaxRetrievePrice = 1
|
||||
const DefaultMaxRetrievePrice = "0.01"
|
||||
|
||||
var clientRetrieveCmd = &cli.Command{
|
||||
Name: "retrieve",
|
||||
@ -981,12 +1037,15 @@ var clientRetrieveCmd = &cli.Command{
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "maxPrice",
|
||||
Usage: fmt.Sprintf("maximum price the client is willing to consider (default: %d FIL)", DefaultMaxRetrievePrice),
|
||||
Usage: fmt.Sprintf("maximum price the client is willing to consider (default: %s FIL)", DefaultMaxRetrievePrice),
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "pieceCid",
|
||||
Usage: "require data to be retrieved from a specific Piece CID",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "allow-local",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if cctx.NArg() != 2 {
|
||||
@ -1016,18 +1075,6 @@ var clientRetrieveCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
// Check if we already have this data locally
|
||||
|
||||
/*has, err := api.ClientHasLocal(ctx, file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if has {
|
||||
fmt.Println("Success: Already in local storage")
|
||||
return nil
|
||||
}*/ // TODO: fix
|
||||
|
||||
var pieceCid *cid.Cid
|
||||
if cctx.String("pieceCid") != "" {
|
||||
parsed, err := cid.Parse(cctx.String("pieceCid"))
|
||||
@ -1037,69 +1084,93 @@ var clientRetrieveCmd = &cli.Command{
|
||||
pieceCid = &parsed
|
||||
}
|
||||
|
||||
var offer api.QueryOffer
|
||||
minerStrAddr := cctx.String("miner")
|
||||
if minerStrAddr == "" { // Local discovery
|
||||
offers, err := fapi.ClientFindData(ctx, file, pieceCid)
|
||||
var order *lapi.RetrievalOrder
|
||||
if cctx.Bool("allow-local") {
|
||||
imports, err := fapi.ClientListImports(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var cleaned []api.QueryOffer
|
||||
// filter out offers that errored
|
||||
for _, o := range offers {
|
||||
if o.Err == "" {
|
||||
cleaned = append(cleaned, o)
|
||||
for _, i := range imports {
|
||||
if i.Root != nil && i.Root.Equals(file) {
|
||||
order = &lapi.RetrievalOrder{
|
||||
Root: file,
|
||||
LocalStore: &i.Key,
|
||||
|
||||
Total: big.Zero(),
|
||||
UnsealPrice: big.Zero(),
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if order == nil {
|
||||
var offer api.QueryOffer
|
||||
minerStrAddr := cctx.String("miner")
|
||||
if minerStrAddr == "" { // Local discovery
|
||||
offers, err := fapi.ClientFindData(ctx, file, pieceCid)
|
||||
|
||||
var cleaned []api.QueryOffer
|
||||
// filter out offers that errored
|
||||
for _, o := range offers {
|
||||
if o.Err == "" {
|
||||
cleaned = append(cleaned, o)
|
||||
}
|
||||
}
|
||||
|
||||
offers = cleaned
|
||||
|
||||
// sort by price low to high
|
||||
sort.Slice(offers, func(i, j int) bool {
|
||||
return offers[i].MinPrice.LessThan(offers[j].MinPrice)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: parse offer strings from `client find`, make this smarter
|
||||
if len(offers) < 1 {
|
||||
fmt.Println("Failed to find file")
|
||||
return nil
|
||||
}
|
||||
offer = offers[0]
|
||||
} else { // Directed retrieval
|
||||
minerAddr, err := address.NewFromString(minerStrAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
offer, err = fapi.ClientMinerQueryOffer(ctx, minerAddr, file, pieceCid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if offer.Err != "" {
|
||||
return fmt.Errorf("The received offer errored: %s", offer.Err)
|
||||
}
|
||||
|
||||
maxPrice := types.MustParseFIL(DefaultMaxRetrievePrice)
|
||||
|
||||
if cctx.String("maxPrice") != "" {
|
||||
maxPrice, err = types.ParseFIL(cctx.String("maxPrice"))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("parsing maxPrice: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
offers = cleaned
|
||||
|
||||
// sort by price low to high
|
||||
sort.Slice(offers, func(i, j int) bool {
|
||||
return offers[i].MinPrice.LessThan(offers[j].MinPrice)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
if offer.MinPrice.GreaterThan(big.Int(maxPrice)) {
|
||||
return xerrors.Errorf("failed to find offer satisfying maxPrice: %s", maxPrice)
|
||||
}
|
||||
|
||||
// TODO: parse offer strings from `client find`, make this smarter
|
||||
if len(offers) < 1 {
|
||||
fmt.Println("Failed to find file")
|
||||
return nil
|
||||
}
|
||||
offer = offers[0]
|
||||
} else { // Directed retrieval
|
||||
minerAddr, err := address.NewFromString(minerStrAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
offer, err = fapi.ClientMinerQueryOffer(ctx, minerAddr, file, pieceCid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o := offer.Order(payer)
|
||||
order = &o
|
||||
}
|
||||
if offer.Err != "" {
|
||||
return fmt.Errorf("The received offer errored: %s", offer.Err)
|
||||
}
|
||||
|
||||
maxPrice := types.FromFil(DefaultMaxRetrievePrice)
|
||||
|
||||
if cctx.String("maxPrice") != "" {
|
||||
maxPriceFil, err := types.ParseFIL(cctx.String("maxPrice"))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("parsing maxPrice: %w", err)
|
||||
}
|
||||
|
||||
maxPrice = types.BigInt(maxPriceFil)
|
||||
}
|
||||
|
||||
if offer.MinPrice.GreaterThan(maxPrice) {
|
||||
return xerrors.Errorf("failed to find offer satisfying maxPrice: %s", maxPrice)
|
||||
}
|
||||
|
||||
ref := &lapi.FileRef{
|
||||
Path: cctx.Args().Get(1),
|
||||
IsCAR: cctx.Bool("car"),
|
||||
}
|
||||
updates, err := fapi.ClientRetrieveWithEvents(ctx, offer.Order(payer), ref)
|
||||
|
||||
updates, err := fapi.ClientRetrieveWithEvents(ctx, *order, ref)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error setting up retrieval: %w", err)
|
||||
}
|
||||
@ -1129,6 +1200,29 @@ var clientRetrieveCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var clientInspectDealCmd = &cli.Command{
|
||||
Name: "inspect-deal",
|
||||
Usage: "Inspect detailed information about deal's lifecycle and the various stages it goes through",
|
||||
Flags: []cli.Flag{
|
||||
&cli.IntFlag{
|
||||
Name: "deal-id",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "proposal-cid",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
|
||||
ctx := ReqContext(cctx)
|
||||
return inspectDealCmd(ctx, api, cctx.String("proposal-cid"), cctx.Int("deal-id"))
|
||||
},
|
||||
}
|
||||
|
||||
var clientDealStatsCmd = &cli.Command{
|
||||
Name: "deal-stats",
|
||||
Usage: "Print statistics about local storage deals",
|
||||
@ -1990,6 +2084,33 @@ var clientCancelTransfer = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var clientCancelRetrievalDealCmd = &cli.Command{
|
||||
Name: "cancel-retrieval",
|
||||
Usage: "Cancel a retrieval deal by deal ID; this also cancels the associated transfer",
|
||||
Flags: []cli.Flag{
|
||||
&cli.Int64Flag{
|
||||
Name: "deal-id",
|
||||
Usage: "specify retrieval deal by deal ID",
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
id := cctx.Int64("deal-id")
|
||||
if id < 0 {
|
||||
return errors.New("deal id cannot be negative")
|
||||
}
|
||||
|
||||
return api.ClientCancelRetrievalDeal(ctx, retrievalmarket.DealID(id))
|
||||
},
|
||||
}
|
||||
|
||||
var clientListTransfers = &cli.Command{
|
||||
Name: "list-transfers",
|
||||
Usage: "List ongoing data transfers for deals",
|
||||
@ -2178,3 +2299,77 @@ func ellipsis(s string, length int) string {
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func inspectDealCmd(ctx context.Context, api lapi.FullNode, proposalCid string, dealId int) error {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
deals, err := api.ClientListDeals(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var di *lapi.DealInfo
|
||||
for i, cdi := range deals {
|
||||
if proposalCid != "" && cdi.ProposalCid.String() == proposalCid {
|
||||
di = &deals[i]
|
||||
break
|
||||
}
|
||||
|
||||
if dealId != 0 && int(cdi.DealID) == dealId {
|
||||
di = &deals[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if di == nil {
|
||||
if proposalCid != "" {
|
||||
return fmt.Errorf("cannot find deal with proposal cid: %s", proposalCid)
|
||||
}
|
||||
if dealId != 0 {
|
||||
return fmt.Errorf("cannot find deal with deal id: %v", dealId)
|
||||
}
|
||||
return errors.New("you must specify proposal cid or deal id in order to inspect a deal")
|
||||
}
|
||||
|
||||
// populate DealInfo.DealStages and DataTransfer.Stages
|
||||
di, err = api.ClientGetDealInfo(ctx, di.ProposalCid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot get deal info for proposal cid: %v", di.ProposalCid)
|
||||
}
|
||||
|
||||
renderDeal(di)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func renderDeal(di *lapi.DealInfo) {
|
||||
color.Blue("Deal ID: %d\n", int(di.DealID))
|
||||
color.Blue("Proposal CID: %s\n\n", di.ProposalCid.String())
|
||||
|
||||
if di.DealStages == nil {
|
||||
color.Yellow("Deal was made with an older version of Lotus and Lotus did not collect detailed information about its stages")
|
||||
return
|
||||
}
|
||||
|
||||
for _, stg := range di.DealStages.Stages {
|
||||
msg := fmt.Sprintf("%s %s: %s (%s)", color.BlueString("Stage:"), color.BlueString(strings.TrimPrefix(stg.Name, "StorageDeal")), stg.Description, color.GreenString(stg.ExpectedDuration))
|
||||
if stg.UpdatedTime.Time().IsZero() {
|
||||
msg = color.YellowString(msg)
|
||||
}
|
||||
fmt.Println(msg)
|
||||
|
||||
for _, l := range stg.Logs {
|
||||
fmt.Printf(" %s %s\n", color.YellowString(l.UpdatedTime.Time().UTC().Round(time.Second).Format(time.Stamp)), l.Log)
|
||||
}
|
||||
|
||||
if stg.Name == "StorageDealStartDataTransfer" {
|
||||
for _, dtStg := range di.DataTransfer.Stages.Stages {
|
||||
fmt.Printf(" %s %s %s\n", color.YellowString(dtStg.CreatedTime.Time().UTC().Round(time.Second).Format(time.Stamp)), color.BlueString("Data transfer stage:"), color.BlueString(dtStg.Name))
|
||||
for _, l := range dtStg.Logs {
|
||||
fmt.Printf(" %s %s\n", color.YellowString(l.UpdatedTime.Time().UTC().Round(time.Second).Format(time.Stamp)), l.Log)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
32
cli/cmd.go
32
cli/cmd.go
@ -56,12 +56,12 @@ var GetStorageMinerAPI = cliutil.GetStorageMinerAPI
|
||||
var GetWorkerAPI = cliutil.GetWorkerAPI
|
||||
|
||||
var CommonCommands = []*cli.Command{
|
||||
netCmd,
|
||||
authCmd,
|
||||
logCmd,
|
||||
waitApiCmd,
|
||||
fetchParamCmd,
|
||||
pprofCmd,
|
||||
NetCmd,
|
||||
AuthCmd,
|
||||
LogCmd,
|
||||
WaitApiCmd,
|
||||
FetchParamCmd,
|
||||
PprofCmd,
|
||||
VersionCmd,
|
||||
}
|
||||
|
||||
@ -71,16 +71,16 @@ var Commands = []*cli.Command{
|
||||
WithCategory("basic", clientCmd),
|
||||
WithCategory("basic", multisigCmd),
|
||||
WithCategory("basic", paychCmd),
|
||||
WithCategory("developer", authCmd),
|
||||
WithCategory("developer", mpoolCmd),
|
||||
WithCategory("developer", stateCmd),
|
||||
WithCategory("developer", chainCmd),
|
||||
WithCategory("developer", logCmd),
|
||||
WithCategory("developer", waitApiCmd),
|
||||
WithCategory("developer", fetchParamCmd),
|
||||
WithCategory("network", netCmd),
|
||||
WithCategory("network", syncCmd),
|
||||
pprofCmd,
|
||||
WithCategory("developer", AuthCmd),
|
||||
WithCategory("developer", MpoolCmd),
|
||||
WithCategory("developer", StateCmd),
|
||||
WithCategory("developer", ChainCmd),
|
||||
WithCategory("developer", LogCmd),
|
||||
WithCategory("developer", WaitApiCmd),
|
||||
WithCategory("developer", FetchParamCmd),
|
||||
WithCategory("network", NetCmd),
|
||||
WithCategory("network", SyncCmd),
|
||||
PprofCmd,
|
||||
VersionCmd,
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ type minerDeadline struct {
|
||||
index uint64
|
||||
}
|
||||
|
||||
var chainDisputeSetCmd = &cli.Command{
|
||||
var ChainDisputeSetCmd = &cli.Command{
|
||||
Name: "disputer",
|
||||
Usage: "interact with the window post disputer",
|
||||
Flags: []cli.Flag{
|
||||
|
10
cli/log.go
10
cli/log.go
@ -7,16 +7,16 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var logCmd = &cli.Command{
|
||||
var LogCmd = &cli.Command{
|
||||
Name: "log",
|
||||
Usage: "Manage logging",
|
||||
Subcommands: []*cli.Command{
|
||||
logList,
|
||||
logSetLevel,
|
||||
LogList,
|
||||
LogSetLevel,
|
||||
},
|
||||
}
|
||||
|
||||
var logList = &cli.Command{
|
||||
var LogList = &cli.Command{
|
||||
Name: "list",
|
||||
Usage: "List log systems",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
@ -41,7 +41,7 @@ var logList = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var logSetLevel = &cli.Command{
|
||||
var LogSetLevel = &cli.Command{
|
||||
Name: "set-level",
|
||||
Usage: "Set log level",
|
||||
ArgsUsage: "[level]",
|
||||
|
34
cli/mpool.go
34
cli/mpool.go
@ -22,22 +22,22 @@ import (
|
||||
"github.com/filecoin-project/lotus/node/config"
|
||||
)
|
||||
|
||||
var mpoolCmd = &cli.Command{
|
||||
var MpoolCmd = &cli.Command{
|
||||
Name: "mpool",
|
||||
Usage: "Manage message pool",
|
||||
Subcommands: []*cli.Command{
|
||||
mpoolPending,
|
||||
mpoolClear,
|
||||
mpoolSub,
|
||||
mpoolStat,
|
||||
mpoolReplaceCmd,
|
||||
mpoolFindCmd,
|
||||
mpoolConfig,
|
||||
mpoolGasPerfCmd,
|
||||
MpoolPending,
|
||||
MpoolClear,
|
||||
MpoolSub,
|
||||
MpoolStat,
|
||||
MpoolReplaceCmd,
|
||||
MpoolFindCmd,
|
||||
MpoolConfig,
|
||||
MpoolGasPerfCmd,
|
||||
},
|
||||
}
|
||||
|
||||
var mpoolPending = &cli.Command{
|
||||
var MpoolPending = &cli.Command{
|
||||
Name: "pending",
|
||||
Usage: "Get pending messages",
|
||||
Flags: []cli.Flag{
|
||||
@ -132,7 +132,7 @@ var mpoolPending = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var mpoolClear = &cli.Command{
|
||||
var MpoolClear = &cli.Command{
|
||||
Name: "clear",
|
||||
Usage: "Clear all pending messages from the mpool (USE WITH CARE)",
|
||||
Flags: []cli.Flag{
|
||||
@ -165,7 +165,7 @@ var mpoolClear = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var mpoolSub = &cli.Command{
|
||||
var MpoolSub = &cli.Command{
|
||||
Name: "sub",
|
||||
Usage: "Subscribe to mpool changes",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
@ -197,7 +197,7 @@ var mpoolSub = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var mpoolStat = &cli.Command{
|
||||
var MpoolStat = &cli.Command{
|
||||
Name: "stat",
|
||||
Usage: "print mempool stats",
|
||||
Flags: []cli.Flag{
|
||||
@ -356,7 +356,7 @@ var mpoolStat = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var mpoolReplaceCmd = &cli.Command{
|
||||
var MpoolReplaceCmd = &cli.Command{
|
||||
Name: "replace",
|
||||
Usage: "replace a message in the mempool",
|
||||
Flags: []cli.Flag{
|
||||
@ -509,7 +509,7 @@ var mpoolReplaceCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var mpoolFindCmd = &cli.Command{
|
||||
var MpoolFindCmd = &cli.Command{
|
||||
Name: "find",
|
||||
Usage: "find a message in the mempool",
|
||||
Flags: []cli.Flag{
|
||||
@ -592,7 +592,7 @@ var mpoolFindCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var mpoolConfig = &cli.Command{
|
||||
var MpoolConfig = &cli.Command{
|
||||
Name: "config",
|
||||
Usage: "get or set current mpool configuration",
|
||||
ArgsUsage: "[new-config]",
|
||||
@ -637,7 +637,7 @@ var mpoolConfig = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var mpoolGasPerfCmd = &cli.Command{
|
||||
var MpoolGasPerfCmd = &cli.Command{
|
||||
Name: "gas-perf",
|
||||
Usage: "Check gas performance of messages in mempool",
|
||||
Flags: []cli.Flag{
|
||||
|
14
cli/net.go
14
cli/net.go
@ -23,16 +23,16 @@ import (
|
||||
"github.com/filecoin-project/lotus/lib/addrutil"
|
||||
)
|
||||
|
||||
var netCmd = &cli.Command{
|
||||
var NetCmd = &cli.Command{
|
||||
Name: "net",
|
||||
Usage: "Manage P2P Network",
|
||||
Subcommands: []*cli.Command{
|
||||
NetPeers,
|
||||
netConnect,
|
||||
NetConnect,
|
||||
NetListen,
|
||||
NetId,
|
||||
netFindPeer,
|
||||
netScores,
|
||||
NetFindPeer,
|
||||
NetScores,
|
||||
NetReachability,
|
||||
NetBandwidthCmd,
|
||||
NetBlockCmd,
|
||||
@ -112,7 +112,7 @@ var NetPeers = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var netScores = &cli.Command{
|
||||
var NetScores = &cli.Command{
|
||||
Name: "scores",
|
||||
Usage: "Print peers' pubsub scores",
|
||||
Flags: []cli.Flag{
|
||||
@ -175,7 +175,7 @@ var NetListen = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var netConnect = &cli.Command{
|
||||
var NetConnect = &cli.Command{
|
||||
Name: "connect",
|
||||
Usage: "Connect to a peer",
|
||||
ArgsUsage: "[peerMultiaddr|minerActorAddress]",
|
||||
@ -264,7 +264,7 @@ var NetId = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var netFindPeer = &cli.Command{
|
||||
var NetFindPeer = &cli.Command{
|
||||
Name: "findpeer",
|
||||
Usage: "Find the addresses of a given peerID",
|
||||
ArgsUsage: "[peerId]",
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
)
|
||||
|
||||
var fetchParamCmd = &cli.Command{
|
||||
var FetchParamCmd = &cli.Command{
|
||||
Name: "fetch-params",
|
||||
Usage: "Fetch proving parameters",
|
||||
ArgsUsage: "[sectorSize]",
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/node/repo"
|
||||
)
|
||||
|
||||
var pprofCmd = &cli.Command{
|
||||
var PprofCmd = &cli.Command{
|
||||
Name: "pprof",
|
||||
Hidden: true,
|
||||
Subcommands: []*cli.Command{
|
||||
|
90
cli/state.go
90
cli/state.go
@ -41,7 +41,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
var stateCmd = &cli.Command{
|
||||
var StateCmd = &cli.Command{
|
||||
Name: "state",
|
||||
Usage: "Interact with and query filecoin chain state",
|
||||
Flags: []cli.Flag{
|
||||
@ -51,32 +51,32 @@ var stateCmd = &cli.Command{
|
||||
},
|
||||
},
|
||||
Subcommands: []*cli.Command{
|
||||
statePowerCmd,
|
||||
stateSectorsCmd,
|
||||
stateActiveSectorsCmd,
|
||||
stateListActorsCmd,
|
||||
stateListMinersCmd,
|
||||
stateCircSupplyCmd,
|
||||
stateSectorCmd,
|
||||
stateGetActorCmd,
|
||||
stateLookupIDCmd,
|
||||
stateReplayCmd,
|
||||
stateSectorSizeCmd,
|
||||
stateReadStateCmd,
|
||||
stateListMessagesCmd,
|
||||
stateComputeStateCmd,
|
||||
stateCallCmd,
|
||||
stateGetDealSetCmd,
|
||||
stateWaitMsgCmd,
|
||||
stateSearchMsgCmd,
|
||||
stateMinerInfo,
|
||||
stateMarketCmd,
|
||||
stateExecTraceCmd,
|
||||
stateNtwkVersionCmd,
|
||||
StatePowerCmd,
|
||||
StateSectorsCmd,
|
||||
StateActiveSectorsCmd,
|
||||
StateListActorsCmd,
|
||||
StateListMinersCmd,
|
||||
StateCircSupplyCmd,
|
||||
StateSectorCmd,
|
||||
StateGetActorCmd,
|
||||
StateLookupIDCmd,
|
||||
StateReplayCmd,
|
||||
StateSectorSizeCmd,
|
||||
StateReadStateCmd,
|
||||
StateListMessagesCmd,
|
||||
StateComputeStateCmd,
|
||||
StateCallCmd,
|
||||
StateGetDealSetCmd,
|
||||
StateWaitMsgCmd,
|
||||
StateSearchMsgCmd,
|
||||
StateMinerInfo,
|
||||
StateMarketCmd,
|
||||
StateExecTraceCmd,
|
||||
StateNtwkVersionCmd,
|
||||
},
|
||||
}
|
||||
|
||||
var stateMinerInfo = &cli.Command{
|
||||
var StateMinerInfo = &cli.Command{
|
||||
Name: "miner-info",
|
||||
Usage: "Retrieve miner information",
|
||||
ArgsUsage: "[minerAddress]",
|
||||
@ -219,7 +219,7 @@ func ParseTipSetRef(ctx context.Context, api api.FullNode, tss string) (*types.T
|
||||
return ts, nil
|
||||
}
|
||||
|
||||
var statePowerCmd = &cli.Command{
|
||||
var StatePowerCmd = &cli.Command{
|
||||
Name: "power",
|
||||
Usage: "Query network or miner power",
|
||||
ArgsUsage: "[<minerAddress> (optional)]",
|
||||
@ -263,7 +263,7 @@ var statePowerCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateSectorsCmd = &cli.Command{
|
||||
var StateSectorsCmd = &cli.Command{
|
||||
Name: "sectors",
|
||||
Usage: "Query the sector set of a miner",
|
||||
ArgsUsage: "[minerAddress]",
|
||||
@ -303,7 +303,7 @@ var stateSectorsCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateActiveSectorsCmd = &cli.Command{
|
||||
var StateActiveSectorsCmd = &cli.Command{
|
||||
Name: "active-sectors",
|
||||
Usage: "Query the active sector set of a miner",
|
||||
ArgsUsage: "[minerAddress]",
|
||||
@ -343,7 +343,7 @@ var stateActiveSectorsCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateExecTraceCmd = &cli.Command{
|
||||
var StateExecTraceCmd = &cli.Command{
|
||||
Name: "exec-trace",
|
||||
Usage: "Get the execution trace of a given message",
|
||||
ArgsUsage: "<messageCid>",
|
||||
@ -411,7 +411,7 @@ var stateExecTraceCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateReplayCmd = &cli.Command{
|
||||
var StateReplayCmd = &cli.Command{
|
||||
Name: "replay",
|
||||
Usage: "Replay a particular message",
|
||||
ArgsUsage: "<messageCid>",
|
||||
@ -476,7 +476,7 @@ var stateReplayCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateGetDealSetCmd = &cli.Command{
|
||||
var StateGetDealSetCmd = &cli.Command{
|
||||
Name: "get-deal",
|
||||
Usage: "View on-chain deal info",
|
||||
ArgsUsage: "[dealId]",
|
||||
@ -518,7 +518,7 @@ var stateGetDealSetCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateListMinersCmd = &cli.Command{
|
||||
var StateListMinersCmd = &cli.Command{
|
||||
Name: "list-miners",
|
||||
Usage: "list all miners in the network",
|
||||
Flags: []cli.Flag{
|
||||
@ -590,7 +590,7 @@ func getDealsCounts(ctx context.Context, lapi api.FullNode) (map[address.Address
|
||||
return out, nil
|
||||
}
|
||||
|
||||
var stateListActorsCmd = &cli.Command{
|
||||
var StateListActorsCmd = &cli.Command{
|
||||
Name: "list-actors",
|
||||
Usage: "list all actors in the network",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
@ -620,7 +620,7 @@ var stateListActorsCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateGetActorCmd = &cli.Command{
|
||||
var StateGetActorCmd = &cli.Command{
|
||||
Name: "get-actor",
|
||||
Usage: "Print actor information",
|
||||
ArgsUsage: "[actorrAddress]",
|
||||
@ -664,7 +664,7 @@ var stateGetActorCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateLookupIDCmd = &cli.Command{
|
||||
var StateLookupIDCmd = &cli.Command{
|
||||
Name: "lookup",
|
||||
Usage: "Find corresponding ID address",
|
||||
ArgsUsage: "[address]",
|
||||
@ -715,7 +715,7 @@ var stateLookupIDCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateSectorSizeCmd = &cli.Command{
|
||||
var StateSectorSizeCmd = &cli.Command{
|
||||
Name: "sector-size",
|
||||
Usage: "Look up miners sector size",
|
||||
ArgsUsage: "[minerAddress]",
|
||||
@ -752,7 +752,7 @@ var stateSectorSizeCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateReadStateCmd = &cli.Command{
|
||||
var StateReadStateCmd = &cli.Command{
|
||||
Name: "read-state",
|
||||
Usage: "View a json representation of an actors state",
|
||||
ArgsUsage: "[actorAddress]",
|
||||
@ -794,7 +794,7 @@ var stateReadStateCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateListMessagesCmd = &cli.Command{
|
||||
var StateListMessagesCmd = &cli.Command{
|
||||
Name: "list-messages",
|
||||
Usage: "list messages on chain matching given criteria",
|
||||
Flags: []cli.Flag{
|
||||
@ -907,7 +907,7 @@ var stateListMessagesCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateComputeStateCmd = &cli.Command{
|
||||
var StateComputeStateCmd = &cli.Command{
|
||||
Name: "compute-state",
|
||||
Usage: "Perform state computations",
|
||||
Flags: []cli.Flag{
|
||||
@ -1365,7 +1365,7 @@ func jsonReturn(code cid.Cid, method abi.MethodNum, ret []byte) (string, error)
|
||||
return string(b), err
|
||||
}
|
||||
|
||||
var stateWaitMsgCmd = &cli.Command{
|
||||
var StateWaitMsgCmd = &cli.Command{
|
||||
Name: "wait-msg",
|
||||
Usage: "Wait for a message to appear on chain",
|
||||
ArgsUsage: "[messageCid]",
|
||||
@ -1407,7 +1407,7 @@ var stateWaitMsgCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateSearchMsgCmd = &cli.Command{
|
||||
var StateSearchMsgCmd = &cli.Command{
|
||||
Name: "search-msg",
|
||||
Usage: "Search to see whether a message has appeared on chain",
|
||||
ArgsUsage: "[messageCid]",
|
||||
@ -1484,7 +1484,7 @@ func printMsg(ctx context.Context, api api.FullNode, msg cid.Cid, mw *lapi.MsgLo
|
||||
return nil
|
||||
}
|
||||
|
||||
var stateCallCmd = &cli.Command{
|
||||
var StateCallCmd = &cli.Command{
|
||||
Name: "call",
|
||||
Usage: "Invoke a method on an actor locally",
|
||||
ArgsUsage: "[toAddress methodId <param1 param2 ...> (optional)]",
|
||||
@ -1692,7 +1692,7 @@ func parseParamsForMethod(act cid.Cid, method uint64, args []string) ([]byte, er
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
var stateCircSupplyCmd = &cli.Command{
|
||||
var StateCircSupplyCmd = &cli.Command{
|
||||
Name: "circulating-supply",
|
||||
Usage: "Get the exact current circulating supply of Filecoin",
|
||||
Flags: []cli.Flag{
|
||||
@ -1741,7 +1741,7 @@ var stateCircSupplyCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateSectorCmd = &cli.Command{
|
||||
var StateSectorCmd = &cli.Command{
|
||||
Name: "sector",
|
||||
Usage: "Get miner sector info",
|
||||
ArgsUsage: "[miner address] [sector number]",
|
||||
@ -1815,7 +1815,7 @@ var stateSectorCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateMarketCmd = &cli.Command{
|
||||
var StateMarketCmd = &cli.Command{
|
||||
Name: "market",
|
||||
Usage: "Inspect the storage market actor",
|
||||
Subcommands: []*cli.Command{
|
||||
@ -1861,7 +1861,7 @@ var stateMarketBalanceCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateNtwkVersionCmd = &cli.Command{
|
||||
var StateNtwkVersionCmd = &cli.Command{
|
||||
Name: "network-version",
|
||||
Usage: "Returns the network version",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
|
26
cli/sync.go
26
cli/sync.go
@ -15,20 +15,20 @@ import (
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
)
|
||||
|
||||
var syncCmd = &cli.Command{
|
||||
var SyncCmd = &cli.Command{
|
||||
Name: "sync",
|
||||
Usage: "Inspect or interact with the chain syncer",
|
||||
Subcommands: []*cli.Command{
|
||||
syncStatusCmd,
|
||||
syncWaitCmd,
|
||||
syncMarkBadCmd,
|
||||
syncUnmarkBadCmd,
|
||||
syncCheckBadCmd,
|
||||
syncCheckpointCmd,
|
||||
SyncStatusCmd,
|
||||
SyncWaitCmd,
|
||||
SyncMarkBadCmd,
|
||||
SyncUnmarkBadCmd,
|
||||
SyncCheckBadCmd,
|
||||
SyncCheckpointCmd,
|
||||
},
|
||||
}
|
||||
|
||||
var syncStatusCmd = &cli.Command{
|
||||
var SyncStatusCmd = &cli.Command{
|
||||
Name: "status",
|
||||
Usage: "check sync status",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
@ -81,7 +81,7 @@ var syncStatusCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var syncWaitCmd = &cli.Command{
|
||||
var SyncWaitCmd = &cli.Command{
|
||||
Name: "wait",
|
||||
Usage: "Wait for sync to be complete",
|
||||
Flags: []cli.Flag{
|
||||
@ -102,7 +102,7 @@ var syncWaitCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var syncMarkBadCmd = &cli.Command{
|
||||
var SyncMarkBadCmd = &cli.Command{
|
||||
Name: "mark-bad",
|
||||
Usage: "Mark the given block as bad, will prevent syncing to a chain that contains it",
|
||||
ArgsUsage: "[blockCid]",
|
||||
@ -127,7 +127,7 @@ var syncMarkBadCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var syncUnmarkBadCmd = &cli.Command{
|
||||
var SyncUnmarkBadCmd = &cli.Command{
|
||||
Name: "unmark-bad",
|
||||
Usage: "Unmark the given block as bad, makes it possible to sync to a chain containing it",
|
||||
Flags: []cli.Flag{
|
||||
@ -162,7 +162,7 @@ var syncUnmarkBadCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var syncCheckBadCmd = &cli.Command{
|
||||
var SyncCheckBadCmd = &cli.Command{
|
||||
Name: "check-bad",
|
||||
Usage: "check if the given block was marked bad, and for what reason",
|
||||
ArgsUsage: "[blockCid]",
|
||||
@ -198,7 +198,7 @@ var syncCheckBadCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var syncCheckpointCmd = &cli.Command{
|
||||
var SyncCheckpointCmd = &cli.Command{
|
||||
Name: "checkpoint",
|
||||
Usage: "mark a certain tipset as checkpointed; the node will never fork away from this tipset",
|
||||
ArgsUsage: "[tipsetKey]",
|
||||
|
@ -230,7 +230,7 @@ func GetStorageMinerAPI(ctx *cli.Context, opts ...GetStorageMinerOption) (api.St
|
||||
return client.NewStorageMinerRPC(ctx.Context, addr, headers)
|
||||
}
|
||||
|
||||
func GetWorkerAPI(ctx *cli.Context) (api.WorkerAPI, jsonrpc.ClientCloser, error) {
|
||||
func GetWorkerAPI(ctx *cli.Context) (api.Worker, jsonrpc.ClientCloser, error) {
|
||||
addr, headers, err := GetRawAPI(ctx, repo.Worker)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@ -239,7 +239,7 @@ func GetWorkerAPI(ctx *cli.Context) (api.WorkerAPI, jsonrpc.ClientCloser, error)
|
||||
return client.NewWorkerRPC(ctx.Context, addr, headers)
|
||||
}
|
||||
|
||||
func GetGatewayAPI(ctx *cli.Context) (api.GatewayAPI, jsonrpc.ClientCloser, error) {
|
||||
func GetGatewayAPI(ctx *cli.Context) (api.Gateway, jsonrpc.ClientCloser, error) {
|
||||
addr, headers, err := GetRawAPI(ctx, repo.FullNode)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var waitApiCmd = &cli.Command{
|
||||
var WaitApiCmd = &cli.Command{
|
||||
Name: "wait-api",
|
||||
Usage: "Wait for lotus api to come online",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
|
@ -404,7 +404,7 @@ func (a *GatewayAPI) WalletVerify(ctx context.Context, k address.Address, msg []
|
||||
return sigs.Verify(sig, k, msg) == nil, nil
|
||||
}
|
||||
|
||||
var _ api.GatewayAPI = (*GatewayAPI)(nil)
|
||||
var _ api.Gateway = (*GatewayAPI)(nil)
|
||||
var _ full.ChainModuleAPI = (*GatewayAPI)(nil)
|
||||
var _ full.GasModuleAPI = (*GatewayAPI)(nil)
|
||||
var _ full.MpoolModuleAPI = (*GatewayAPI)(nil)
|
||||
|
@ -249,12 +249,12 @@ func startNodes(
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create a gateway client API that connects to the gateway server
|
||||
var gapi api.GatewayAPI
|
||||
var gapi api.Gateway
|
||||
gapi, closer, err = client.NewGatewayRPC(ctx, addr, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Provide the gateway API to dependency injection
|
||||
return node.Override(new(api.GatewayAPI), gapi)
|
||||
return node.Override(new(api.Gateway), gapi)
|
||||
},
|
||||
},
|
||||
)
|
||||
|
@ -9,6 +9,8 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
apitypes "github.com/filecoin-project/lotus/api/types"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
||||
@ -76,4 +78,8 @@ func (w *worker) Session(ctx context.Context) (uuid.UUID, error) {
|
||||
return w.LocalWorker.Session(ctx)
|
||||
}
|
||||
|
||||
func (w *worker) Discover(ctx context.Context) (apitypes.OpenRPCDocument, error) {
|
||||
return build.OpenRPCDiscoverJSON_Worker(), nil
|
||||
}
|
||||
|
||||
var _ storiface.WorkerCalls = &worker{}
|
||||
|
@ -41,17 +41,17 @@ var tasksEnableCmd = &cli.Command{
|
||||
Name: "enable",
|
||||
Usage: "Enable a task type",
|
||||
ArgsUsage: "[" + settableStr + "]",
|
||||
Action: taskAction(api.WorkerAPI.TaskEnable),
|
||||
Action: taskAction(api.Worker.TaskEnable),
|
||||
}
|
||||
|
||||
var tasksDisableCmd = &cli.Command{
|
||||
Name: "disable",
|
||||
Usage: "Disable a task type",
|
||||
ArgsUsage: "[" + settableStr + "]",
|
||||
Action: taskAction(api.WorkerAPI.TaskDisable),
|
||||
Action: taskAction(api.Worker.TaskDisable),
|
||||
}
|
||||
|
||||
func taskAction(tf func(a api.WorkerAPI, ctx context.Context, tt sealtasks.TaskType) error) func(cctx *cli.Context) error {
|
||||
func taskAction(tf func(a api.Worker, ctx context.Context, tt sealtasks.TaskType) error) func(cctx *cli.Context) error {
|
||||
return func(cctx *cli.Context) error {
|
||||
if cctx.NArg() != 1 {
|
||||
return xerrors.Errorf("expected 1 argument")
|
||||
|
75
cmd/lotus-shed/base64.go
Normal file
75
cmd/lotus-shed/base64.go
Normal file
@ -0,0 +1,75 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var base64Cmd = &cli.Command{
|
||||
Name: "base64",
|
||||
Description: "multiformats base64",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "decodeAddr",
|
||||
Value: false,
|
||||
Usage: "Decode a base64 addr",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "decodeBig",
|
||||
Value: false,
|
||||
Usage: "Decode a base64 big",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
var input io.Reader
|
||||
|
||||
if cctx.Args().Len() == 0 {
|
||||
input = os.Stdin
|
||||
} else {
|
||||
input = strings.NewReader(cctx.Args().First())
|
||||
}
|
||||
|
||||
bytes, err := ioutil.ReadAll(input)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
decoded, err := base64.RawStdEncoding.DecodeString(strings.TrimSpace(string(bytes)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cctx.Bool("decodeAddr") {
|
||||
addr, err := address.NewFromBytes(decoded)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(addr)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if cctx.Bool("decodeBig") {
|
||||
var val abi.TokenAmount
|
||||
err = val.UnmarshalBinary(decoded)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(val)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
@ -180,8 +180,11 @@ var datastoreBackupStatCmd = &cli.Command{
|
||||
}
|
||||
defer f.Close() // nolint:errcheck
|
||||
|
||||
var keys, kbytes, vbytes uint64
|
||||
err = backupds.ReadBackup(f, func(key datastore.Key, value []byte) error {
|
||||
var keys, logs, kbytes, vbytes uint64
|
||||
clean, err := backupds.ReadBackup(f, func(key datastore.Key, value []byte, log bool) error {
|
||||
if log {
|
||||
logs++
|
||||
}
|
||||
keys++
|
||||
kbytes += uint64(len(key.String()))
|
||||
vbytes += uint64(len(value))
|
||||
@ -191,7 +194,9 @@ var datastoreBackupStatCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Truncated: ", !clean)
|
||||
fmt.Println("Keys: ", keys)
|
||||
fmt.Println("Log values: ", log)
|
||||
fmt.Println("Key bytes: ", units.BytesSize(float64(kbytes)))
|
||||
fmt.Println("Value bytes: ", units.BytesSize(float64(vbytes)))
|
||||
|
||||
@ -225,7 +230,7 @@ var datastoreBackupListCmd = &cli.Command{
|
||||
defer f.Close() // nolint:errcheck
|
||||
|
||||
printKv := kvPrinter(cctx.Bool("top-level"), cctx.String("get-enc"))
|
||||
err = backupds.ReadBackup(f, func(key datastore.Key, value []byte) error {
|
||||
_, err = backupds.ReadBackup(f, func(key datastore.Key, value []byte, _ bool) error {
|
||||
return printKv(key.String(), value)
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -7,30 +7,35 @@ import (
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var electionCmd = &cli.Command{
|
||||
Name: "election",
|
||||
Usage: "commands related to leader election",
|
||||
Usage: "Commands related to leader election",
|
||||
Subcommands: []*cli.Command{
|
||||
electionRunDummy,
|
||||
electionEstimate,
|
||||
},
|
||||
}
|
||||
|
||||
var electionRunDummy = &cli.Command{
|
||||
Name: "run-dummy",
|
||||
Usage: "runs dummy elections with given power",
|
||||
Usage: "Runs dummy elections with given power",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "network-power",
|
||||
Name: "network-power",
|
||||
Usage: "network storage power",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "miner-power",
|
||||
Name: "miner-power",
|
||||
Usage: "miner storage power",
|
||||
},
|
||||
&cli.Uint64Flag{
|
||||
Name: "seed",
|
||||
Usage: "rand number",
|
||||
Value: 0,
|
||||
},
|
||||
},
|
||||
@ -42,7 +47,7 @@ var electionRunDummy = &cli.Command{
|
||||
}
|
||||
networkPow, err := types.BigFromString(cctx.String("network-power"))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("decoding miner-power: %w", err)
|
||||
return xerrors.Errorf("decoding network-power: %w", err)
|
||||
}
|
||||
|
||||
ep := &types.ElectionProof{}
|
||||
@ -68,3 +73,54 @@ var electionRunDummy = &cli.Command{
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
var electionEstimate = &cli.Command{
|
||||
Name: "estimate",
|
||||
Usage: "Estimate elections with given power",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "network-power",
|
||||
Usage: "network storage power",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "miner-power",
|
||||
Usage: "miner storage power",
|
||||
},
|
||||
&cli.Uint64Flag{
|
||||
Name: "seed",
|
||||
Usage: "rand number",
|
||||
Value: 0,
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
minerPow, err := types.BigFromString(cctx.String("miner-power"))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("decoding miner-power: %w", err)
|
||||
}
|
||||
networkPow, err := types.BigFromString(cctx.String("network-power"))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("decoding network-power: %w", err)
|
||||
}
|
||||
|
||||
ep := &types.ElectionProof{}
|
||||
ep.VRFProof = make([]byte, 32)
|
||||
seed := cctx.Uint64("seed")
|
||||
if seed == 0 {
|
||||
seed = rand.Uint64()
|
||||
}
|
||||
binary.BigEndian.PutUint64(ep.VRFProof, seed)
|
||||
|
||||
winYear := int64(0)
|
||||
for i := 0; i < builtin2.EpochsInYear; i++ {
|
||||
binary.BigEndian.PutUint64(ep.VRFProof[8:], uint64(i))
|
||||
j := ep.ComputeWinCount(minerPow, networkPow)
|
||||
winYear += j
|
||||
}
|
||||
winHour := winYear * builtin2.EpochsInHour / builtin2.EpochsInYear
|
||||
winDay := winYear * builtin2.EpochsInDay / builtin2.EpochsInYear
|
||||
winMonth := winYear * builtin2.EpochsInDay * 30 / builtin2.EpochsInYear
|
||||
fmt.Println("winInHour, winInDay, winInMonth, winInYear")
|
||||
fmt.Printf("%d, %d, %d, %d\n", winHour, winDay, winMonth, winYear)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ func main() {
|
||||
logging.SetLogLevel("*", "INFO")
|
||||
|
||||
local := []*cli.Command{
|
||||
base64Cmd,
|
||||
base32Cmd,
|
||||
base16Cmd,
|
||||
bitFieldCmd,
|
||||
@ -37,6 +38,7 @@ func main() {
|
||||
mpoolCmd,
|
||||
genesisVerifyCmd,
|
||||
mathCmd,
|
||||
minerCmd,
|
||||
mpoolStatsCmd,
|
||||
exportChainCmd,
|
||||
consensusCmd,
|
||||
@ -51,6 +53,7 @@ func main() {
|
||||
rpcCmd,
|
||||
cidCmd,
|
||||
blockmsgidCmd,
|
||||
signaturesCmd,
|
||||
}
|
||||
|
||||
app := &cli.App{
|
||||
|
113
cmd/lotus-shed/miner.go
Normal file
113
cmd/lotus-shed/miner.go
Normal file
@ -0,0 +1,113 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var minerCmd = &cli.Command{
|
||||
Name: "miner",
|
||||
Usage: "miner-related utilities",
|
||||
Subcommands: []*cli.Command{
|
||||
minerUnpackInfoCmd,
|
||||
},
|
||||
}
|
||||
|
||||
var minerUnpackInfoCmd = &cli.Command{
|
||||
Name: "unpack-info",
|
||||
Usage: "unpack miner info all dump",
|
||||
ArgsUsage: "[allinfo.txt] [dir]",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if cctx.Args().Len() != 2 {
|
||||
return xerrors.Errorf("expected 2 args")
|
||||
}
|
||||
|
||||
src, err := homedir.Expand(cctx.Args().Get(0))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("expand src: %w", err)
|
||||
}
|
||||
|
||||
f, err := os.Open(src)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("open file: %w", err)
|
||||
}
|
||||
defer f.Close() // nolint
|
||||
|
||||
dest, err := homedir.Expand(cctx.Args().Get(1))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("expand dest: %w", err)
|
||||
}
|
||||
|
||||
var outf *os.File
|
||||
|
||||
r := bufio.NewReader(f)
|
||||
for {
|
||||
l, _, err := r.ReadLine()
|
||||
if err == io.EOF {
|
||||
if outf != nil {
|
||||
return outf.Close()
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return xerrors.Errorf("read line: %w", err)
|
||||
}
|
||||
sl := string(l)
|
||||
|
||||
if strings.HasPrefix(sl, "#") {
|
||||
if strings.Contains(sl, "..") {
|
||||
return xerrors.Errorf("bad name %s", sl)
|
||||
}
|
||||
|
||||
if strings.HasPrefix(sl, "#: ") {
|
||||
if outf != nil {
|
||||
if err := outf.Close(); err != nil {
|
||||
return xerrors.Errorf("close out file: %w", err)
|
||||
}
|
||||
}
|
||||
p := filepath.Join(dest, sl[len("#: "):])
|
||||
if err := os.MkdirAll(filepath.Dir(p), 0775); err != nil {
|
||||
return xerrors.Errorf("mkdir: %w", err)
|
||||
}
|
||||
outf, err = os.Create(p)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("create out file: %w", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(sl, "##: ") {
|
||||
if outf != nil {
|
||||
if err := outf.Close(); err != nil {
|
||||
return xerrors.Errorf("close out file: %w", err)
|
||||
}
|
||||
}
|
||||
p := filepath.Join(dest, "Per Sector Infos", sl[len("##: "):])
|
||||
if err := os.MkdirAll(filepath.Dir(p), 0775); err != nil {
|
||||
return xerrors.Errorf("mkdir: %w", err)
|
||||
}
|
||||
outf, err = os.Create(p)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("create out file: %w", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if outf != nil {
|
||||
if _, err := outf.Write(l); err != nil {
|
||||
return xerrors.Errorf("write line: %w", err)
|
||||
}
|
||||
if _, err := outf.Write([]byte("\n")); err != nil {
|
||||
return xerrors.Errorf("write line end: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
@ -6,6 +6,7 @@ import (
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
@ -34,6 +35,10 @@ var terminateSectorCmd = &cli.Command{
|
||||
Usage: "Forcefully terminate a sector (WARNING: This means losing power and pay a one-time termination penalty(including collateral) for the terminated sector)",
|
||||
ArgsUsage: "[sectorNum1 sectorNum2 ...]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "actor",
|
||||
Usage: "specify the address of miner actor",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "really-do-it",
|
||||
Usage: "pass this flag if you know what you are doing",
|
||||
@ -44,6 +49,15 @@ var terminateSectorCmd = &cli.Command{
|
||||
return fmt.Errorf("at least one sector must be specified")
|
||||
}
|
||||
|
||||
var maddr address.Address
|
||||
if act := cctx.String("actor"); act != "" {
|
||||
var err error
|
||||
maddr, err = address.NewFromString(act)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing address %s: %w", act, err)
|
||||
}
|
||||
}
|
||||
|
||||
if !cctx.Bool("really-do-it") {
|
||||
return fmt.Errorf("this is a command for advanced users, only use it if you are sure of what you are doing")
|
||||
}
|
||||
@ -54,17 +68,19 @@ var terminateSectorCmd = &cli.Command{
|
||||
}
|
||||
defer closer()
|
||||
|
||||
api, acloser, err := lcli.GetStorageMinerAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer acloser()
|
||||
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
maddr, err := api.ActorAddress(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
if maddr.Empty() {
|
||||
api, acloser, err := lcli.GetStorageMinerAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer acloser()
|
||||
|
||||
maddr, err = api.ActorAddress(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
mi, err := nodeApi.StateMinerInfo(ctx, maddr, types.EmptyTSK)
|
||||
@ -147,28 +163,45 @@ var terminateSectorPenaltyEstimationCmd = &cli.Command{
|
||||
Name: "termination-estimate",
|
||||
Usage: "Estimate the termination penalty",
|
||||
ArgsUsage: "[sectorNum1 sectorNum2 ...]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "actor",
|
||||
Usage: "specify the address of miner actor",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if cctx.Args().Len() < 1 {
|
||||
return fmt.Errorf("at least one sector must be specified")
|
||||
}
|
||||
|
||||
var maddr address.Address
|
||||
if act := cctx.String("actor"); act != "" {
|
||||
var err error
|
||||
maddr, err = address.NewFromString(act)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing address %s: %w", act, err)
|
||||
}
|
||||
}
|
||||
|
||||
nodeApi, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
|
||||
api, acloser, err := lcli.GetStorageMinerAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer acloser()
|
||||
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
maddr, err := api.ActorAddress(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
if maddr.Empty() {
|
||||
api, acloser, err := lcli.GetStorageMinerAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer acloser()
|
||||
|
||||
maddr, err = api.ActorAddress(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
mi, err := nodeApi.StateMinerInfo(ctx, maddr, types.EmptyTSK)
|
||||
|
74
cmd/lotus-shed/signatures.go
Normal file
74
cmd/lotus-shed/signatures.go
Normal file
@ -0,0 +1,74 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/lib/sigs"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var signaturesCmd = &cli.Command{
|
||||
Name: "signatures",
|
||||
Usage: "tools involving signatures",
|
||||
Subcommands: []*cli.Command{
|
||||
sigsVerifyVoteCmd,
|
||||
},
|
||||
}
|
||||
|
||||
var sigsVerifyVoteCmd = &cli.Command{
|
||||
Name: "verify-vote",
|
||||
Description: "can be used to verify signed votes being submitted for FILPolls",
|
||||
Usage: "<FIPnumber> <signingAddress> <signature>",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
|
||||
if cctx.Args().Len() != 3 {
|
||||
return xerrors.Errorf("usage: verify-vote <FIPnumber> <signingAddress> <signature>")
|
||||
}
|
||||
|
||||
fip, err := strconv.ParseInt(cctx.Args().First(), 10, 64)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("couldn't parse FIP number: %w", err)
|
||||
}
|
||||
|
||||
addr, err := address.NewFromString(cctx.Args().Get(1))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("couldn't parse signing address: %w", err)
|
||||
}
|
||||
|
||||
sigBytes, err := hex.DecodeString(cctx.Args().Get(2))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("couldn't parse sig: %w", err)
|
||||
}
|
||||
|
||||
var sig crypto.Signature
|
||||
if err := sig.UnmarshalBinary(sigBytes); err != nil {
|
||||
return xerrors.Errorf("couldn't unmarshal sig: %w", err)
|
||||
}
|
||||
|
||||
switch fip {
|
||||
case 14:
|
||||
approve := []byte("7 - Approve")
|
||||
|
||||
if sigs.Verify(&sig, addr, approve) == nil {
|
||||
fmt.Println("valid vote for approving FIP-0014")
|
||||
return nil
|
||||
}
|
||||
|
||||
reject := []byte("7 - Reject")
|
||||
if sigs.Verify(&sig, addr, reject) == nil {
|
||||
fmt.Println("valid vote for rejecting FIP-0014")
|
||||
return nil
|
||||
}
|
||||
|
||||
return xerrors.Errorf("invalid vote for FIP-0014!")
|
||||
default:
|
||||
return xerrors.Errorf("unrecognized FIP number")
|
||||
}
|
||||
},
|
||||
}
|
@ -35,80 +35,80 @@ var infoAllCmd = &cli.Command{
|
||||
|
||||
fmt.Println("#: Version")
|
||||
if err := lcli.VersionCmd.Action(cctx); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
fmt.Println("\n#: Miner Info")
|
||||
if err := infoCmdAct(cctx); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
// Verbose info
|
||||
|
||||
fmt.Println("\n#: Storage List")
|
||||
if err := storageListCmd.Action(cctx); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
fmt.Println("\n#: Worker List")
|
||||
if err := sealingWorkersCmd.Action(cctx); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
fmt.Println("\n#: PeerID")
|
||||
if err := lcli.NetId.Action(cctx); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
fmt.Println("\n#: Listen Addresses")
|
||||
if err := lcli.NetListen.Action(cctx); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
fmt.Println("\n#: Reachability")
|
||||
if err := lcli.NetReachability.Action(cctx); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
// Very Verbose info
|
||||
fmt.Println("\n#: Peers")
|
||||
if err := lcli.NetPeers.Action(cctx); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
fmt.Println("\n#: Sealing Jobs")
|
||||
if err := sealingJobsCmd.Action(cctx); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
fmt.Println("\n#: Sched Diag")
|
||||
if err := sealingSchedDiagCmd.Action(cctx); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
fmt.Println("\n#: Storage Ask")
|
||||
if err := getAskCmd.Action(cctx); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
fmt.Println("\n#: Storage Deals")
|
||||
if err := dealsListCmd.Action(cctx); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
fmt.Println("\n#: Retrieval Deals")
|
||||
if err := retrievalDealsListCmd.Action(cctx); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
fmt.Println("\n#: Sector List")
|
||||
if err := sectorsListCmd.Action(cctx); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
fmt.Println("\n#: Sector Refs")
|
||||
if err := sectorsRefsCmd.Action(cctx); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
// Very Very Verbose info
|
||||
@ -116,7 +116,7 @@ var infoAllCmd = &cli.Command{
|
||||
|
||||
list, err := nodeApi.SectorsList(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
sort.Slice(list, func(i, j int) bool {
|
||||
@ -129,11 +129,11 @@ var infoAllCmd = &cli.Command{
|
||||
fs := &flag.FlagSet{}
|
||||
for _, f := range sectorsStatusCmd.Flags {
|
||||
if err := f.Apply(fs); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
}
|
||||
if err := fs.Parse([]string{"--log", "--on-chain-info", fmt.Sprint(s)}); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
if err := sectorsStatusCmd.Action(cli.NewContext(cctx.App, fs, cctx)); err != nil {
|
||||
@ -144,7 +144,7 @@ var infoAllCmd = &cli.Command{
|
||||
|
||||
fs = &flag.FlagSet{}
|
||||
if err := fs.Parse([]string{fmt.Sprint(s)}); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
|
||||
if err := storageFindCmd.Action(cli.NewContext(cctx.App, fs, cctx)); err != nil {
|
||||
@ -155,7 +155,7 @@ var infoAllCmd = &cli.Command{
|
||||
if !_test {
|
||||
fmt.Println("\n#: Goroutines")
|
||||
if err := lcli.PprofGoroutines.Action(cctx); err != nil {
|
||||
return err
|
||||
fmt.Println("ERROR: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ type InteractiveWallet struct {
|
||||
lk sync.Mutex
|
||||
|
||||
apiGetter func() (api.FullNode, jsonrpc.ClientCloser, error)
|
||||
under api.WalletAPI
|
||||
under api.Wallet
|
||||
}
|
||||
|
||||
func (c *InteractiveWallet) WalletNew(ctx context.Context, typ types.KeyType) (address.Address, error) {
|
||||
|
@ -16,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
type LoggedWallet struct {
|
||||
under api.WalletAPI
|
||||
under api.Wallet
|
||||
}
|
||||
|
||||
func (c *LoggedWallet) WalletNew(ctx context.Context, typ types.KeyType) (address.Address, error) {
|
||||
|
@ -130,7 +130,7 @@ var runCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
var w api.WalletAPI = lw
|
||||
var w api.Wallet = lw
|
||||
if cctx.Bool("ledger") {
|
||||
ds, err := lr.Datastore(context.Background(), "/metadata")
|
||||
if err != nil {
|
||||
|
@ -289,7 +289,7 @@ var DaemonCmd = &cli.Command{
|
||||
|
||||
shutdownChan := make(chan struct{})
|
||||
|
||||
// If the daemon is started in "lite mode", provide a GatewayAPI
|
||||
// If the daemon is started in "lite mode", provide a Gateway
|
||||
// for RPC calls
|
||||
liteModeDeps := node.Options()
|
||||
if isLite {
|
||||
@ -299,7 +299,7 @@ var DaemonCmd = &cli.Command{
|
||||
}
|
||||
|
||||
defer closer()
|
||||
liteModeDeps = node.Override(new(api.GatewayAPI), gapi)
|
||||
liteModeDeps = node.Override(new(api.Gateway), gapi)
|
||||
}
|
||||
|
||||
// some libraries like ipfs/go-ds-measure and ipfs/go-ipfs-blockstore
|
||||
|
@ -37,6 +37,7 @@ func serveRPC(a api.FullNode, stop node.StopFunc, addr multiaddr.Multiaddr, shut
|
||||
}
|
||||
rpcServer := jsonrpc.NewServer(serverOptions...)
|
||||
rpcServer.Register("Filecoin", apistruct.PermissionedFullAPI(metrics.MetricedFullAPI(a)))
|
||||
rpcServer.AliasMethod("rpc.discover", "Filecoin.Discover")
|
||||
|
||||
ah := &auth.Handler{
|
||||
Verify: a.AuthVerify,
|
||||
|
@ -1,6 +1,7 @@
|
||||
# Groups
|
||||
* [](#)
|
||||
* [Closing](#Closing)
|
||||
* [Discover](#Discover)
|
||||
* [Session](#Session)
|
||||
* [Shutdown](#Shutdown)
|
||||
* [Version](#Version)
|
||||
@ -13,6 +14,8 @@
|
||||
* [AuthVerify](#AuthVerify)
|
||||
* [Check](#Check)
|
||||
* [CheckProvable](#CheckProvable)
|
||||
* [Compute](#Compute)
|
||||
* [ComputeProof](#ComputeProof)
|
||||
* [Create](#Create)
|
||||
* [CreateBackup](#CreateBackup)
|
||||
* [Deals](#Deals)
|
||||
@ -142,6 +145,25 @@ Inputs: `null`
|
||||
|
||||
Response: `{}`
|
||||
|
||||
### Discover
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
Inputs: `null`
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"info": {
|
||||
"title": "Lotus RPC API",
|
||||
"version": "1.2.1/generated=2020-11-22T08:22:42-06:00"
|
||||
},
|
||||
"methods": [],
|
||||
"openrpc": "1.2.6"
|
||||
}
|
||||
```
|
||||
|
||||
### Session
|
||||
|
||||
|
||||
@ -180,7 +202,7 @@ Response:
|
||||
|
||||
|
||||
### ActorAddress
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -189,7 +211,7 @@ Inputs: `null`
|
||||
Response: `"f01234"`
|
||||
|
||||
### ActorAddressConfig
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -207,7 +229,7 @@ Response:
|
||||
```
|
||||
|
||||
### ActorSectorSize
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -255,7 +277,7 @@ Response: `null`
|
||||
|
||||
|
||||
### CheckProvable
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -275,6 +297,24 @@ Response:
|
||||
}
|
||||
```
|
||||
|
||||
## Compute
|
||||
|
||||
|
||||
### ComputeProof
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
null,
|
||||
null
|
||||
]
|
||||
```
|
||||
|
||||
Response: `null`
|
||||
|
||||
## Create
|
||||
|
||||
|
||||
@ -300,63 +340,63 @@ Response: `{}`
|
||||
|
||||
|
||||
### DealsConsiderOfflineRetrievalDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
Perms: read
|
||||
|
||||
Perms: admin
|
||||
|
||||
Inputs: `null`
|
||||
|
||||
Response: `true`
|
||||
|
||||
### DealsConsiderOfflineStorageDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
Perms: read
|
||||
|
||||
Perms: admin
|
||||
|
||||
Inputs: `null`
|
||||
|
||||
Response: `true`
|
||||
|
||||
### DealsConsiderOnlineRetrievalDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
Perms: read
|
||||
|
||||
Perms: admin
|
||||
|
||||
Inputs: `null`
|
||||
|
||||
Response: `true`
|
||||
|
||||
### DealsConsiderOnlineStorageDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
Perms: read
|
||||
|
||||
Perms: admin
|
||||
|
||||
Inputs: `null`
|
||||
|
||||
Response: `true`
|
||||
|
||||
### DealsConsiderUnverifiedStorageDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
Perms: read
|
||||
|
||||
Perms: admin
|
||||
|
||||
Inputs: `null`
|
||||
|
||||
Response: `true`
|
||||
|
||||
### DealsConsiderVerifiedStorageDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
Perms: read
|
||||
|
||||
Perms: admin
|
||||
|
||||
Inputs: `null`
|
||||
|
||||
Response: `true`
|
||||
|
||||
### DealsImportData
|
||||
There are not yet any comments for this method.
|
||||
|
||||
Perms: write
|
||||
|
||||
Perms: admin
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
@ -371,25 +411,25 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### DealsList
|
||||
There are not yet any comments for this method.
|
||||
|
||||
Perms: read
|
||||
|
||||
Perms: admin
|
||||
|
||||
Inputs: `null`
|
||||
|
||||
Response: `null`
|
||||
|
||||
### DealsPieceCidBlocklist
|
||||
There are not yet any comments for this method.
|
||||
|
||||
Perms: read
|
||||
|
||||
Perms: admin
|
||||
|
||||
Inputs: `null`
|
||||
|
||||
Response: `null`
|
||||
|
||||
### DealsSetConsiderOfflineRetrievalDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -403,7 +443,7 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### DealsSetConsiderOfflineStorageDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -417,7 +457,7 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### DealsSetConsiderOnlineRetrievalDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -431,7 +471,7 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### DealsSetConsiderOnlineStorageDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -445,7 +485,7 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### DealsSetConsiderUnverifiedStorageDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -459,7 +499,7 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### DealsSetConsiderVerifiedStorageDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -473,7 +513,7 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### DealsSetPieceCidBlocklist
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -546,7 +586,7 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### MarketDataTransferUpdates
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: write
|
||||
|
||||
@ -565,12 +605,15 @@ Response:
|
||||
"Voucher": "string value",
|
||||
"Message": "string value",
|
||||
"OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf",
|
||||
"Transferred": 42
|
||||
"Transferred": 42,
|
||||
"Stages": {
|
||||
"Stages": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### MarketGetAsk
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -597,7 +640,7 @@ Response:
|
||||
```
|
||||
|
||||
### MarketGetDealUpdates
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -662,7 +705,7 @@ Response:
|
||||
```
|
||||
|
||||
### MarketGetRetrievalAsk
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -679,7 +722,7 @@ Response:
|
||||
```
|
||||
|
||||
### MarketImportDealData
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: write
|
||||
|
||||
@ -696,7 +739,7 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### MarketListDataTransfers
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: write
|
||||
|
||||
@ -705,7 +748,7 @@ Inputs: `null`
|
||||
Response: `null`
|
||||
|
||||
### MarketListDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -714,7 +757,7 @@ Inputs: `null`
|
||||
Response: `null`
|
||||
|
||||
### MarketListIncompleteDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -723,7 +766,7 @@ Inputs: `null`
|
||||
Response: `null`
|
||||
|
||||
### MarketListRetrievalDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -732,7 +775,7 @@ Inputs: `null`
|
||||
Response: `null`
|
||||
|
||||
### MarketPendingDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: write
|
||||
|
||||
@ -748,7 +791,7 @@ Response:
|
||||
```
|
||||
|
||||
### MarketPublishPendingDeals
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -774,7 +817,7 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### MarketSetAsk
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -792,7 +835,7 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### MarketSetRetrievalAsk
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -814,7 +857,7 @@ Response: `{}`
|
||||
|
||||
|
||||
### MiningBase
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -1102,7 +1145,7 @@ Response: `null`
|
||||
|
||||
|
||||
### PiecesGetCIDInfo
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -1126,7 +1169,7 @@ Response:
|
||||
```
|
||||
|
||||
### PiecesGetPieceInfo
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -1150,7 +1193,7 @@ Response:
|
||||
```
|
||||
|
||||
### PiecesListCidInfos
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -1159,7 +1202,7 @@ Inputs: `null`
|
||||
Response: `null`
|
||||
|
||||
### PiecesListPieces
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -1190,6 +1233,7 @@ Response:
|
||||
|
||||
|
||||
### ReturnAddPiece
|
||||
storiface.WorkerReturn
|
||||
|
||||
|
||||
Perms: admin
|
||||
@ -1475,7 +1519,7 @@ Response: `{}`
|
||||
|
||||
|
||||
### SealingAbort
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -1534,7 +1578,7 @@ Inputs: `null`
|
||||
Response: `60000000000`
|
||||
|
||||
### SectorMarkForUpgrade
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -1688,7 +1732,7 @@ Response:
|
||||
```
|
||||
|
||||
### SectorsRefs
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -1771,7 +1815,7 @@ Response:
|
||||
```
|
||||
|
||||
### SectorsUpdate
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -1789,7 +1833,7 @@ Response: `{}`
|
||||
|
||||
|
||||
### StorageAddLocal
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -1803,6 +1847,7 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### StorageAttach
|
||||
stores.SectorIndex
|
||||
|
||||
|
||||
Perms: admin
|
||||
@ -1931,7 +1976,7 @@ Response:
|
||||
```
|
||||
|
||||
### StorageList
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -1951,7 +1996,7 @@ Response:
|
||||
```
|
||||
|
||||
### StorageLocal
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -2009,7 +2054,7 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### StorageStat
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -2070,7 +2115,7 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### WorkerJobs
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -2102,7 +2147,7 @@ Response:
|
||||
```
|
||||
|
||||
### WorkerStats
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
|
||||
|
||||
### Enabled
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -81,7 +81,7 @@ Response:
|
||||
```
|
||||
|
||||
### Info
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -102,7 +102,7 @@ Response:
|
||||
```
|
||||
|
||||
### Paths
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -139,7 +139,6 @@ Inputs: `null`
|
||||
Response: `"07070707-0707-0707-0707-070707070707"`
|
||||
|
||||
### Version
|
||||
TODO: Info() (name, ...) ?
|
||||
|
||||
|
||||
Perms: admin
|
||||
@ -152,6 +151,7 @@ Response: `65792`
|
||||
|
||||
|
||||
### AddPiece
|
||||
storiface.WorkerCalls
|
||||
|
||||
|
||||
Perms: admin
|
||||
@ -488,7 +488,7 @@ Response: `{}`
|
||||
|
||||
|
||||
### StorageAddLocal
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -505,7 +505,7 @@ Response: `{}`
|
||||
|
||||
|
||||
### TaskDisable
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
@ -519,7 +519,7 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### TaskEnable
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
# Groups
|
||||
* [](#)
|
||||
* [Closing](#Closing)
|
||||
* [Discover](#Discover)
|
||||
* [Session](#Session)
|
||||
* [Shutdown](#Shutdown)
|
||||
* [Version](#Version)
|
||||
@ -34,6 +35,7 @@
|
||||
* [Client](#Client)
|
||||
* [ClientCalcCommP](#ClientCalcCommP)
|
||||
* [ClientCancelDataTransfer](#ClientCancelDataTransfer)
|
||||
* [ClientCancelRetrievalDeal](#ClientCancelRetrievalDeal)
|
||||
* [ClientDataTransferUpdates](#ClientDataTransferUpdates)
|
||||
* [ClientDealPieceCID](#ClientDealPieceCID)
|
||||
* [ClientDealSize](#ClientDealSize)
|
||||
@ -226,6 +228,25 @@ Inputs: `null`
|
||||
|
||||
Response: `{}`
|
||||
|
||||
### Discover
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
Inputs: `null`
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"info": {
|
||||
"title": "Lotus RPC API",
|
||||
"version": "1.2.1/generated=2020-11-22T08:22:42-06:00"
|
||||
},
|
||||
"methods": [],
|
||||
"openrpc": "1.2.6"
|
||||
}
|
||||
```
|
||||
|
||||
### Session
|
||||
|
||||
|
||||
@ -425,6 +446,17 @@ Response:
|
||||
### ChainGetBlockMessages
|
||||
ChainGetBlockMessages returns messages stored in the specified block.
|
||||
|
||||
Note: If there are multiple blocks in a tipset, it's likely that some
|
||||
messages will be duplicated. It's also possible for blocks in a tipset to have
|
||||
different messages from the same sender at the same nonce. When that happens,
|
||||
only the first message (in a block with lowest ticket) will be considered
|
||||
for execution
|
||||
|
||||
NOTE: THIS METHOD SHOULD ONLY BE USED FOR GETTING MESSAGES IN A SPECIFIC BLOCK
|
||||
|
||||
DO NOT USE THIS METHOD TO GET MESSAGES INCLUDED IN A TIPSET
|
||||
Use ChainGetParentMessages, which will perform correct message deduplication
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -499,7 +531,7 @@ Response:
|
||||
```
|
||||
|
||||
### ChainGetNode
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -540,7 +572,8 @@ Response: `null`
|
||||
|
||||
### ChainGetParentReceipts
|
||||
ChainGetParentReceipts returns receipts for messages in parent tipset of
|
||||
the specified block.
|
||||
the specified block. The receipts in the list returned is one-to-one with the
|
||||
messages returned by a call to ChainGetParentMessages with the same blockCid.
|
||||
|
||||
|
||||
Perms: read
|
||||
@ -853,7 +886,7 @@ retrieval markets as a client
|
||||
ClientCalcCommP calculates the CommP for a specified file
|
||||
|
||||
|
||||
Perms: read
|
||||
Perms: write
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
@ -889,8 +922,23 @@ Inputs:
|
||||
|
||||
Response: `{}`
|
||||
|
||||
### ClientCancelRetrievalDeal
|
||||
ClientCancelRetrievalDeal cancels an ongoing retrieval deal based on DealID
|
||||
|
||||
|
||||
Perms: write
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
5
|
||||
]
|
||||
```
|
||||
|
||||
Response: `{}`
|
||||
|
||||
### ClientDataTransferUpdates
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: write
|
||||
|
||||
@ -909,7 +957,10 @@ Response:
|
||||
"Voucher": "string value",
|
||||
"Message": "string value",
|
||||
"OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf",
|
||||
"Transferred": 42
|
||||
"Transferred": 42,
|
||||
"Stages": {
|
||||
"Stages": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@ -1022,6 +1073,9 @@ Response:
|
||||
},
|
||||
"State": 42,
|
||||
"Message": "string value",
|
||||
"DealStages": {
|
||||
"Stages": null
|
||||
},
|
||||
"Provider": "f01234",
|
||||
"DataRef": {
|
||||
"TransferType": "string value",
|
||||
@ -1057,7 +1111,10 @@ Response:
|
||||
"Voucher": "string value",
|
||||
"Message": "string value",
|
||||
"OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf",
|
||||
"Transferred": 42
|
||||
"Transferred": 42,
|
||||
"Stages": {
|
||||
"Stages": null
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -1081,7 +1138,7 @@ Response: `"string value"`
|
||||
ClientGetDealUpdates returns the status of updated deals
|
||||
|
||||
|
||||
Perms: read
|
||||
Perms: write
|
||||
|
||||
Inputs: `null`
|
||||
|
||||
@ -1093,6 +1150,9 @@ Response:
|
||||
},
|
||||
"State": 42,
|
||||
"Message": "string value",
|
||||
"DealStages": {
|
||||
"Stages": null
|
||||
},
|
||||
"Provider": "f01234",
|
||||
"DataRef": {
|
||||
"TransferType": "string value",
|
||||
@ -1128,7 +1188,10 @@ Response:
|
||||
"Voucher": "string value",
|
||||
"Message": "string value",
|
||||
"OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf",
|
||||
"Transferred": 42
|
||||
"Transferred": 42,
|
||||
"Stages": {
|
||||
"Stages": null
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -1320,6 +1383,7 @@ Inputs:
|
||||
},
|
||||
"Piece": null,
|
||||
"Size": 42,
|
||||
"LocalStore": 12,
|
||||
"Total": "0",
|
||||
"UnsealPrice": "0",
|
||||
"PaymentInterval": 42,
|
||||
@ -1373,6 +1437,7 @@ Inputs:
|
||||
},
|
||||
"Piece": null,
|
||||
"Size": 42,
|
||||
"LocalStore": 12,
|
||||
"Total": "0",
|
||||
"UnsealPrice": "0",
|
||||
"PaymentInterval": 42,
|
||||
@ -1762,7 +1827,7 @@ Response:
|
||||
|
||||
|
||||
### MinerCreateBlock
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: write
|
||||
|
||||
@ -2178,7 +2243,7 @@ Response: `null`
|
||||
MpoolSetConfig sets the mpool config to (a copy of) the supplied config
|
||||
|
||||
|
||||
Perms: write
|
||||
Perms: admin
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
@ -2197,7 +2262,7 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### MpoolSub
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -2943,7 +3008,7 @@ The Paych methods are for interacting with and managing payment channels
|
||||
|
||||
|
||||
### PaychAllocateLane
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: sign
|
||||
|
||||
@ -2957,7 +3022,7 @@ Inputs:
|
||||
Response: `42`
|
||||
|
||||
### PaychAvailableFunds
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: sign
|
||||
|
||||
@ -2983,7 +3048,7 @@ Response:
|
||||
```
|
||||
|
||||
### PaychAvailableFundsByFromTo
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: sign
|
||||
|
||||
@ -3010,7 +3075,7 @@ Response:
|
||||
```
|
||||
|
||||
### PaychCollect
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: sign
|
||||
|
||||
@ -3053,7 +3118,7 @@ Response:
|
||||
```
|
||||
|
||||
### PaychGetWaitReady
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: sign
|
||||
|
||||
@ -3069,7 +3134,7 @@ Inputs:
|
||||
Response: `"f01234"`
|
||||
|
||||
### PaychList
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -3078,7 +3143,7 @@ Inputs: `null`
|
||||
Response: `null`
|
||||
|
||||
### PaychNewPayment
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: sign
|
||||
|
||||
@ -3103,7 +3168,7 @@ Response:
|
||||
```
|
||||
|
||||
### PaychSettle
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: sign
|
||||
|
||||
@ -3122,7 +3187,7 @@ Response:
|
||||
```
|
||||
|
||||
### PaychStatus
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -3142,7 +3207,7 @@ Response:
|
||||
```
|
||||
|
||||
### PaychVoucherAdd
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: write
|
||||
|
||||
@ -3178,7 +3243,7 @@ Inputs:
|
||||
Response: `"0"`
|
||||
|
||||
### PaychVoucherCheckSpendable
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -3214,7 +3279,7 @@ Inputs:
|
||||
Response: `true`
|
||||
|
||||
### PaychVoucherCheckValid
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -3248,7 +3313,7 @@ Inputs:
|
||||
Response: `{}`
|
||||
|
||||
### PaychVoucherCreate
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: sign
|
||||
|
||||
@ -3289,7 +3354,7 @@ Response:
|
||||
```
|
||||
|
||||
### PaychVoucherList
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: write
|
||||
|
||||
@ -3303,7 +3368,7 @@ Inputs:
|
||||
Response: `null`
|
||||
|
||||
### PaychVoucherSubmit
|
||||
There are not yet any comments for this method.
|
||||
|
||||
|
||||
Perms: sign
|
||||
|
||||
@ -3565,6 +3630,36 @@ Response: `"0"`
|
||||
StateCompute is a flexible command that applies the given messages on the given tipset.
|
||||
The messages are run as though the VM were at the provided height.
|
||||
|
||||
When called, StateCompute will:
|
||||
- Load the provided tipset, or use the current chain head if not provided
|
||||
- Compute the tipset state of the provided tipset on top of the parent state
|
||||
- (note that this step runs before vmheight is applied to the execution)
|
||||
- Execute state upgrade if any were scheduled at the epoch, or in null
|
||||
blocks preceding the tipset
|
||||
- Call the cron actor on null blocks preceding the tipset
|
||||
- For each block in the tipset
|
||||
- Apply messages in blocks in the specified
|
||||
- Award block reward by calling the reward actor
|
||||
- Call the cron actor for the current epoch
|
||||
- If the specified vmheight is higher than the current epoch, apply any
|
||||
needed state upgrades to the state
|
||||
- Apply the specified messages to the state
|
||||
|
||||
The vmheight parameter sets VM execution epoch, and can be used to simulate
|
||||
message execution in different network versions. If the specified vmheight
|
||||
epoch is higher than the epoch of the specified tipset, any state upgrades
|
||||
until the vmheight will be executed on the state before applying messages
|
||||
specified by the user.
|
||||
|
||||
Note that the initial tipset state computation is not affected by the
|
||||
vmheight parameter - only the messages in the `apply` set are
|
||||
|
||||
If the caller wants to simply compute the state, vmheight should be set to
|
||||
the epoch of the specified tipset.
|
||||
|
||||
Messages in the `apply` parameter must have the correct nonces, and gas
|
||||
values set.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -3686,7 +3781,15 @@ Response:
|
||||
```
|
||||
|
||||
### StateGetReceipt
|
||||
StateGetReceipt returns the message receipt for the given message
|
||||
StateGetReceipt returns the message receipt for the given message or for a
|
||||
matching gas-repriced replacing message
|
||||
|
||||
NOTE: If the requested message was replaced, this method will return the receipt
|
||||
for the replacing message - if the caller needs the receipt for exactly the
|
||||
requested message, use StateSearchMsg().Receipt, and check that MsgLookup.Message
|
||||
is matching the requested CID
|
||||
|
||||
DEPRECATED: Use StateSearchMsg, this method won't be supported in v1 API
|
||||
|
||||
|
||||
Perms: read
|
||||
@ -4450,7 +4553,22 @@ Response:
|
||||
|
||||
### StateReplay
|
||||
StateReplay replays a given message, assuming it was included in a block in the specified tipset.
|
||||
If no tipset key is provided, the appropriate tipset is looked up.
|
||||
|
||||
If a tipset key is provided, and a replacing message is found on chain,
|
||||
the method will return an error saying that the message wasn't found
|
||||
|
||||
If no tipset key is provided, the appropriate tipset is looked up, and if
|
||||
the message was gas-repriced, the on-chain message will be replayed - in
|
||||
that case the returned InvocResult.MsgCid will not match the Cid param
|
||||
|
||||
If the caller wants to ensure that exactly the requested message was executed,
|
||||
they MUST check that InvocResult.MsgCid is equal to the provided Cid.
|
||||
Without this check both the requested and original message may appear as
|
||||
successfully executed on-chain, which may look like a double-spend.
|
||||
|
||||
A replacing message is a message with a different CID, any of Gas values, and
|
||||
different signature, but with all other parameters matching (source/destination,
|
||||
nonce, params, etc.)
|
||||
|
||||
|
||||
Perms: read
|
||||
@ -4544,6 +4662,20 @@ Response:
|
||||
### StateSearchMsg
|
||||
StateSearchMsg searches for a message in the chain, and returns its receipt and the tipset where it was executed
|
||||
|
||||
NOTE: If a replacing message is found on chain, this method will return
|
||||
a MsgLookup for the replacing message - the MsgLookup.Message will be a different
|
||||
CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the
|
||||
result of the execution of the replacing message.
|
||||
|
||||
If the caller wants to ensure that exactly the requested message was executed,
|
||||
they MUST check that MsgLookup.Message is equal to the provided 'cid'.
|
||||
Without this check both the requested and original message may appear as
|
||||
successfully executed on-chain, which may look like a double-spend.
|
||||
|
||||
A replacing message is a message with a different CID, any of Gas values, and
|
||||
different signature, but with all other parameters matching (source/destination,
|
||||
nonce, params, etc.)
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -4583,6 +4715,20 @@ Response:
|
||||
### StateSearchMsgLimited
|
||||
StateSearchMsgLimited looks back up to limit epochs in the chain for a message, and returns its receipt and the tipset where it was executed
|
||||
|
||||
NOTE: If a replacing message is found on chain, this method will return
|
||||
a MsgLookup for the replacing message - the MsgLookup.Message will be a different
|
||||
CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the
|
||||
result of the execution of the replacing message.
|
||||
|
||||
If the caller wants to ensure that exactly the requested message was executed,
|
||||
they MUST check that MsgLookup.Message is equal to the provided 'cid'.
|
||||
Without this check both the requested and original message may appear as
|
||||
successfully executed on-chain, which may look like a double-spend.
|
||||
|
||||
A replacing message is a message with a different CID, any of Gas values, and
|
||||
different signature, but with all other parameters matching (source/destination,
|
||||
nonce, params, etc.)
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -4877,6 +5023,20 @@ Response: `"0"`
|
||||
StateWaitMsg looks back in the chain for a message. If not found, it blocks until the
|
||||
message arrives on chain, and gets to the indicated confidence depth.
|
||||
|
||||
NOTE: If a replacing message is found on chain, this method will return
|
||||
a MsgLookup for the replacing message - the MsgLookup.Message will be a different
|
||||
CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the
|
||||
result of the execution of the replacing message.
|
||||
|
||||
If the caller wants to ensure that exactly the requested message was executed,
|
||||
they MUST check that MsgLookup.Message is equal to the provided 'cid'.
|
||||
Without this check both the requested and original message may appear as
|
||||
successfully executed on-chain, which may look like a double-spend.
|
||||
|
||||
A replacing message is a message with a different CID, any of Gas values, and
|
||||
different signature, but with all other parameters matching (source/destination,
|
||||
nonce, params, etc.)
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -4919,6 +5079,20 @@ StateWaitMsgLimited looks back up to limit epochs in the chain for a message.
|
||||
If not found, it blocks until the message arrives on chain, and gets to the
|
||||
indicated confidence depth.
|
||||
|
||||
NOTE: If a replacing message is found on chain, this method will return
|
||||
a MsgLookup for the replacing message - the MsgLookup.Message will be a different
|
||||
CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the
|
||||
result of the execution of the replacing message.
|
||||
|
||||
If the caller wants to ensure that exactly the requested message was executed,
|
||||
they MUST check that MsgLookup.Message is equal to the provided 'cid'.
|
||||
Without this check both the requested and original message may appear as
|
||||
successfully executed on-chain, which may look like a double-spend.
|
||||
|
||||
A replacing message is a message with a different CID, any of Gas values, and
|
||||
different signature, but with all other parameters matching (source/destination,
|
||||
nonce, params, etc.)
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
@ -5219,7 +5393,7 @@ Response: `"f01234"`
|
||||
WalletDelete deletes an address from the wallet.
|
||||
|
||||
|
||||
Perms: write
|
||||
Perms: admin
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
@ -5315,7 +5489,7 @@ Response: `"f01234"`
|
||||
WalletSetDefault marks the given address as as the default one.
|
||||
|
||||
|
||||
Perms: admin
|
||||
Perms: write
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
|
3
extern/sector-storage/mock/mock.go
vendored
3
extern/sector-storage/mock/mock.go
vendored
@ -325,6 +325,8 @@ func (mgr *SectorMgr) GenerateWindowPoSt(ctx context.Context, minerID abi.ActorI
|
||||
}
|
||||
|
||||
func generateFakePoStProof(sectorInfo []proof2.SectorInfo, randomness abi.PoStRandomness) []byte {
|
||||
randomness[31] &= 0x3f
|
||||
|
||||
hasher := sha256.New()
|
||||
_, _ = hasher.Write(randomness)
|
||||
for _, info := range sectorInfo {
|
||||
@ -489,6 +491,7 @@ func (m mockVerif) VerifySeal(svi proof2.SealVerifyInfo) (bool, error) {
|
||||
}
|
||||
|
||||
func (m mockVerif) VerifyWinningPoSt(ctx context.Context, info proof2.WinningPoStVerifyInfo) (bool, error) {
|
||||
info.Randomness[31] &= 0x3f
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
9
extern/sector-storage/stores/http_handler.go
vendored
9
extern/sector-storage/stores/http_handler.go
vendored
@ -116,9 +116,16 @@ func (handler *FetchHandler) remoteGetSector(w http.ResponseWriter, r *http.Requ
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
if !stat.IsDir() {
|
||||
defer func() {
|
||||
if err := rd.(*os.File).Close(); err != nil {
|
||||
log.Errorf("closing source file: %+v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
w.WriteHeader(200)
|
||||
if _, err := io.Copy(w, rd); err != nil { // TODO: default 32k buf may be too small
|
||||
if _, err := io.CopyBuffer(w, rd, make([]byte, CopyBuf)); err != nil {
|
||||
log.Errorf("%+v", err)
|
||||
return
|
||||
}
|
||||
|
6
extern/sector-storage/stores/local.go
vendored
6
extern/sector-storage/stores/local.go
vendored
@ -392,8 +392,10 @@ func (st *Local) Reserve(ctx context.Context, sid storage.SectorRef, ft storifac
|
||||
}
|
||||
|
||||
p.reserved += overhead
|
||||
p.reservations[sid.ID] |= fileType
|
||||
|
||||
prevDone := done
|
||||
saveFileType := fileType
|
||||
done = func() {
|
||||
prevDone()
|
||||
|
||||
@ -401,6 +403,10 @@ func (st *Local) Reserve(ctx context.Context, sid storage.SectorRef, ft storifac
|
||||
defer st.localLk.Unlock()
|
||||
|
||||
p.reserved -= overhead
|
||||
p.reservations[sid.ID] ^= saveFileType
|
||||
if p.reservations[sid.ID] == storiface.FTNone {
|
||||
delete(p.reservations, sid.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
10
extern/storage-sealing/checks.go
vendored
10
extern/storage-sealing/checks.go
vendored
@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
|
||||
proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof"
|
||||
@ -94,14 +93,9 @@ func checkPrecommit(ctx context.Context, maddr address.Address, si SectorInfo, t
|
||||
return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %s != %s", commD, si.CommD)}
|
||||
}
|
||||
|
||||
nv, err := api.StateNetworkVersion(ctx, tok)
|
||||
if err != nil {
|
||||
return &ErrApi{xerrors.Errorf("calling StateNetworkVersion: %w", err)}
|
||||
}
|
||||
ticketEarliest := height - policy.MaxPreCommitRandomnessLookback
|
||||
|
||||
msd := policy.GetMaxProveCommitDuration(actors.VersionForNetwork(nv), si.SectorType)
|
||||
|
||||
if height-(si.TicketEpoch+policy.SealRandomnessLookback) > msd {
|
||||
if si.TicketEpoch < ticketEarliest {
|
||||
return &ErrExpiredTicket{xerrors.Errorf("ticket expired: seal height: %d, head: %d", si.TicketEpoch+policy.SealRandomnessLookback, height)}
|
||||
}
|
||||
|
||||
|
35
extern/storage-sealing/fsm.go
vendored
35
extern/storage-sealing/fsm.go
vendored
@ -300,7 +300,9 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta
|
||||
|
||||
*/
|
||||
|
||||
m.stats.updateSector(m.minerSectorID(state.SectorNumber), state.State)
|
||||
if err := m.onUpdateSector(context.TODO(), state); err != nil {
|
||||
log.Errorw("update sector stats", "error", err)
|
||||
}
|
||||
|
||||
switch state.State {
|
||||
// Happy path
|
||||
@ -391,6 +393,37 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta
|
||||
return nil, processed, nil
|
||||
}
|
||||
|
||||
func (m *Sealing) onUpdateSector(ctx context.Context, state *SectorInfo) error {
|
||||
if m.getConfig == nil {
|
||||
return nil // tests
|
||||
}
|
||||
|
||||
cfg, err := m.getConfig()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting config: %w", err)
|
||||
}
|
||||
sp, err := m.currentSealProof(ctx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting seal proof type: %w", err)
|
||||
}
|
||||
|
||||
shouldUpdateInput := m.stats.updateSector(cfg, m.minerSectorID(state.SectorNumber), state.State)
|
||||
|
||||
// trigger more input processing when we've dipped below max sealing limits
|
||||
if shouldUpdateInput {
|
||||
go func() {
|
||||
m.inputLk.Lock()
|
||||
defer m.inputLk.Unlock()
|
||||
|
||||
if err := m.updateInput(ctx, sp); err != nil {
|
||||
log.Errorf("%+v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func planCommitting(events []statemachine.Event, state *SectorInfo) (uint64, error) {
|
||||
for i, event := range events {
|
||||
switch e := event.User.(type) {
|
||||
|
11
extern/storage-sealing/garbage.go
vendored
11
extern/storage-sealing/garbage.go
vendored
@ -28,18 +28,13 @@ func (m *Sealing) PledgeSector(ctx context.Context) (storage.SectorRef, error) {
|
||||
return storage.SectorRef{}, xerrors.Errorf("getting seal proof type: %w", err)
|
||||
}
|
||||
|
||||
sid, err := m.sc.Next()
|
||||
sid, err := m.createSector(ctx, cfg, spt)
|
||||
if err != nil {
|
||||
return storage.SectorRef{}, xerrors.Errorf("generating sector number: %w", err)
|
||||
}
|
||||
sectorID := m.minerSector(spt, sid)
|
||||
err = m.sealer.NewSector(ctx, sectorID)
|
||||
if err != nil {
|
||||
return storage.SectorRef{}, xerrors.Errorf("notifying sealer of the new sector: %w", err)
|
||||
return storage.SectorRef{}, err
|
||||
}
|
||||
|
||||
log.Infof("Creating CC sector %d", sid)
|
||||
return sectorID, m.sectors.Send(uint64(sid), SectorStartCC{
|
||||
return m.minerSector(spt, sid), m.sectors.Send(uint64(sid), SectorStartCC{
|
||||
ID: sid,
|
||||
SectorType: spt,
|
||||
})
|
||||
|
32
extern/storage-sealing/input.go
vendored
32
extern/storage-sealing/input.go
vendored
@ -16,6 +16,7 @@ import (
|
||||
|
||||
sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/lotus/extern/storage-sealing/sealiface"
|
||||
)
|
||||
|
||||
func (m *Sealing) handleWaitDeals(ctx statemachine.Context, sector SectorInfo) error {
|
||||
@ -388,16 +389,9 @@ func (m *Sealing) tryCreateDealSector(ctx context.Context, sp abi.RegisteredSeal
|
||||
return nil
|
||||
}
|
||||
|
||||
// Now actually create a new sector
|
||||
|
||||
sid, err := m.sc.Next()
|
||||
sid, err := m.createSector(ctx, cfg, sp)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting sector number: %w", err)
|
||||
}
|
||||
|
||||
err = m.sealer.NewSector(ctx, m.minerSector(sp, sid))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("initializing sector: %w", err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infow("Creating sector", "number", sid, "type", "deal", "proofType", sp)
|
||||
@ -407,6 +401,26 @@ func (m *Sealing) tryCreateDealSector(ctx context.Context, sp abi.RegisteredSeal
|
||||
})
|
||||
}
|
||||
|
||||
// call with m.inputLk
|
||||
func (m *Sealing) createSector(ctx context.Context, cfg sealiface.Config, sp abi.RegisteredSealProof) (abi.SectorNumber, error) {
|
||||
// Now actually create a new sector
|
||||
|
||||
sid, err := m.sc.Next()
|
||||
if err != nil {
|
||||
return 0, xerrors.Errorf("getting sector number: %w", err)
|
||||
}
|
||||
|
||||
err = m.sealer.NewSector(ctx, m.minerSector(sp, sid))
|
||||
if err != nil {
|
||||
return 0, xerrors.Errorf("initializing sector: %w", err)
|
||||
}
|
||||
|
||||
// update stats early, fsm planner would do that async
|
||||
m.stats.updateSector(cfg, m.minerSectorID(sid), UndefinedSectorState)
|
||||
|
||||
return sid, nil
|
||||
}
|
||||
|
||||
func (m *Sealing) StartPacking(sid abi.SectorNumber) error {
|
||||
return m.sectors.Send(uint64(sid), SectorStartPacking{})
|
||||
}
|
||||
|
3
extern/storage-sealing/states_sealing.go
vendored
3
extern/storage-sealing/states_sealing.go
vendored
@ -12,7 +12,6 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
"github.com/filecoin-project/go-statemachine"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-storage/storage"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
@ -22,7 +21,7 @@ import (
|
||||
)
|
||||
|
||||
var DealSectorPriority = 1024
|
||||
var MaxTicketAge = abi.ChainEpoch(builtin0.EpochsInDay * 2)
|
||||
var MaxTicketAge = policy.MaxPreCommitRandomnessLookback
|
||||
|
||||
func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) error {
|
||||
m.inputLk.Lock()
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user