Merge branch 'testnet/3' into feat/specs-actors
This commit is contained in:
commit
d787aa5007
@ -7,6 +7,9 @@ executors:
|
||||
docker:
|
||||
- image: circleci/golang:1.13
|
||||
resource_class: 2xlarge
|
||||
ubuntu:
|
||||
docker:
|
||||
- image: ubuntu:19.10
|
||||
|
||||
commands:
|
||||
install-deps:
|
||||
@ -24,6 +27,8 @@ commands:
|
||||
description: is a darwin build environment?
|
||||
type: boolean
|
||||
steps:
|
||||
- checkout
|
||||
- git_fetch_all_tags
|
||||
- checkout
|
||||
- when:
|
||||
condition: << parameters.linux >>
|
||||
@ -46,7 +51,27 @@ commands:
|
||||
key: 'v20-1k-lotus-params'
|
||||
paths:
|
||||
- /var/tmp/filecoin-proof-parameters/
|
||||
|
||||
install_ipfs:
|
||||
steps:
|
||||
- run: |
|
||||
apt update
|
||||
apt install -y wget
|
||||
wget https://github.com/ipfs/go-ipfs/releases/download/v0.4.22/go-ipfs_v0.4.22_linux-amd64.tar.gz
|
||||
wget https://github.com/ipfs/go-ipfs/releases/download/v0.4.22/go-ipfs_v0.4.22_linux-amd64.tar.gz.sha512
|
||||
if [ "$(sha512sum go-ipfs_v0.4.22_linux-amd64.tar.gz)" != "$(cat go-ipfs_v0.4.22_linux-amd64.tar.gz.sha512)" ]
|
||||
then
|
||||
echo "ipfs failed checksum check"
|
||||
exit 1
|
||||
fi
|
||||
tar -xf go-ipfs_v0.4.22_linux-amd64.tar.gz
|
||||
mv go-ipfs/ipfs /usr/local/bin/ipfs
|
||||
chmod +x /usr/local/bin/ipfs
|
||||
git_fetch_all_tags:
|
||||
steps:
|
||||
- run:
|
||||
name: fetch all tags
|
||||
command: |
|
||||
git fetch --all
|
||||
|
||||
jobs:
|
||||
mod-tidy-check:
|
||||
@ -74,6 +99,13 @@ jobs:
|
||||
path: lotus
|
||||
- store_artifacts:
|
||||
path: lotus-storage-miner
|
||||
- store_artifacts:
|
||||
path: lotus-seal-worker
|
||||
- run: mkdir linux && mv lotus lotus-storage-miner lotus-seal-worker linux/
|
||||
- persist_to_workspace:
|
||||
root: "."
|
||||
paths:
|
||||
- linux
|
||||
|
||||
test: &test
|
||||
description: |
|
||||
@ -153,7 +185,7 @@ jobs:
|
||||
- "~/go/src/github.com"
|
||||
- "~/go/src/golang.org"
|
||||
|
||||
test-short:
|
||||
test-short:
|
||||
<<: *test
|
||||
|
||||
build-macos:
|
||||
@ -196,6 +228,13 @@ jobs:
|
||||
path: lotus
|
||||
- store_artifacts:
|
||||
path: lotus-storage-miner
|
||||
- store_artifacts:
|
||||
path: lotus-seal-worker
|
||||
- run: mkdir darwin && mv lotus lotus-storage-miner lotus-seal-worker darwin/
|
||||
- persist_to_workspace:
|
||||
root: "."
|
||||
paths:
|
||||
- darwin
|
||||
- save_cache:
|
||||
name: save cargo cache
|
||||
key: v3-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.sum" }}
|
||||
@ -246,6 +285,26 @@ jobs:
|
||||
lint-all:
|
||||
<<: *lint
|
||||
|
||||
publish:
|
||||
description: publish binary artifacts
|
||||
executor: ubuntu
|
||||
steps:
|
||||
- run:
|
||||
name: Install git jq curl
|
||||
command: apt update && apt install -y git jq curl
|
||||
- checkout
|
||||
- git_fetch_all_tags
|
||||
- checkout
|
||||
- install_ipfs
|
||||
- attach_workspace:
|
||||
at: "."
|
||||
- run:
|
||||
name: Create bundles
|
||||
command: ./scripts/build-bundle.sh
|
||||
- run:
|
||||
name: Publish release
|
||||
command: ./scripts/publish-release.sh
|
||||
|
||||
|
||||
workflows:
|
||||
version: 2.1
|
||||
@ -255,8 +314,38 @@ workflows:
|
||||
args: "--new-from-rev origin/master"
|
||||
- test:
|
||||
codecov-upload: true
|
||||
- mod-tidy-check
|
||||
- test-short:
|
||||
go-test-flags: "--timeout 10m --short"
|
||||
- mod-tidy-check
|
||||
- build-all
|
||||
- build-macos
|
||||
filters:
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+$/
|
||||
- build-all:
|
||||
requires:
|
||||
- test-short
|
||||
filters:
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+$/
|
||||
- build-macos:
|
||||
requires:
|
||||
- test-short
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- /.*/
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+$/
|
||||
- publish:
|
||||
requires:
|
||||
- build-all
|
||||
- build-macos
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- /.*/
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+$/
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -26,6 +26,9 @@ build/paramfetch.sh
|
||||
/blocks.svg
|
||||
/chainwatch
|
||||
/chainwatch.db
|
||||
/bundle
|
||||
/darwin
|
||||
/linux
|
||||
|
||||
*-fuzz.zip
|
||||
/chain/types/work_msg/
|
||||
|
@ -1,7 +1,8 @@
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- vet
|
||||
- gofmt
|
||||
- govet
|
||||
- goimports
|
||||
- misspell
|
||||
- goconst
|
||||
|
@ -23,12 +23,16 @@ type Common interface {
|
||||
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)
|
||||
|
||||
// ID returns peerID of libp2p node backing this API
|
||||
ID(context.Context) (peer.ID, error)
|
||||
|
||||
// Version provides information about API provider
|
||||
Version(context.Context) (Version, error)
|
||||
|
||||
LogList(context.Context) ([]string, error)
|
||||
LogSetLevel(context.Context, string, string) error
|
||||
}
|
||||
|
||||
// Version provides various build-time information
|
||||
|
@ -37,25 +37,26 @@ type FullNode interface {
|
||||
ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error)
|
||||
ChainGetParentReceipts(context.Context, cid.Cid) ([]*types.MessageReceipt, error)
|
||||
ChainGetParentMessages(context.Context, cid.Cid) ([]Message, error)
|
||||
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error)
|
||||
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error)
|
||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||
ChainSetHead(context.Context, *types.TipSet) error
|
||||
ChainSetHead(context.Context, types.TipSetKey) error
|
||||
ChainGetGenesis(context.Context) (*types.TipSet, error)
|
||||
ChainTipSetWeight(context.Context, *types.TipSet) (types.BigInt, error)
|
||||
ChainTipSetWeight(context.Context, types.TipSetKey) (types.BigInt, error)
|
||||
ChainGetNode(ctx context.Context, p string) (interface{}, error)
|
||||
ChainGetMessage(context.Context, cid.Cid) (*types.Message, error)
|
||||
ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*store.HeadChange, error)
|
||||
ChainExport(context.Context, *types.TipSet) (<-chan []byte, error)
|
||||
ChainExport(context.Context, types.TipSetKey) (<-chan []byte, error)
|
||||
|
||||
// syncer
|
||||
SyncState(context.Context) (*SyncState, error)
|
||||
SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error
|
||||
SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error)
|
||||
SyncMarkBad(ctx context.Context, bcid cid.Cid) error
|
||||
SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error)
|
||||
|
||||
// messages
|
||||
MpoolPending(context.Context, *types.TipSet) ([]*types.SignedMessage, error)
|
||||
MpoolPending(context.Context, types.TipSetKey) ([]*types.SignedMessage, error)
|
||||
MpoolPush(context.Context, *types.SignedMessage) (cid.Cid, error)
|
||||
MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) // get nonce, sign, push
|
||||
MpoolGetNonce(context.Context, address.Address) (uint64, error)
|
||||
@ -65,7 +66,7 @@ type FullNode interface {
|
||||
|
||||
// miner
|
||||
|
||||
MinerCreateBlock(context.Context, address.Address, *types.TipSet, *types.Ticket, *types.EPostProof, []*types.SignedMessage, abi.ChainEpoch, uint64) (*types.BlockMsg, error)
|
||||
MinerCreateBlock(context.Context, address.Address, types.TipSetKey, *types.Ticket, *types.EPostProof, []*types.SignedMessage, abi.ChainEpoch, uint64) (*types.BlockMsg, error)
|
||||
|
||||
// // UX ?
|
||||
|
||||
@ -103,35 +104,35 @@ type FullNode interface {
|
||||
//ClientListAsks() []Ask
|
||||
|
||||
// if tipset is nil, we'll use heaviest
|
||||
StateCall(context.Context, *types.Message, *types.TipSet) (*MethodCall, error)
|
||||
StateReplay(context.Context, *types.TipSet, cid.Cid) (*ReplayResults, error)
|
||||
StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error)
|
||||
StateReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*ActorState, error)
|
||||
StateListMessages(ctx context.Context, match *types.Message, ts *types.TipSet, toht abi.ChainEpoch) ([]cid.Cid, error)
|
||||
StateCall(context.Context, *types.Message, types.TipSetKey) (*MethodCall, error)
|
||||
StateReplay(context.Context, types.TipSetKey, cid.Cid) (*ReplayResults, error)
|
||||
StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error)
|
||||
StateReadState(ctx context.Context, act *types.Actor, tsk types.TipSetKey) (*ActorState, error)
|
||||
StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error)
|
||||
|
||||
StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error)
|
||||
StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error)
|
||||
StateMinerPower(context.Context, address.Address, *types.TipSet) (MinerPower, error)
|
||||
StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error)
|
||||
StateMinerPeerID(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error)
|
||||
StateMinerPostState(ctx context.Context, actor address.Address, ts *types.TipSet) (*miner.PoStState, error)
|
||||
StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (abi.SectorSize, error)
|
||||
StateMinerFaults(context.Context, address.Address, *types.TipSet) ([]abi.SectorNumber, error)
|
||||
StatePledgeCollateral(context.Context, *types.TipSet) (types.BigInt, error)
|
||||
StateMinerSectors(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error)
|
||||
StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error)
|
||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (MinerPower, error)
|
||||
StateMinerWorker(context.Context, address.Address, types.TipSetKey) (address.Address, error)
|
||||
StateMinerPeerID(ctx context.Context, m address.Address, tsk types.TipSetKey) (peer.ID, error)
|
||||
StateMinerPostState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*miner.PoStState, error)
|
||||
StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error)
|
||||
StateMinerFaults(context.Context, address.Address, types.TipSetKey) ([]abi.SectorNumber, error)
|
||||
StatePledgeCollateral(context.Context, types.TipSetKey) (types.BigInt, error)
|
||||
StateWaitMsg(context.Context, cid.Cid) (*MsgWait, error)
|
||||
StateListMiners(context.Context, *types.TipSet) ([]address.Address, error)
|
||||
StateListActors(context.Context, *types.TipSet) ([]address.Address, error)
|
||||
StateMarketBalance(context.Context, address.Address, *types.TipSet) (MarketBalance, error)
|
||||
StateMarketParticipants(context.Context, *types.TipSet) (map[string]MarketBalance, error)
|
||||
StateMarketDeals(context.Context, *types.TipSet) (map[string]MarketDeal, error)
|
||||
StateMarketStorageDeal(context.Context, abi.DealID, *types.TipSet) (*MarketDeal, error)
|
||||
StateLookupID(context.Context, address.Address, *types.TipSet) (address.Address, error)
|
||||
StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error)
|
||||
StateListActors(context.Context, types.TipSetKey) ([]address.Address, error)
|
||||
StateMarketBalance(context.Context, address.Address, types.TipSetKey) (MarketBalance, error)
|
||||
StateMarketParticipants(context.Context, types.TipSetKey) (map[string]MarketBalance, error)
|
||||
StateMarketDeals(context.Context, types.TipSetKey) (map[string]MarketDeal, error)
|
||||
StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*MarketDeal, error)
|
||||
StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error)
|
||||
StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error)
|
||||
StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error)
|
||||
StateMinerSectorCount(context.Context, address.Address, *types.TipSet) (MinerSectors, error)
|
||||
StateCompute(context.Context, abi.ChainEpoch, []*types.Message, *types.TipSet) (cid.Cid, error)
|
||||
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
|
||||
StateMinerSectorCount(context.Context, address.Address, types.TipSetKey) (MinerSectors, error)
|
||||
StateCompute(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (cid.Cid, error)
|
||||
|
||||
MsigGetAvailableBalance(context.Context, address.Address, *types.TipSet) (types.BigInt, error)
|
||||
MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
||||
|
||||
MarketEnsureAvailable(context.Context, address.Address, types.BigInt) error
|
||||
// MarketFreeBalance
|
||||
|
@ -33,9 +33,13 @@ type CommonStruct struct {
|
||||
NetConnect func(context.Context, peer.AddrInfo) error `perm:"write"`
|
||||
NetAddrsListen func(context.Context) (peer.AddrInfo, error) `perm:"read"`
|
||||
NetDisconnect func(context.Context, peer.ID) error `perm:"write"`
|
||||
NetFindPeer func(context.Context, peer.ID) (peer.AddrInfo, error) `perm:"read"`
|
||||
|
||||
ID func(context.Context) (peer.ID, error) `perm:"read"`
|
||||
Version func(context.Context) (api.Version, error) `perm:"read"`
|
||||
|
||||
LogList func(context.Context) ([]string, error) `perm:"write"`
|
||||
LogSetLevel func(context.Context, string, string) error `perm:"write"`
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,29 +56,30 @@ type FullNodeStruct struct {
|
||||
ChainGetBlockMessages func(context.Context, cid.Cid) (*api.BlockMessages, error) `perm:"read"`
|
||||
ChainGetParentReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"`
|
||||
ChainGetParentMessages func(context.Context, cid.Cid) ([]api.Message, error) `perm:"read"`
|
||||
ChainGetTipSetByHeight func(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error) `perm:"read"`
|
||||
ChainGetTipSetByHeight func(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) `perm:"read"`
|
||||
ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"`
|
||||
ChainHasObj func(context.Context, cid.Cid) (bool, error) `perm:"read"`
|
||||
ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"`
|
||||
ChainSetHead func(context.Context, types.TipSetKey) error `perm:"admin"`
|
||||
ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"`
|
||||
ChainTipSetWeight func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"`
|
||||
ChainTipSetWeight func(context.Context, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
ChainGetNode func(ctx context.Context, p string) (interface{}, error) `perm:"read"`
|
||||
ChainGetMessage func(context.Context, cid.Cid) (*types.Message, error) `perm:"read"`
|
||||
ChainGetPath func(context.Context, types.TipSetKey, types.TipSetKey) ([]*store.HeadChange, error) `perm:"read"`
|
||||
ChainExport func(context.Context, *types.TipSet) (<-chan []byte, error) `perm:"read"`
|
||||
ChainExport func(context.Context, types.TipSetKey) (<-chan []byte, error) `perm:"read"`
|
||||
|
||||
SyncState func(context.Context) (*api.SyncState, error) `perm:"read"`
|
||||
SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"`
|
||||
SyncIncomingBlocks func(ctx context.Context) (<-chan *types.BlockHeader, error) `perm:"read"`
|
||||
SyncMarkBad func(ctx context.Context, bcid cid.Cid) error `perm:"admin"`
|
||||
SyncCheckBad func(ctx context.Context, bcid cid.Cid) (string, error) `perm:"read"`
|
||||
|
||||
MpoolPending func(context.Context, *types.TipSet) ([]*types.SignedMessage, error) `perm:"read"`
|
||||
MpoolPending func(context.Context, types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"`
|
||||
MpoolPush func(context.Context, *types.SignedMessage) (cid.Cid, error) `perm:"write"`
|
||||
MpoolPushMessage func(context.Context, *types.Message) (*types.SignedMessage, error) `perm:"sign"`
|
||||
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
|
||||
MpoolSub func(context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"`
|
||||
|
||||
MinerCreateBlock func(context.Context, address.Address, *types.TipSet, *types.Ticket, *types.EPostProof, []*types.SignedMessage, abi.ChainEpoch, uint64) (*types.BlockMsg, error) `perm:"write"`
|
||||
MinerCreateBlock func(context.Context, address.Address, types.TipSetKey, *types.Ticket, *types.EPostProof, []*types.SignedMessage, abi.ChainEpoch, uint64) (*types.BlockMsg, error) `perm:"write"`
|
||||
|
||||
WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"`
|
||||
WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"`
|
||||
@ -97,34 +102,34 @@ type FullNodeStruct struct {
|
||||
ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, path string) error `perm:"admin"`
|
||||
ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) `perm:"read"`
|
||||
|
||||
StateMinerSectors func(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) `perm:"read"`
|
||||
StateMinerProvingSet func(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) `perm:"read"`
|
||||
StateMinerPower func(context.Context, address.Address, *types.TipSet) (api.MinerPower, error) `perm:"read"`
|
||||
StateMinerWorker func(context.Context, address.Address, *types.TipSet) (address.Address, error) `perm:"read"`
|
||||
StateMinerPeerID func(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error) `perm:"read"`
|
||||
StateMinerPostState func(ctx context.Context, actor address.Address, ts *types.TipSet) (*miner.PoStState, error) `perm:"read"`
|
||||
StateMinerSectorSize func(context.Context, address.Address, *types.TipSet) (abi.SectorSize, error) `perm:"read"`
|
||||
StateMinerFaults func(context.Context, address.Address, *types.TipSet) ([]abi.SectorNumber, error) `perm:"read"`
|
||||
StateCall func(context.Context, *types.Message, *types.TipSet) (*api.MethodCall, error) `perm:"read"`
|
||||
StateReplay func(context.Context, *types.TipSet, cid.Cid) (*api.ReplayResults, error) `perm:"read"`
|
||||
StateGetActor func(context.Context, address.Address, *types.TipSet) (*types.Actor, error) `perm:"read"`
|
||||
StateReadState func(context.Context, *types.Actor, *types.TipSet) (*api.ActorState, error) `perm:"read"`
|
||||
StatePledgeCollateral func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"`
|
||||
StateMinerSectors func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
|
||||
StateMinerProvingSet func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
|
||||
StateMinerPower func(context.Context, address.Address, types.TipSetKey) (api.MinerPower, error) `perm:"read"`
|
||||
StateMinerWorker func(context.Context, address.Address, types.TipSetKey) (address.Address, error) `perm:"read"`
|
||||
StateMinerPeerID func(ctx context.Context, m address.Address, tsk types.TipSetKey) (peer.ID, error) `perm:"read"`
|
||||
StateMinerPostState func(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*miner.PoStState, error) `perm:"read"`
|
||||
StateMinerSectorSize func(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error) `perm:"read"`
|
||||
StateMinerFaults func(context.Context, address.Address, types.TipSetKey) ([]abi.SectorNumber, error) `perm:"read"`
|
||||
StateCall func(context.Context, *types.Message, types.TipSetKey) (*api.MethodCall, error) `perm:"read"`
|
||||
StateReplay func(context.Context, types.TipSetKey, cid.Cid) (*api.ReplayResults, error) `perm:"read"`
|
||||
StateGetActor func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) `perm:"read"`
|
||||
StateReadState func(context.Context, *types.Actor, types.TipSetKey) (*api.ActorState, error) `perm:"read"`
|
||||
StatePledgeCollateral func(context.Context, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
StateWaitMsg func(context.Context, cid.Cid) (*api.MsgWait, error) `perm:"read"`
|
||||
StateListMiners func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"`
|
||||
StateListActors func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"`
|
||||
StateMarketBalance func(context.Context, address.Address, *types.TipSet) (api.MarketBalance, error) `perm:"read"`
|
||||
StateMarketParticipants func(context.Context, *types.TipSet) (map[string]api.MarketBalance, error) `perm:"read"`
|
||||
StateMarketDeals func(context.Context, *types.TipSet) (map[string]api.MarketDeal, error) `perm:"read"`
|
||||
StateMarketStorageDeal func(context.Context, abi.DealID, *types.TipSet) (*api.MarketDeal, error) `perm:"read"`
|
||||
StateLookupID func(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) `perm:"read"`
|
||||
StateListMiners func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"`
|
||||
StateListActors func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"`
|
||||
StateMarketBalance func(context.Context, address.Address, types.TipSetKey) (api.MarketBalance, error) `perm:"read"`
|
||||
StateMarketParticipants func(context.Context, types.TipSetKey) (map[string]api.MarketBalance, error) `perm:"read"`
|
||||
StateMarketDeals func(context.Context, types.TipSetKey) (map[string]api.MarketDeal, error) `perm:"read"`
|
||||
StateMarketStorageDeal func(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error) `perm:"read"`
|
||||
StateLookupID func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) `perm:"read"`
|
||||
StateChangedActors func(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) `perm:"read"`
|
||||
StateGetReceipt func(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"`
|
||||
StateMinerSectorCount func(context.Context, address.Address, *types.TipSet) (api.MinerSectors, error) `perm:"read"`
|
||||
StateListMessages func(ctx context.Context, match *types.Message, ts *types.TipSet, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"`
|
||||
StateCompute func(context.Context, abi.ChainEpoch, []*types.Message, *types.TipSet) (cid.Cid, error) `perm:"read"`
|
||||
StateGetReceipt func(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) `perm:"read"`
|
||||
StateMinerSectorCount func(context.Context, address.Address, types.TipSetKey) (api.MinerSectors, error) `perm:"read"`
|
||||
StateListMessages func(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"`
|
||||
StateCompute func(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (cid.Cid, error) `perm:"read"`
|
||||
|
||||
MsigGetAvailableBalance func(context.Context, address.Address, *types.TipSet) (types.BigInt, error) `perm:"read"`
|
||||
MsigGetAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
|
||||
MarketEnsureAvailable func(context.Context, address.Address, types.BigInt) error `perm:"sign"`
|
||||
|
||||
@ -144,8 +149,8 @@ type FullNodeStruct struct {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerSectorCount(ctx context.Context, addr address.Address, ts *types.TipSet) (api.MinerSectors, error) {
|
||||
return c.Internal.StateMinerSectorCount(ctx, addr, ts)
|
||||
func (c *FullNodeStruct) StateMinerSectorCount(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MinerSectors, error) {
|
||||
return c.Internal.StateMinerSectorCount(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
type StorageMinerStruct struct {
|
||||
@ -197,6 +202,10 @@ func (c *CommonStruct) NetDisconnect(ctx context.Context, p peer.ID) error {
|
||||
return c.Internal.NetDisconnect(ctx, p)
|
||||
}
|
||||
|
||||
func (c *CommonStruct) NetFindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, error) {
|
||||
return c.Internal.NetFindPeer(ctx, p)
|
||||
}
|
||||
|
||||
// ID implements API.ID
|
||||
func (c *CommonStruct) ID(ctx context.Context) (peer.ID, error) {
|
||||
return c.Internal.ID(ctx)
|
||||
@ -207,6 +216,14 @@ func (c *CommonStruct) Version(ctx context.Context) (api.Version, error) {
|
||||
return c.Internal.Version(ctx)
|
||||
}
|
||||
|
||||
func (c *CommonStruct) LogList(ctx context.Context) ([]string, error) {
|
||||
return c.Internal.LogList(ctx)
|
||||
}
|
||||
|
||||
func (c *CommonStruct) LogSetLevel(ctx context.Context, group, level string) error {
|
||||
return c.Internal.LogSetLevel(ctx, group, level)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ClientListImports(ctx context.Context) ([]api.Import, error) {
|
||||
return c.Internal.ClientListImports(ctx)
|
||||
}
|
||||
@ -242,8 +259,8 @@ func (c *FullNodeStruct) ClientQueryAsk(ctx context.Context, p peer.ID, miner ad
|
||||
return c.Internal.ClientQueryAsk(ctx, p, miner)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MpoolPending(ctx context.Context, ts *types.TipSet) ([]*types.SignedMessage, error) {
|
||||
return c.Internal.MpoolPending(ctx, ts)
|
||||
func (c *FullNodeStruct) MpoolPending(ctx context.Context, tsk types.TipSetKey) ([]*types.SignedMessage, error) {
|
||||
return c.Internal.MpoolPending(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MpoolPush(ctx context.Context, smsg *types.SignedMessage) (cid.Cid, error) {
|
||||
@ -258,7 +275,7 @@ func (c *FullNodeStruct) MpoolSub(ctx context.Context) (<-chan api.MpoolUpdate,
|
||||
return c.Internal.MpoolSub(ctx)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MinerCreateBlock(ctx context.Context, addr address.Address, base *types.TipSet, ticket *types.Ticket, eproof *types.EPostProof, msgs []*types.SignedMessage, height abi.ChainEpoch, ts uint64) (*types.BlockMsg, error) {
|
||||
func (c *FullNodeStruct) MinerCreateBlock(ctx context.Context, addr address.Address, base types.TipSetKey, ticket *types.Ticket, eproof *types.EPostProof, msgs []*types.SignedMessage, height abi.ChainEpoch, ts uint64) (*types.BlockMsg, error) {
|
||||
return c.Internal.MinerCreateBlock(ctx, addr, base, ticket, eproof, msgs, height, ts)
|
||||
}
|
||||
|
||||
@ -270,8 +287,8 @@ func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, tsk types.TipSe
|
||||
return c.Internal.ChainGetRandomness(ctx, tsk, personalization, randEpoch, entropy)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, ts *types.TipSet) (*types.TipSet, error) {
|
||||
return c.Internal.ChainGetTipSetByHeight(ctx, h, ts)
|
||||
func (c *FullNodeStruct) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) {
|
||||
return c.Internal.ChainGetTipSetByHeight(ctx, h, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) WalletNew(ctx context.Context, typ crypto.SigType) (address.Address, error) {
|
||||
@ -350,16 +367,16 @@ func (c *FullNodeStruct) ChainHasObj(ctx context.Context, o cid.Cid) (bool, erro
|
||||
return c.Internal.ChainHasObj(ctx, o)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainSetHead(ctx context.Context, ts *types.TipSet) error {
|
||||
return c.Internal.ChainSetHead(ctx, ts)
|
||||
func (c *FullNodeStruct) ChainSetHead(ctx context.Context, tsk types.TipSetKey) error {
|
||||
return c.Internal.ChainSetHead(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainGetGenesis(ctx context.Context) (*types.TipSet, error) {
|
||||
return c.Internal.ChainGetGenesis(ctx)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainTipSetWeight(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
|
||||
return c.Internal.ChainTipSetWeight(ctx, ts)
|
||||
func (c *FullNodeStruct) ChainTipSetWeight(ctx context.Context, tsk types.TipSetKey) (types.BigInt, error) {
|
||||
return c.Internal.ChainTipSetWeight(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainGetNode(ctx context.Context, p string) (interface{}, error) {
|
||||
@ -374,8 +391,8 @@ func (c *FullNodeStruct) ChainGetPath(ctx context.Context, from types.TipSetKey,
|
||||
return c.Internal.ChainGetPath(ctx, from, to)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainExport(ctx context.Context, ts *types.TipSet) (<-chan []byte, error) {
|
||||
return c.Internal.ChainExport(ctx, ts)
|
||||
func (c *FullNodeStruct) ChainExport(ctx context.Context, tsk types.TipSetKey) (<-chan []byte, error) {
|
||||
return c.Internal.ChainExport(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) SyncState(ctx context.Context) (*api.SyncState, error) {
|
||||
@ -394,107 +411,111 @@ func (c *FullNodeStruct) SyncMarkBad(ctx context.Context, bcid cid.Cid) error {
|
||||
return c.Internal.SyncMarkBad(ctx, bcid)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*api.ChainSectorInfo, error) {
|
||||
return c.Internal.StateMinerSectors(ctx, addr, ts)
|
||||
func (c *FullNodeStruct) SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error) {
|
||||
return c.Internal.SyncCheckBad(ctx, bcid)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerProvingSet(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*api.ChainSectorInfo, error) {
|
||||
return c.Internal.StateMinerProvingSet(ctx, addr, ts)
|
||||
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
|
||||
return c.Internal.StateMinerSectors(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerPower(ctx context.Context, a address.Address, ts *types.TipSet) (api.MinerPower, error) {
|
||||
return c.Internal.StateMinerPower(ctx, a, ts)
|
||||
func (c *FullNodeStruct) StateMinerProvingSet(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
|
||||
return c.Internal.StateMinerProvingSet(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerWorker(ctx context.Context, m address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
return c.Internal.StateMinerWorker(ctx, m, ts)
|
||||
func (c *FullNodeStruct) StateMinerPower(ctx context.Context, a address.Address, tsk types.TipSetKey) (api.MinerPower, error) {
|
||||
return c.Internal.StateMinerPower(ctx, a, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerPeerID(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error) {
|
||||
return c.Internal.StateMinerPeerID(ctx, m, ts)
|
||||
func (c *FullNodeStruct) StateMinerWorker(ctx context.Context, m address.Address, tsk types.TipSetKey) (address.Address, error) {
|
||||
return c.Internal.StateMinerWorker(ctx, m, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerPostState(ctx context.Context, actor address.Address, ts *types.TipSet) (*miner.PoStState, error) {
|
||||
return c.Internal.StateMinerPostState(ctx, actor, ts)
|
||||
func (c *FullNodeStruct) StateMinerPeerID(ctx context.Context, m address.Address, tsk types.TipSetKey) (peer.ID, error) {
|
||||
return c.Internal.StateMinerPeerID(ctx, m, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerSectorSize(ctx context.Context, actor address.Address, ts *types.TipSet) (abi.SectorSize, error) {
|
||||
return c.Internal.StateMinerSectorSize(ctx, actor, ts)
|
||||
func (c *FullNodeStruct) StateMinerPostState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*miner.PoStState, error) {
|
||||
return c.Internal.StateMinerPostState(ctx, actor, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerFaults(ctx context.Context, actor address.Address, ts *types.TipSet) ([]abi.SectorNumber, error) {
|
||||
return c.Internal.StateMinerFaults(ctx, actor, ts)
|
||||
func (c *FullNodeStruct) StateMinerSectorSize(ctx context.Context, actor address.Address, tsk types.TipSetKey) (abi.SectorSize, error) {
|
||||
return c.Internal.StateMinerSectorSize(ctx, actor, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*api.MethodCall, error) {
|
||||
return c.Internal.StateCall(ctx, msg, ts)
|
||||
func (c *FullNodeStruct) StateMinerFaults(ctx context.Context, actor address.Address, tsk types.TipSetKey) ([]abi.SectorNumber, error) {
|
||||
return c.Internal.StateMinerFaults(ctx, actor, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateReplay(ctx context.Context, ts *types.TipSet, mc cid.Cid) (*api.ReplayResults, error) {
|
||||
return c.Internal.StateReplay(ctx, ts, mc)
|
||||
func (c *FullNodeStruct) StateCall(ctx context.Context, msg *types.Message, tsk types.TipSetKey) (*api.MethodCall, error) {
|
||||
return c.Internal.StateCall(ctx, msg, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
return c.Internal.StateGetActor(ctx, actor, ts)
|
||||
func (c *FullNodeStruct) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid.Cid) (*api.ReplayResults, error) {
|
||||
return c.Internal.StateReplay(ctx, tsk, mc)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*api.ActorState, error) {
|
||||
return c.Internal.StateReadState(ctx, act, ts)
|
||||
func (c *FullNodeStruct) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||
return c.Internal.StateGetActor(ctx, actor, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StatePledgeCollateral(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
|
||||
return c.Internal.StatePledgeCollateral(ctx, ts)
|
||||
func (c *FullNodeStruct) StateReadState(ctx context.Context, act *types.Actor, tsk types.TipSetKey) (*api.ActorState, error) {
|
||||
return c.Internal.StateReadState(ctx, act, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StatePledgeCollateral(ctx context.Context, tsk types.TipSetKey) (types.BigInt, error) {
|
||||
return c.Internal.StatePledgeCollateral(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateWaitMsg(ctx context.Context, msgc cid.Cid) (*api.MsgWait, error) {
|
||||
return c.Internal.StateWaitMsg(ctx, msgc)
|
||||
}
|
||||
func (c *FullNodeStruct) StateListMiners(ctx context.Context, ts *types.TipSet) ([]address.Address, error) {
|
||||
return c.Internal.StateListMiners(ctx, ts)
|
||||
func (c *FullNodeStruct) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) {
|
||||
return c.Internal.StateListMiners(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateListActors(ctx context.Context, ts *types.TipSet) ([]address.Address, error) {
|
||||
return c.Internal.StateListActors(ctx, ts)
|
||||
func (c *FullNodeStruct) StateListActors(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) {
|
||||
return c.Internal.StateListActors(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMarketBalance(ctx context.Context, addr address.Address, ts *types.TipSet) (api.MarketBalance, error) {
|
||||
return c.Internal.StateMarketBalance(ctx, addr, ts)
|
||||
func (c *FullNodeStruct) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) {
|
||||
return c.Internal.StateMarketBalance(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMarketParticipants(ctx context.Context, ts *types.TipSet) (map[string]api.MarketBalance, error) {
|
||||
return c.Internal.StateMarketParticipants(ctx, ts)
|
||||
func (c *FullNodeStruct) StateMarketParticipants(ctx context.Context, tsk types.TipSetKey) (map[string]api.MarketBalance, error) {
|
||||
return c.Internal.StateMarketParticipants(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMarketDeals(ctx context.Context, ts *types.TipSet) (map[string]api.MarketDeal, error) {
|
||||
return c.Internal.StateMarketDeals(ctx, ts)
|
||||
func (c *FullNodeStruct) StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (map[string]api.MarketDeal, error) {
|
||||
return c.Internal.StateMarketDeals(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMarketStorageDeal(ctx context.Context, dealid abi.DealID, ts *types.TipSet) (*api.MarketDeal, error) {
|
||||
return c.Internal.StateMarketStorageDeal(ctx, dealid, ts)
|
||||
func (c *FullNodeStruct) StateMarketStorageDeal(ctx context.Context, dealid abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) {
|
||||
return c.Internal.StateMarketStorageDeal(ctx, dealid, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateLookupID(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
return c.Internal.StateLookupID(ctx, addr, ts)
|
||||
func (c *FullNodeStruct) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
|
||||
return c.Internal.StateLookupID(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateChangedActors(ctx context.Context, olnstate cid.Cid, newstate cid.Cid) (map[string]types.Actor, error) {
|
||||
return c.Internal.StateChangedActors(ctx, olnstate, newstate)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateGetReceipt(ctx context.Context, msg cid.Cid, ts *types.TipSet) (*types.MessageReceipt, error) {
|
||||
return c.Internal.StateGetReceipt(ctx, msg, ts)
|
||||
func (c *FullNodeStruct) StateGetReceipt(ctx context.Context, msg cid.Cid, tsk types.TipSetKey) (*types.MessageReceipt, error) {
|
||||
return c.Internal.StateGetReceipt(ctx, msg, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateListMessages(ctx context.Context, match *types.Message, ts *types.TipSet, toht abi.ChainEpoch) ([]cid.Cid, error) {
|
||||
return c.Internal.StateListMessages(ctx, match, ts, toht)
|
||||
func (c *FullNodeStruct) StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) {
|
||||
return c.Internal.StateListMessages(ctx, match, tsk, toht)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateCompute(ctx context.Context, height abi.ChainEpoch, msgs []*types.Message, ts *types.TipSet) (cid.Cid, error) {
|
||||
return c.Internal.StateCompute(ctx, height, msgs, ts)
|
||||
func (c *FullNodeStruct) StateCompute(ctx context.Context, height abi.ChainEpoch, msgs []*types.Message, tsk types.TipSetKey) (cid.Cid, error) {
|
||||
return c.Internal.StateCompute(ctx, height, msgs, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MsigGetAvailableBalance(ctx context.Context, a address.Address, ts *types.TipSet) (types.BigInt, error) {
|
||||
return c.Internal.MsigGetAvailableBalance(ctx, a, ts)
|
||||
func (c *FullNodeStruct) MsigGetAvailableBalance(ctx context.Context, a address.Address, tsk types.TipSetKey) (types.BigInt, error) {
|
||||
return c.Internal.MsigGetAvailableBalance(ctx, a, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MarketEnsureAvailable(ctx context.Context, addr address.Address, amt types.BigInt) error {
|
||||
|
@ -23,6 +23,8 @@ func SupportedSectorSize(ssize abi.SectorSize) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
const SectorChallengeRatioDiv = 25
|
||||
|
||||
// /////
|
||||
// Payments
|
||||
|
||||
|
@ -21,10 +21,15 @@ func NewBadBlockCache() *BadBlockCache {
|
||||
}
|
||||
}
|
||||
|
||||
func (bts *BadBlockCache) Add(c cid.Cid) {
|
||||
bts.badBlocks.Add(c, nil)
|
||||
func (bts *BadBlockCache) Add(c cid.Cid, reason string) {
|
||||
bts.badBlocks.Add(c, reason)
|
||||
}
|
||||
|
||||
func (bts *BadBlockCache) Has(c cid.Cid) bool {
|
||||
return bts.badBlocks.Contains(c)
|
||||
func (bts *BadBlockCache) Has(c cid.Cid) (string, bool) {
|
||||
rval, ok := bts.badBlocks.Get(c)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
|
||||
return rval.(string), true
|
||||
}
|
||||
|
@ -34,10 +34,10 @@ type heightHandler struct {
|
||||
type eventApi interface {
|
||||
ChainNotify(context.Context) (<-chan []*store.HeadChange, error)
|
||||
ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error)
|
||||
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error)
|
||||
StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error)
|
||||
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error)
|
||||
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
|
||||
|
||||
StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) // optional / for CalledMsg
|
||||
StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) // optional / for CalledMsg
|
||||
}
|
||||
|
||||
type Events struct {
|
||||
|
@ -193,7 +193,7 @@ func (e *calledEvents) applyWithConfidence(ts *types.TipSet) {
|
||||
continue
|
||||
}
|
||||
|
||||
rec, err := e.cs.StateGetReceipt(e.ctx, event.msg.Cid(), ts)
|
||||
rec, err := e.cs.StateGetReceipt(e.ctx, event.msg.Cid(), ts.Key())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
|
@ -43,15 +43,15 @@ type fakeCS struct {
|
||||
sub func(rev, app []*types.TipSet)
|
||||
}
|
||||
|
||||
func (fcs *fakeCS) StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) {
|
||||
func (fcs *fakeCS) StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (fcs *fakeCS) StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
func (fcs *fakeCS) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||
panic("Not Implemented")
|
||||
}
|
||||
|
||||
func (fcs *fakeCS) ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error) {
|
||||
func (fcs *fakeCS) ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) {
|
||||
panic("Not Implemented")
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
type tsByHFunc func(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error)
|
||||
type tsByHFunc func(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error)
|
||||
|
||||
// tipSetCache implements a simple ring-buffer cache to keep track of recent
|
||||
// tipsets
|
||||
@ -94,7 +94,7 @@ func (tsc *tipSetCache) getNonNull(height abi.ChainEpoch) (*types.TipSet, error)
|
||||
func (tsc *tipSetCache) get(height abi.ChainEpoch) (*types.TipSet, error) {
|
||||
if tsc.len == 0 {
|
||||
log.Warnf("tipSetCache.get: cache is empty, requesting from storage (h=%d)", height)
|
||||
return tsc.storage(context.TODO(), height, nil)
|
||||
return tsc.storage(context.TODO(), height, types.EmptyTSK)
|
||||
}
|
||||
|
||||
headH := tsc.cache[tsc.start].Height()
|
||||
@ -114,7 +114,7 @@ func (tsc *tipSetCache) get(height abi.ChainEpoch) (*types.TipSet, error) {
|
||||
|
||||
if height < tail.Height() {
|
||||
log.Warnf("tipSetCache.get: requested tipset not in cache, requesting from storage (h=%d; tail=%d)", height, tail.Height())
|
||||
return tsc.storage(context.TODO(), height, tail)
|
||||
return tsc.storage(context.TODO(), height, tail.Key())
|
||||
}
|
||||
|
||||
return tsc.cache[normalModulo(tsc.start-int(headH-height), clen)], nil
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
func TestTsCache(t *testing.T) {
|
||||
tsc := newTSCache(50, func(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error) {
|
||||
tsc := newTSCache(50, func(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) {
|
||||
t.Fatal("storage call")
|
||||
return &types.TipSet{}, nil
|
||||
})
|
||||
@ -56,7 +56,7 @@ func TestTsCache(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTsCacheNulls(t *testing.T) {
|
||||
tsc := newTSCache(50, func(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error) {
|
||||
tsc := newTSCache(50, func(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) {
|
||||
t.Fatal("storage call")
|
||||
return &types.TipSet{}, nil
|
||||
})
|
||||
|
@ -13,7 +13,7 @@ func (e *calledEvents) CheckMsg(ctx context.Context, smsg store.ChainMsg, hnd Ca
|
||||
msg := smsg.VMMessage()
|
||||
|
||||
return func(ts *types.TipSet) (done bool, more bool, err error) {
|
||||
fa, err := e.cs.StateGetActor(ctx, msg.From, ts)
|
||||
fa, err := e.cs.StateGetActor(ctx, msg.From, ts.Key())
|
||||
if err != nil {
|
||||
return false, true, err
|
||||
}
|
||||
@ -23,7 +23,7 @@ func (e *calledEvents) CheckMsg(ctx context.Context, smsg store.ChainMsg, hnd Ca
|
||||
return false, true, nil
|
||||
}
|
||||
|
||||
rec, err := e.cs.StateGetReceipt(ctx, smsg.VMMessage().Cid(), ts)
|
||||
rec, err := e.cs.StateGetReceipt(ctx, smsg.VMMessage().Cid(), ts.Key())
|
||||
if err != nil {
|
||||
return false, true, xerrors.Errorf("getting receipt in CheckMsg: %w", err)
|
||||
}
|
||||
|
@ -444,13 +444,13 @@ func (cg *ChainGen) YieldRepo() (repo.Repo, error) {
|
||||
type MiningCheckAPI interface {
|
||||
ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
|
||||
|
||||
StateMinerPower(context.Context, address.Address, *types.TipSet) (api.MinerPower, error)
|
||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (api.MinerPower, error)
|
||||
|
||||
StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error)
|
||||
StateMinerWorker(context.Context, address.Address, types.TipSetKey) (address.Address, error)
|
||||
|
||||
StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (abi.SectorSize, error)
|
||||
StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error)
|
||||
|
||||
StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error)
|
||||
StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error)
|
||||
|
||||
WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error)
|
||||
}
|
||||
@ -469,7 +469,11 @@ func (mca mca) ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, pers
|
||||
return mca.sm.ChainStore().GetRandomness(ctx, pts.Cids(), personalization, int64(randEpoch), entropy)
|
||||
}
|
||||
|
||||
func (mca mca) StateMinerPower(ctx context.Context, maddr address.Address, ts *types.TipSet) (api.MinerPower, error) {
|
||||
func (mca mca) StateMinerPower(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (api.MinerPower, error) {
|
||||
ts, err := mca.sm.ChainStore().LoadTipSet(tsk)
|
||||
if err != nil {
|
||||
return api.MinerPower{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
mpow, tpow, err := stmgr.GetPower(ctx, mca.sm, ts, maddr)
|
||||
if err != nil {
|
||||
return api.MinerPower{}, err
|
||||
@ -481,15 +485,27 @@ func (mca mca) StateMinerPower(ctx context.Context, maddr address.Address, ts *t
|
||||
}, err
|
||||
}
|
||||
|
||||
func (mca mca) StateMinerWorker(ctx context.Context, maddr address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
func (mca mca) StateMinerWorker(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (address.Address, error) {
|
||||
ts, err := mca.sm.ChainStore().LoadTipSet(tsk)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return stmgr.GetMinerWorkerRaw(ctx, mca.sm, ts.ParentState(), maddr)
|
||||
}
|
||||
|
||||
func (mca mca) StateMinerSectorSize(ctx context.Context, maddr address.Address, ts *types.TipSet) (abi.SectorSize, error) {
|
||||
func (mca mca) StateMinerSectorSize(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (abi.SectorSize, error) {
|
||||
ts, err := mca.sm.ChainStore().LoadTipSet(tsk)
|
||||
if err != nil {
|
||||
return 0, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return stmgr.GetMinerSectorSize(ctx, mca.sm, ts, maddr)
|
||||
}
|
||||
|
||||
func (mca mca) StateMinerProvingSet(ctx context.Context, maddr address.Address, ts *types.TipSet) ([]*api.ChainSectorInfo, error) {
|
||||
func (mca mca) StateMinerProvingSet(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
|
||||
ts, err := mca.sm.ChainStore().LoadTipSet(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return stmgr.GetMinerProvingSet(ctx, mca.sm, ts, maddr)
|
||||
}
|
||||
|
||||
@ -533,7 +549,7 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner add
|
||||
return nil, xerrors.Errorf("chain get randomness: %w", err)
|
||||
}
|
||||
|
||||
mworker, err := a.StateMinerWorker(ctx, miner, ts)
|
||||
mworker, err := a.StateMinerWorker(ctx, miner, ts.Key())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get miner worker: %w", err)
|
||||
}
|
||||
@ -543,7 +559,7 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner add
|
||||
return nil, xerrors.Errorf("failed to compute VRF: %w", err)
|
||||
}
|
||||
|
||||
pset, err := a.StateMinerProvingSet(ctx, miner, ts)
|
||||
pset, err := a.StateMinerProvingSet(ctx, miner, ts.Key())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to load proving set for miner: %w", err)
|
||||
}
|
||||
@ -572,12 +588,12 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner add
|
||||
return nil, xerrors.Errorf("failed to generate electionPoSt candidates: %w", err)
|
||||
}
|
||||
|
||||
pow, err := a.StateMinerPower(ctx, miner, ts)
|
||||
pow, err := a.StateMinerPower(ctx, miner, ts.Key())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to check power: %w", err)
|
||||
}
|
||||
|
||||
ssize, err := a.StateMinerSectorSize(ctx, miner, ts)
|
||||
ssize, err := a.StateMinerSectorSize(ctx, miner, ts.Key())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to look up miners sector size: %w", err)
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import (
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -96,7 +96,7 @@ func sendHeadNotifs(ctx context.Context, ps *pubsub.PubSub, topic string, chain
|
||||
case notif := <-notifs:
|
||||
n := notif[len(notif)-1]
|
||||
|
||||
w, err := chain.ChainTipSetWeight(ctx, n.Val)
|
||||
w, err := chain.ChainTipSetWeight(ctx, n.Val.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ import (
|
||||
. "github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||
|
@ -1066,3 +1066,11 @@ func NewChainRand(cs *ChainStore, blks []cid.Cid, bheight abi.ChainEpoch) vm.Ran
|
||||
func (cr *chainRand) GetRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round int64, entropy []byte) ([]byte, error) {
|
||||
return cr.cs.GetRandomness(ctx, cr.blks, pers, round, entropy)
|
||||
}
|
||||
|
||||
func (cs *ChainStore) GetTipSetFromKey(tsk types.TipSetKey) (*types.TipSet, error) {
|
||||
if tsk.IsEmpty() {
|
||||
return cs.GetHeaviestTipSet(), nil
|
||||
} else {
|
||||
return cs.LoadTipSet(tsk)
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,11 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
"github.com/ipfs/go-cid"
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
connmgr "github.com/libp2p/go-libp2p-core/connmgr"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
@ -28,15 +31,9 @@ func HandleIncomingBlocks(ctx context.Context, bsub *pubsub.Subscription, s *cha
|
||||
continue
|
||||
}
|
||||
|
||||
blk, err := types.DecodeBlockMsg(msg.GetData())
|
||||
if err != nil {
|
||||
log.Error("got invalid block over pubsub: ", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if len(blk.BlsMessages)+len(blk.SecpkMessages) > build.BlockMessageLimit {
|
||||
log.Warnf("received block with too many messages over pubsub")
|
||||
continue
|
||||
blk, ok := msg.ValidatorData.(*types.BlockMsg)
|
||||
if !ok {
|
||||
log.Warnf("pubsub block validator passed on wrong type: %#v", msg.ValidatorData)
|
||||
}
|
||||
|
||||
go func() {
|
||||
@ -73,6 +70,89 @@ func HandleIncomingBlocks(ctx context.Context, bsub *pubsub.Subscription, s *cha
|
||||
}
|
||||
}
|
||||
|
||||
type BlockValidator struct {
|
||||
peers *lru.TwoQueueCache
|
||||
|
||||
killThresh int
|
||||
|
||||
recvBlocks *blockReceiptCache
|
||||
|
||||
blacklist func(peer.ID)
|
||||
}
|
||||
|
||||
func NewBlockValidator(blacklist func(peer.ID)) *BlockValidator {
|
||||
p, _ := lru.New2Q(4096)
|
||||
return &BlockValidator{
|
||||
peers: p,
|
||||
killThresh: 5,
|
||||
blacklist: blacklist,
|
||||
recvBlocks: newBlockReceiptCache(),
|
||||
}
|
||||
}
|
||||
|
||||
func (bv *BlockValidator) flagPeer(p peer.ID) {
|
||||
v, ok := bv.peers.Get(p)
|
||||
if !ok {
|
||||
bv.peers.Add(p, int(1))
|
||||
return
|
||||
}
|
||||
|
||||
val := v.(int)
|
||||
|
||||
if val >= bv.killThresh {
|
||||
bv.blacklist(p)
|
||||
}
|
||||
|
||||
bv.peers.Add(p, v.(int)+1)
|
||||
}
|
||||
|
||||
func (bv *BlockValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub.Message) bool {
|
||||
blk, err := types.DecodeBlockMsg(msg.GetData())
|
||||
if err != nil {
|
||||
log.Error("got invalid block over pubsub: ", err)
|
||||
bv.flagPeer(pid)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(blk.BlsMessages)+len(blk.SecpkMessages) > build.BlockMessageLimit {
|
||||
log.Warnf("received block with too many messages over pubsub")
|
||||
bv.flagPeer(pid)
|
||||
return false
|
||||
}
|
||||
|
||||
if bv.recvBlocks.add(blk.Header.Cid()) > 0 {
|
||||
// TODO: once these changes propagate to the network, we can consider
|
||||
// dropping peers who send us the same block multiple times
|
||||
return false
|
||||
}
|
||||
|
||||
msg.ValidatorData = blk
|
||||
return true
|
||||
}
|
||||
|
||||
type blockReceiptCache struct {
|
||||
blocks *lru.TwoQueueCache
|
||||
}
|
||||
|
||||
func newBlockReceiptCache() *blockReceiptCache {
|
||||
c, _ := lru.New2Q(8192)
|
||||
|
||||
return &blockReceiptCache{
|
||||
blocks: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (brc *blockReceiptCache) add(bcid cid.Cid) int {
|
||||
val, ok := brc.blocks.Get(bcid)
|
||||
if !ok {
|
||||
brc.blocks.Add(bcid, int(1))
|
||||
return 0
|
||||
}
|
||||
|
||||
brc.blocks.Add(bcid, val.(int)+1)
|
||||
return val.(int)
|
||||
}
|
||||
|
||||
func HandleIncomingMessages(ctx context.Context, mpool *messagepool.MessagePool, msub *pubsub.Subscription) {
|
||||
for {
|
||||
msg, err := msub.Next(ctx)
|
||||
@ -85,9 +165,9 @@ func HandleIncomingMessages(ctx context.Context, mpool *messagepool.MessagePool,
|
||||
continue
|
||||
}
|
||||
|
||||
m, err := types.DecodeSignedMessage(msg.GetData())
|
||||
if err != nil {
|
||||
log.Errorf("got incorrectly formatted Message: %s", err)
|
||||
m, ok := msg.ValidatorData.(*types.SignedMessage)
|
||||
if !ok {
|
||||
log.Errorf("message validator func passed on wrong type: %#v", msg.ValidatorData)
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -121,6 +121,10 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) bool {
|
||||
}
|
||||
|
||||
for _, b := range fts.Blocks {
|
||||
if reason, ok := syncer.bad.Has(b.Cid()); ok {
|
||||
log.Warnf("InformNewHead called on block marked as bad: %s (reason: %s)", b.Cid(), reason)
|
||||
return false
|
||||
}
|
||||
if err := syncer.ValidateMsgMeta(b); err != nil {
|
||||
log.Warnf("invalid block received: %s", err)
|
||||
return false
|
||||
@ -450,7 +454,7 @@ func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet)
|
||||
for _, b := range fts.Blocks {
|
||||
if err := syncer.ValidateBlock(ctx, b); err != nil {
|
||||
if isPermanent(err) {
|
||||
syncer.bad.Add(b.Cid())
|
||||
syncer.bad.Add(b.Cid(), err.Error())
|
||||
}
|
||||
return xerrors.Errorf("validating block %s: %w", b.Cid(), err)
|
||||
}
|
||||
@ -870,11 +874,11 @@ func (syncer *Syncer) collectHeaders(ctx context.Context, from *types.TipSet, to
|
||||
)
|
||||
|
||||
for _, pcid := range from.Parents().Cids() {
|
||||
if syncer.bad.Has(pcid) {
|
||||
if reason, ok := syncer.bad.Has(pcid); ok {
|
||||
for _, b := range from.Cids() {
|
||||
syncer.bad.Add(b)
|
||||
syncer.bad.Add(b, fmt.Sprintf("linked to %s", pcid))
|
||||
}
|
||||
return nil, xerrors.Errorf("chain linked to block marked previously as bad (%s, %s)", from.Cids(), pcid)
|
||||
return nil, xerrors.Errorf("chain linked to block marked previously as bad (%s, %s) (reason: %s)", from.Cids(), pcid, reason)
|
||||
}
|
||||
}
|
||||
|
||||
@ -892,12 +896,12 @@ func (syncer *Syncer) collectHeaders(ctx context.Context, from *types.TipSet, to
|
||||
loop:
|
||||
for blockSet[len(blockSet)-1].Height() > untilHeight {
|
||||
for _, bc := range at.Cids() {
|
||||
if syncer.bad.Has(bc) {
|
||||
if reason, ok := syncer.bad.Has(bc); ok {
|
||||
for _, b := range acceptedBlocks {
|
||||
syncer.bad.Add(b)
|
||||
syncer.bad.Add(b, fmt.Sprintf("chain contained %s", bc))
|
||||
}
|
||||
|
||||
return nil, xerrors.Errorf("chain contained block marked previously as bad (%s, %s)", from.Cids(), bc)
|
||||
return nil, xerrors.Errorf("chain contained block marked previously as bad (%s, %s) (reason: %s)", from.Cids(), bc, reason)
|
||||
}
|
||||
}
|
||||
|
||||
@ -940,12 +944,12 @@ loop:
|
||||
break loop
|
||||
}
|
||||
for _, bc := range b.Cids() {
|
||||
if syncer.bad.Has(bc) {
|
||||
if reason, ok := syncer.bad.Has(bc); ok {
|
||||
for _, b := range acceptedBlocks {
|
||||
syncer.bad.Add(b)
|
||||
syncer.bad.Add(b, fmt.Sprintf("chain contained %s", bc))
|
||||
}
|
||||
|
||||
return nil, xerrors.Errorf("chain contained block marked previously as bad (%s, %s)", from.Cids(), bc)
|
||||
return nil, xerrors.Errorf("chain contained block marked previously as bad (%s, %s) (reason: %s)", from.Cids(), bc, reason)
|
||||
}
|
||||
}
|
||||
blockSet = append(blockSet, b)
|
||||
@ -972,7 +976,7 @@ loop:
|
||||
// TODO: we're marking this block bad in the same way that we mark invalid blocks bad. Maybe distinguish?
|
||||
log.Warn("adding forked chain to our bad tipset cache")
|
||||
for _, b := range from.Blocks() {
|
||||
syncer.bad.Add(b.Cid())
|
||||
syncer.bad.Add(b.Cid(), "fork past finality")
|
||||
}
|
||||
}
|
||||
return nil, xerrors.Errorf("failed to sync fork: %w", err)
|
||||
@ -1189,5 +1193,9 @@ func (syncer *Syncer) State() []SyncerState {
|
||||
}
|
||||
|
||||
func (syncer *Syncer) MarkBad(blk cid.Cid) {
|
||||
syncer.bad.Add(blk)
|
||||
syncer.bad.Add(blk, "manually marked bad")
|
||||
}
|
||||
|
||||
func (syncer *Syncer) CheckBadBlockCache(blk cid.Cid) (string, bool) {
|
||||
return syncer.bad.Has(blk)
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"math/big"
|
||||
|
||||
"github.com/filecoin-project/go-sectorbuilder"
|
||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||
|
||||
@ -207,7 +206,11 @@ func IsTicketWinner(partialTicket []byte, ssizeI abi.SectorSize, snum uint64, to
|
||||
}
|
||||
|
||||
func ElectionPostChallengeCount(sectors uint64, faults uint64) uint64 {
|
||||
return sectorbuilder.ElectionPostChallengeCount(sectors, faults)
|
||||
if sectors-faults == 0 {
|
||||
return 0
|
||||
}
|
||||
// ceil(sectors / SectorChallengeRatioDiv)
|
||||
return (sectors-faults-1)/build.SectorChallengeRatioDiv + 1
|
||||
}
|
||||
|
||||
func (t *Ticket) Equals(ot *Ticket) bool {
|
||||
|
@ -130,6 +130,9 @@ func (ts *TipSet) Cids() []cid.Cid {
|
||||
}
|
||||
|
||||
func (ts *TipSet) Key() TipSetKey {
|
||||
if ts == nil {
|
||||
return EmptyTSK
|
||||
}
|
||||
return NewTipSetKey(ts.cids...)
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,8 @@ import (
|
||||
"github.com/multiformats/go-multihash"
|
||||
)
|
||||
|
||||
var EmptyTSK = TipSetKey{}
|
||||
|
||||
// The length of a block header CID in bytes.
|
||||
var blockHeaderCIDLen int
|
||||
|
||||
@ -90,6 +92,10 @@ func (k *TipSetKey) UnmarshalJSON(b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k TipSetKey) IsEmpty() bool {
|
||||
return len(k.value) == 0
|
||||
}
|
||||
|
||||
func encodeKey(cids []cid.Cid) []byte {
|
||||
buffer := new(bytes.Buffer)
|
||||
for _, c := range cids {
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||
)
|
||||
|
||||
func TestMessageFactory(t *testing.T) {
|
||||
|
@ -7,6 +7,8 @@ import (
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||
)
|
||||
|
||||
const HalvingPeriodEpochs = 6 * 365 * 24 * 60 * 2
|
||||
|
12
cli/chain.go
12
cli/chain.go
@ -255,7 +255,7 @@ var chainSetHeadCmd = &cli.Command{
|
||||
ts, err = api.ChainGetGenesis(ctx)
|
||||
}
|
||||
if ts == nil && cctx.IsSet("epoch") {
|
||||
ts, err = api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(cctx.Uint64("epoch")), nil)
|
||||
ts, err = api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(cctx.Uint64("epoch")), types.EmptyTSK)
|
||||
}
|
||||
if ts == nil {
|
||||
ts, err = parseTipSet(api, ctx, cctx.Args().Slice())
|
||||
@ -268,7 +268,7 @@ var chainSetHeadCmd = &cli.Command{
|
||||
return fmt.Errorf("must pass cids for tipset to set as head")
|
||||
}
|
||||
|
||||
if err := api.ChainSetHead(ctx, ts); err != nil {
|
||||
if err := api.ChainSetHead(ctx, ts.Key()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -318,7 +318,7 @@ var chainListCmd = &cli.Command{
|
||||
var head *types.TipSet
|
||||
|
||||
if cctx.IsSet("height") {
|
||||
head, err = api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(cctx.Uint64("height")), nil)
|
||||
head, err = api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(cctx.Uint64("height")), types.EmptyTSK)
|
||||
} else {
|
||||
head, err = api.ChainHead(ctx)
|
||||
}
|
||||
@ -451,7 +451,7 @@ var chainBisectCmd = &cli.Command{
|
||||
|
||||
subPath := cctx.Args().Get(2)
|
||||
|
||||
highest, err := api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(end), nil)
|
||||
highest, err := api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(end), types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -465,7 +465,7 @@ var chainBisectCmd = &cli.Command{
|
||||
start = end
|
||||
}
|
||||
|
||||
midTs, err := api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(mid), highest)
|
||||
midTs, err := api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(mid), highest.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -547,7 +547,7 @@ var chainExportCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
stream, err := api.ChainExport(ctx, ts)
|
||||
stream, err := api.ChainExport(ctx, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -291,7 +291,7 @@ var clientQueryAskCmd = &cli.Command{
|
||||
}
|
||||
pid = p
|
||||
} else {
|
||||
p, err := api.StateMinerPeerID(ctx, maddr, nil)
|
||||
p, err := api.StateMinerPeerID(ctx, maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get peerID for miner: %w", err)
|
||||
}
|
||||
|
@ -210,4 +210,5 @@ var Commands = []*cli.Command{
|
||||
syncCmd,
|
||||
versionCmd,
|
||||
walletCmd,
|
||||
logCmd,
|
||||
}
|
||||
|
101
cli/log.go
Normal file
101
cli/log.go
Normal file
@ -0,0 +1,101 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
)
|
||||
|
||||
var logCmd = &cli.Command{
|
||||
Name: "log",
|
||||
Usage: "Manage logging",
|
||||
Subcommands: []*cli.Command{
|
||||
logList,
|
||||
logSetLevel,
|
||||
},
|
||||
}
|
||||
|
||||
var logList = &cli.Command{
|
||||
Name: "list",
|
||||
Usage: "List log systems",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
systems, err := api.LogList(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, system := range systems {
|
||||
fmt.Println(system)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var logSetLevel = &cli.Command{
|
||||
Name: "set-level",
|
||||
Usage: "Set log level",
|
||||
ArgsUsage: "<level>",
|
||||
Description: `Set the log level for logging systems:
|
||||
|
||||
The system flag can be specified multiple times.
|
||||
|
||||
eg) log set-level --system chain --system blocksync debug
|
||||
|
||||
Available Levels:
|
||||
debug
|
||||
info
|
||||
warn
|
||||
error
|
||||
|
||||
Environment Variables:
|
||||
GOLOG_LOG_LEVEL - Default log level for all log systems
|
||||
GOLOG_LOG_FMT - Change output log format (json, nocolor)
|
||||
GOLOG_FILE - Write logs to file in addition to stderr
|
||||
`,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringSliceFlag{
|
||||
Name: "system",
|
||||
Usage: "limit to log system",
|
||||
Value: &cli.StringSlice{},
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
if !cctx.Args().Present() {
|
||||
return fmt.Errorf("level is required")
|
||||
}
|
||||
|
||||
systems := cctx.StringSlice("system")
|
||||
if len(systems) == 0 {
|
||||
var err error
|
||||
systems, err = api.LogList(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, system := range systems {
|
||||
if err := api.LogSetLevel(ctx, system, cctx.Args().First()); err != nil {
|
||||
return xerrors.Errorf("setting log level on %s: %w", system, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
@ -33,7 +33,7 @@ var mpoolPending = &cli.Command{
|
||||
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msgs, err := api.MpoolPending(ctx, nil)
|
||||
msgs, err := api.MpoolPending(ctx, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -103,7 +103,7 @@ var mpoolStat = &cli.Command{
|
||||
return xerrors.Errorf("getting chain head: %w", err)
|
||||
}
|
||||
|
||||
msgs, err := api.MpoolPending(ctx, nil)
|
||||
msgs, err := api.MpoolPending(ctx, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -122,7 +122,7 @@ var mpoolStat = &cli.Command{
|
||||
bkt.msgs[v.Message.Nonce] = v
|
||||
}
|
||||
for a, bkt := range buckets {
|
||||
act, err := api.StateGetActor(ctx, a, ts)
|
||||
act, err := api.StateGetActor(ctx, a, ts.Key())
|
||||
if err != nil {
|
||||
fmt.Printf("%s, err: %s\n", a, err)
|
||||
continue
|
||||
|
@ -177,7 +177,7 @@ var msigInspectCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
act, err := api.StateGetActor(ctx, maddr, nil)
|
||||
act, err := api.StateGetActor(ctx, maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
36
cli/net.go
36
cli/net.go
@ -2,6 +2,7 @@ package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@ -18,6 +19,7 @@ var netCmd = &cli.Command{
|
||||
netConnect,
|
||||
netListen,
|
||||
netId,
|
||||
netFindPeer,
|
||||
},
|
||||
}
|
||||
|
||||
@ -123,3 +125,37 @@ var netId = &cli.Command{
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var netFindPeer = &cli.Command{
|
||||
Name: "findpeer",
|
||||
Usage: "Find the addresses of a given peerID",
|
||||
ArgsUsage: "<peer ID>",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if cctx.NArg() != 1 {
|
||||
fmt.Println("Usage: findpeer [peer ID]")
|
||||
return nil
|
||||
}
|
||||
|
||||
pid, err := peer.IDB58Decode(cctx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
api, closer, err := GetAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
addrs, err := api.NetFindPeer(ctx, pid)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(addrs)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
139
cli/state.go
139
cli/state.go
@ -21,6 +21,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/miner"
|
||||
|
||||
"github.com/docker/go-units"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
@ -51,6 +52,68 @@ var stateCmd = &cli.Command{
|
||||
stateComputeStateCmd,
|
||||
stateCallCmd,
|
||||
stateGetDealSetCmd,
|
||||
stateWaitMsgCmd,
|
||||
stateMinerInfo,
|
||||
},
|
||||
}
|
||||
|
||||
var stateMinerInfo = &cli.Command{
|
||||
Name: "miner-info",
|
||||
Usage: "Retrieve miner information",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
if !cctx.Args().Present() {
|
||||
return fmt.Errorf("must specify miner to get information for")
|
||||
}
|
||||
|
||||
addr, err := address.NewFromString(cctx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ts, err := loadTipSet(ctx, cctx, api)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
act, err := api.StateGetActor(ctx, addr, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
aso, err := api.ChainReadObj(ctx, act.Head)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var mst actors.StorageMinerActorState
|
||||
if err := mst.UnmarshalCBOR(bytes.NewReader(aso)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mio, err := api.ChainReadObj(ctx, mst.Info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var mi actors.MinerInfo
|
||||
if err := mi.UnmarshalCBOR(bytes.NewReader(mio)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Owner:\t%s\n", mi.Owner)
|
||||
fmt.Printf("Worker:\t%s\n", mi.Worker)
|
||||
fmt.Printf("PeerID:\t%s\n", mi.PeerID)
|
||||
fmt.Printf("SectorSize:\t%s (%d)\n", units.BytesSize(float64(mi.SectorSize)), mi.SectorSize)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
@ -118,7 +181,7 @@ var statePowerCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
power, err := api.StateMinerPower(ctx, maddr, ts)
|
||||
power, err := api.StateMinerPower(ctx, maddr, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -162,7 +225,7 @@ var stateSectorsCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
sectors, err := api.StateMinerSectors(ctx, maddr, ts)
|
||||
sectors, err := api.StateMinerSectors(ctx, maddr, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -201,7 +264,7 @@ var stateProvingSetCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
sectors, err := api.StateMinerProvingSet(ctx, maddr, ts)
|
||||
sectors, err := api.StateMinerProvingSet(ctx, maddr, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -276,7 +339,7 @@ var stateReplaySetCmd = &cli.Command{
|
||||
|
||||
}
|
||||
|
||||
res, err := api.StateReplay(ctx, ts, mcid)
|
||||
res, err := api.StateReplay(ctx, ts.Key(), mcid)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("replay call failed: %w", err)
|
||||
}
|
||||
@ -310,7 +373,7 @@ var statePledgeCollateralCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
coll, err := api.StatePledgeCollateral(ctx, ts)
|
||||
coll, err := api.StatePledgeCollateral(ctx, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -346,7 +409,7 @@ var stateGetDealSetCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
deal, err := api.StateMarketStorageDeal(ctx, abi.DealID(dealid), ts)
|
||||
deal, err := api.StateMarketStorageDeal(ctx, abi.DealID(dealid), ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -378,7 +441,7 @@ var stateListMinersCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
miners, err := api.StateListMiners(ctx, ts)
|
||||
miners, err := api.StateListMiners(ctx, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -408,7 +471,7 @@ var stateListActorsCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
actors, err := api.StateListActors(ctx, ts)
|
||||
actors, err := api.StateListActors(ctx, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -447,7 +510,7 @@ var stateGetActorCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
a, err := api.StateGetActor(ctx, addr, ts)
|
||||
a, err := api.StateGetActor(ctx, addr, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -488,7 +551,7 @@ var stateLookupIDCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
a, err := api.StateLookupID(ctx, addr, ts)
|
||||
a, err := api.StateLookupID(ctx, addr, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -525,7 +588,7 @@ var stateSectorSizeCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
ssize, err := api.StateMinerSectorSize(ctx, addr, ts)
|
||||
ssize, err := api.StateMinerSectorSize(ctx, addr, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -561,12 +624,12 @@ var stateReadStateCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
act, err := api.StateGetActor(ctx, addr, ts)
|
||||
act, err := api.StateGetActor(ctx, addr, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
as, err := api.StateReadState(ctx, act, ts)
|
||||
as, err := api.StateReadState(ctx, act, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -635,7 +698,7 @@ var stateListMessagesCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
msgs, err := api.StateListMessages(ctx, &types.Message{To: toa, From: froma}, ts, abi.ChainEpoch(toh))
|
||||
msgs, err := api.StateListMessages(ctx, &types.Message{To: toa, From: froma}, ts.Key(), abi.ChainEpoch(toh))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -702,7 +765,7 @@ var stateComputeStateCmd = &cli.Command{
|
||||
|
||||
var msgs []*types.Message
|
||||
if cctx.Bool("apply-mpool-messages") {
|
||||
pmsgs, err := api.MpoolPending(ctx, ts)
|
||||
pmsgs, err := api.MpoolPending(ctx, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -717,7 +780,7 @@ var stateComputeStateCmd = &cli.Command{
|
||||
}
|
||||
}
|
||||
|
||||
nstate, err := api.StateCompute(ctx, h, msgs, ts)
|
||||
nstate, err := api.StateCompute(ctx, h, msgs, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -727,6 +790,46 @@ var stateComputeStateCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateWaitMsgCmd = &cli.Command{
|
||||
Name: "wait-msg",
|
||||
Usage: "Wait for a message to appear on chain",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "timeout",
|
||||
Value: "10m",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if !cctx.Args().Present() {
|
||||
return fmt.Errorf("must specify message cid to wait for")
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msg, err := cid.Decode(cctx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mw, err := api.StateWaitMsg(ctx, msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("message was executed in tipset: %s", mw.TipSet.Cids())
|
||||
fmt.Printf("Exit Code: %d", mw.Receipt.ExitCode)
|
||||
fmt.Printf("Gas Used: %s", mw.Receipt.GasUsed)
|
||||
fmt.Printf("Return: %x", mw.Receipt.Return)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var stateCallCmd = &cli.Command{
|
||||
Name: "call",
|
||||
Usage: "Invoke a method on an actor locally",
|
||||
@ -785,7 +888,7 @@ var stateCallCmd = &cli.Command{
|
||||
return fmt.Errorf("failed to parse 'value': %s", err)
|
||||
}
|
||||
|
||||
act, err := api.StateGetActor(ctx, toa, ts)
|
||||
act, err := api.StateGetActor(ctx, toa, ts.Key())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to lookup target actor: %s", err)
|
||||
}
|
||||
@ -803,7 +906,7 @@ var stateCallCmd = &cli.Command{
|
||||
GasPrice: types.NewInt(0),
|
||||
Method: abi.MethodNum(method),
|
||||
Params: params,
|
||||
}, ts)
|
||||
}, ts.Key())
|
||||
if err != nil {
|
||||
return fmt.Errorf("state call failed: %s", err)
|
||||
}
|
||||
|
36
cli/sync.go
36
cli/sync.go
@ -21,6 +21,7 @@ var syncCmd = &cli.Command{
|
||||
syncStatusCmd,
|
||||
syncWaitCmd,
|
||||
syncMarkBadCmd,
|
||||
syncCheckBadCmd,
|
||||
},
|
||||
}
|
||||
|
||||
@ -116,6 +117,41 @@ var syncMarkBadCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var syncCheckBadCmd = &cli.Command{
|
||||
Name: "check-bad",
|
||||
Usage: "check if the given block was marked bad, and for what reason",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
napi, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
if !cctx.Args().Present() {
|
||||
return fmt.Errorf("must specify block cid to check")
|
||||
}
|
||||
|
||||
bcid, err := cid.Decode(cctx.Args().First())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to decode input as a cid: %s", err)
|
||||
}
|
||||
|
||||
reason, err := napi.SyncCheckBad(ctx, bcid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if reason == "" {
|
||||
fmt.Println("block was not marked as bad")
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println(reason)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func SyncWait(ctx context.Context, napi api.FullNode) error {
|
||||
for {
|
||||
state, err := napi.SyncState(ctx)
|
||||
|
@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
@ -59,6 +60,10 @@ var runCmd = &cli.Command{
|
||||
Name: "front",
|
||||
Value: "127.0.0.1:8418",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "max-batch",
|
||||
Value: 1000,
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||
@ -75,13 +80,15 @@ var runCmd = &cli.Command{
|
||||
|
||||
log.Info("Remote version: %s", v.Version)
|
||||
|
||||
maxBatch := cctx.Int("max-batch")
|
||||
|
||||
st, err := openStorage(cctx.String("db"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer st.close()
|
||||
|
||||
runSyncer(ctx, api, st)
|
||||
runSyncer(ctx, api, st, maxBatch)
|
||||
|
||||
h, err := newHandler(api, st)
|
||||
if err != nil {
|
||||
|
@ -20,9 +20,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
const maxBatch = 3000
|
||||
|
||||
func runSyncer(ctx context.Context, api api.FullNode, st *storage) {
|
||||
func runSyncer(ctx context.Context, api api.FullNode, st *storage, maxBatch int) {
|
||||
notifs, err := api.ChainNotify(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -34,7 +32,7 @@ func runSyncer(ctx context.Context, api api.FullNode, st *storage) {
|
||||
case store.HCCurrent:
|
||||
fallthrough
|
||||
case store.HCApply:
|
||||
syncHead(ctx, api, st, change.Val)
|
||||
syncHead(ctx, api, st, change.Val, maxBatch)
|
||||
case store.HCRevert:
|
||||
log.Warnf("revert todo")
|
||||
}
|
||||
@ -67,9 +65,7 @@ type actorInfo struct {
|
||||
state string
|
||||
}
|
||||
|
||||
func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipSet) {
|
||||
addresses := map[address.Address]address.Address{}
|
||||
actors := map[address.Address]map[types.Actor]actorInfo{}
|
||||
func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipSet, maxBatch int) {
|
||||
var alk sync.Mutex
|
||||
|
||||
log.Infof("Getting synced block list")
|
||||
@ -94,7 +90,6 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
|
||||
}
|
||||
|
||||
allToSync[bh.Cid()] = bh
|
||||
addresses[bh.Miner] = address.Undef
|
||||
|
||||
if len(allToSync)%500 == 10 {
|
||||
log.Infof("todo: (%d) %s @%d", len(allToSync), bh.Cid(), bh.Height)
|
||||
@ -116,7 +111,9 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
|
||||
}
|
||||
|
||||
for len(allToSync) > 0 {
|
||||
minH := abi.ChainEpoch(math.MaxInt64)
|
||||
actors := map[address.Address]map[types.Actor]actorInfo{}
|
||||
addresses := map[address.Address]address.Address{}
|
||||
minH := abi.ChainEpoch(math.MaxUint64)
|
||||
|
||||
for _, header := range allToSync {
|
||||
if header.Height < minH {
|
||||
@ -126,8 +123,9 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
|
||||
|
||||
toSync := map[cid.Cid]*types.BlockHeader{}
|
||||
for c, header := range allToSync {
|
||||
if header.Height < minH+maxBatch {
|
||||
if header.Height < minH+uint64(maxBatch) {
|
||||
toSync[c] = header
|
||||
addresses[header.Miner] = address.Undef
|
||||
}
|
||||
}
|
||||
for c := range toSync {
|
||||
@ -145,19 +143,19 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
|
||||
|
||||
if len(bh.Parents) == 0 { // genesis case
|
||||
ts, err := types.NewTipSet([]*types.BlockHeader{bh})
|
||||
aadrs, err := api.StateListActors(ctx, ts)
|
||||
aadrs, err := api.StateListActors(ctx, ts.Key())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
par(50, aadrs, func(addr address.Address) {
|
||||
act, err := api.StateGetActor(ctx, addr, ts)
|
||||
act, err := api.StateGetActor(ctx, addr, ts.Key())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
ast, err := api.StateReadState(ctx, act, ts)
|
||||
ast, err := api.StateReadState(ctx, act, ts.Key())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
@ -202,7 +200,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
ast, err := api.StateReadState(ctx, &act, ts)
|
||||
ast, err := api.StateReadState(ctx, &act, pts.Key())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
@ -239,7 +237,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
|
||||
}
|
||||
|
||||
par(50, kmaparr(addresses), func(addr address.Address) {
|
||||
raddr, err := api.StateLookupID(ctx, addr, nil)
|
||||
raddr, err := api.StateLookupID(ctx, addr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
log.Warn(err)
|
||||
return
|
||||
@ -270,7 +268,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
|
||||
par(50, kvmaparr(miners), func(it func() (minerKey, *minerInfo)) {
|
||||
k, info := it()
|
||||
|
||||
sszs, err := api.StateMinerSectorCount(ctx, k.addr, nil)
|
||||
sszs, err := api.StateMinerSectorCount(ctx, k.addr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
@ -359,7 +357,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
|
||||
log.Infof("Get deals")
|
||||
|
||||
// TODO: incremental, gather expired
|
||||
deals, err := api.StateMarketDeals(ctx, ts)
|
||||
deals, err := api.StateMarketDeals(ctx, ts.Key())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
|
@ -208,7 +208,8 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if owner.Protocol() != address.BLS {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte("Miner address must use BLS"))
|
||||
w.Write([]byte("Miner address must use BLS. A BLS address starts with the prefix 't3'."))
|
||||
w.Write([]byte("Please create a BLS address by running \"lotus wallet new bls\" while connected to a Lotus node."))
|
||||
return
|
||||
}
|
||||
|
||||
@ -239,7 +240,7 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
collateral, err := h.api.StatePledgeCollateral(r.Context(), nil)
|
||||
collateral, err := h.api.StatePledgeCollateral(r.Context(), types.EmptyTSK)
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte(err.Error()))
|
||||
|
@ -3,7 +3,7 @@ package main
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/coreos/go-systemd/dbus"
|
||||
"github.com/coreos/go-systemd/v22/dbus"
|
||||
)
|
||||
|
||||
func notifyHandler(n string, ch chan interface{}, sCh chan os.Signal) (string, error) {
|
||||
|
@ -11,6 +11,9 @@ import (
|
||||
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
)
|
||||
|
@ -38,14 +38,14 @@ var infoCmd = &cli.Command{
|
||||
fmt.Printf("Miner: %s\n", maddr)
|
||||
|
||||
// Sector size
|
||||
sizeByte, err := api.StateMinerSectorSize(ctx, maddr, nil)
|
||||
sizeByte, err := api.StateMinerSectorSize(ctx, maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Sector Size: %s\n", types.SizeStr(types.NewInt(uint64(sizeByte))))
|
||||
|
||||
pow, err := api.StateMinerPower(ctx, maddr, nil)
|
||||
pow, err := api.StateMinerPower(ctx, maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -53,11 +53,11 @@ var infoCmd = &cli.Command{
|
||||
percI := types.BigDiv(types.BigMul(pow.MinerPower, types.NewInt(1000000)), pow.TotalPower)
|
||||
fmt.Printf("Power: %s / %s (%0.4f%%)\n", types.SizeStr(pow.MinerPower), types.SizeStr(pow.TotalPower), float64(percI.Int64())/10000)
|
||||
|
||||
secCounts, err := api.StateMinerSectorCount(ctx, maddr, nil)
|
||||
secCounts, err := api.StateMinerSectorCount(ctx, maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
faults, err := api.StateMinerFaults(ctx, maddr, nil)
|
||||
faults, err := api.StateMinerFaults(ctx, maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -88,7 +88,7 @@ var infoCmd = &cli.Command{
|
||||
fmt.Printf("\tCommit: %d\n", wstat.CommitWait)
|
||||
fmt.Printf("\tUnseal: %d\n", wstat.UnsealWait)
|
||||
|
||||
ps, err := api.StateMinerPostState(ctx, maddr, nil)
|
||||
ps, err := api.StateMinerPostState(ctx, maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import (
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
"github.com/filecoin-project/lotus/genesis"
|
||||
"github.com/filecoin-project/lotus/miner"
|
||||
"github.com/filecoin-project/lotus/node/config"
|
||||
"github.com/filecoin-project/lotus/node/modules"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
"github.com/filecoin-project/lotus/node/repo"
|
||||
@ -78,6 +79,10 @@ var initCmd = &cli.Command{
|
||||
Name: "pre-sealed-sectors",
|
||||
Usage: "specify set of presealed sectors for starting as a genesis miner",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "pre-sealed-metadata",
|
||||
Usage: "specify the metadata file for the presealed sectors",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "nosync",
|
||||
Usage: "don't check full-node sync status",
|
||||
@ -221,13 +226,13 @@ var initCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
func migratePreSealMeta(ctx context.Context, api lapi.FullNode, presealDir string, maddr address.Address, mds dtypes.MetadataDS) error {
|
||||
presealDir, err := homedir.Expand(presealDir)
|
||||
func migratePreSealMeta(ctx context.Context, api lapi.FullNode, metadata string, maddr address.Address, mds dtypes.MetadataDS) error {
|
||||
metadata, err := homedir.Expand(metadata)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("expanding preseal dir: %w", err)
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadFile(filepath.Join(presealDir, "pre-seal-"+maddr.String()+".json"))
|
||||
b, err := ioutil.ReadFile(metadata)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("reading preseal metadata: %w", err)
|
||||
}
|
||||
@ -307,7 +312,7 @@ func findMarketDealID(ctx context.Context, api lapi.FullNode, deal actors.Storag
|
||||
// TODO: find a better way
|
||||
// (this is only used by genesis miners)
|
||||
|
||||
deals, err := api.StateMarketDeals(ctx, nil)
|
||||
deals, err := api.StateMarketDeals(ctx, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return 0, xerrors.Errorf("getting market deals: %w", err)
|
||||
}
|
||||
@ -358,7 +363,22 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode,
|
||||
return err
|
||||
}
|
||||
|
||||
sbcfg, err := modules.SectorBuilderConfig(sectorbuilder.SimplePath(lr.Path()), 2, false, false)(mds, api)
|
||||
c, err := lr.Config()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg, ok := c.(*config.StorageMiner)
|
||||
if !ok {
|
||||
return xerrors.Errorf("invalid config from repo, got: %T", c)
|
||||
}
|
||||
|
||||
scfg := sectorbuilder.SimplePath(lr.Path())
|
||||
if len(cfg.SectorBuilder.Storage) > 0 {
|
||||
scfg = cfg.SectorBuilder.Storage
|
||||
}
|
||||
|
||||
sbcfg, err := modules.SectorBuilderConfig(scfg, 2, false, false)(mds, api)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting genesis miner sector builder config: %w", err)
|
||||
}
|
||||
@ -385,20 +405,20 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode,
|
||||
}
|
||||
}
|
||||
|
||||
if pssb := cctx.String("pre-sealed-sectors"); pssb != "" {
|
||||
pssb, err := homedir.Expand(pssb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Infof("Importing pre-sealed sector metadata for %s", a)
|
||||
|
||||
if err := migratePreSealMeta(ctx, api, pssb, a, mds); err != nil {
|
||||
return xerrors.Errorf("migrating presealed sector metadata: %w", err)
|
||||
}
|
||||
if pssb := cctx.String("pre-sealed-metadata"); pssb != "" {
|
||||
pssb, err := homedir.Expand(pssb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
log.Infof("Importing pre-sealed sector metadata for %s", a)
|
||||
|
||||
if err := migratePreSealMeta(ctx, api, pssb, a, mds); err != nil {
|
||||
return xerrors.Errorf("migrating presealed sector metadata: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := configureStorageMiner(ctx, api, a, peerid); err != nil {
|
||||
@ -450,7 +470,7 @@ func makeHostKey(lr repo.LockedRepo) (crypto.PrivKey, error) {
|
||||
}
|
||||
|
||||
func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address.Address, peerid peer.ID) error {
|
||||
waddr, err := api.StateMinerWorker(ctx, addr, nil)
|
||||
waddr, err := api.StateMinerWorker(ctx, addr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getWorkerAddr returned bad address: %w", err)
|
||||
}
|
||||
@ -514,7 +534,7 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID,
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
collateral, err := api.StatePledgeCollateral(ctx, nil)
|
||||
collateral, err := api.StatePledgeCollateral(ctx, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
@ -130,7 +131,7 @@ var sectorsListCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
pset, err := fullApi.StateMinerProvingSet(ctx, maddr, nil)
|
||||
pset, err := fullApi.StateMinerProvingSet(ctx, maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -139,7 +140,7 @@ var sectorsListCmd = &cli.Command{
|
||||
provingIDs[info.ID] = struct{}{}
|
||||
}
|
||||
|
||||
sset, err := fullApi.StateMinerSectors(ctx, maddr, nil)
|
||||
sset, err := fullApi.StateMinerSectors(ctx, maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -16,7 +16,10 @@ import (
|
||||
paramfetch "github.com/filecoin-project/go-paramfetch"
|
||||
"github.com/filecoin-project/go-sectorbuilder"
|
||||
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
@ -95,7 +98,15 @@ var DaemonCmd = &cli.Command{
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
log.Infof("lotus repo: %s", cctx.String("repo"))
|
||||
{
|
||||
dir, err := homedir.Expand(cctx.String("repo"))
|
||||
if err != nil {
|
||||
log.Warnw("could not expand repo location", "error", err)
|
||||
} else {
|
||||
log.Infof("lotus repo: %s", dir)
|
||||
}
|
||||
}
|
||||
|
||||
r, err := repo.NewFS(cctx.String("repo"))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("opening fs repo: %w", err)
|
||||
@ -173,6 +184,17 @@ var DaemonCmd = &cli.Command{
|
||||
}
|
||||
}
|
||||
|
||||
// Add lotus version info to prometheus metrics
|
||||
var lotusInfoMetric = promauto.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "lotus_info",
|
||||
Help: "Lotus version information.",
|
||||
}, []string{"version"})
|
||||
|
||||
// Setting to 1 lets us multiply it with other stats to add the version labels
|
||||
lotusInfoMetric.With(prometheus.Labels{
|
||||
"version": build.UserVersion,
|
||||
}).Set(1)
|
||||
|
||||
endpoint, err := r.APIEndpoint()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting api endpoint: %w", err)
|
||||
|
@ -30,7 +30,7 @@ func init() {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pending, err := api.MpoolPending(ctx, head)
|
||||
pending, err := api.MpoolPending(ctx, head.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -47,7 +47,7 @@ func init() {
|
||||
addr, _ := address.NewIDAddress(1000)
|
||||
var ticket *types.Ticket
|
||||
{
|
||||
w, err := api.StateMinerWorker(ctx, addr, nil)
|
||||
w, err := api.StateMinerWorker(ctx, addr, head.Key())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("StateMinerWorker: %w", err)
|
||||
}
|
||||
@ -82,7 +82,7 @@ func init() {
|
||||
if err != nil {
|
||||
return xerrors.Errorf("chain get randomness: %w", err)
|
||||
}
|
||||
mworker, err := api.StateMinerWorker(ctx, addr, head)
|
||||
mworker, err := api.StateMinerWorker(ctx, addr, head.Key())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get miner worker: %w", err)
|
||||
}
|
||||
@ -96,7 +96,7 @@ func init() {
|
||||
|
||||
uts := head.MinTimestamp() + uint64(build.BlockDelay)
|
||||
nheight := head.Height() + 1
|
||||
blk, err := api.MinerCreateBlock(ctx, addr, head, ticket, epostp, msgs, nheight, uts)
|
||||
blk, err := api.MinerCreateBlock(ctx, addr, head.Key(), ticket, epostp, msgs, nheight, uts)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("creating block: %w", err)
|
||||
}
|
||||
|
@ -3,13 +3,14 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/filecoin-project/lotus/api/apistruct"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/filecoin-project/lotus/api/apistruct"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/lib/auth"
|
||||
"github.com/filecoin-project/lotus/lib/jsonrpc"
|
||||
@ -21,6 +22,8 @@ import (
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
manet "github.com/multiformats/go-multiaddr-net"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
|
||||
var log = logging.Logger("main")
|
||||
@ -43,6 +46,8 @@ func serveRPC(a api.FullNode, stop node.StopFunc, addr multiaddr.Multiaddr) erro
|
||||
|
||||
http.Handle("/rest/v0/import", importAH)
|
||||
|
||||
http.Handle("/metrics", promhttp.Handler())
|
||||
|
||||
lst, err := manet.Listen(addr)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("could not listen: %w", err)
|
||||
|
@ -160,6 +160,13 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "FAQs",
|
||||
"slug": "en+faqs",
|
||||
"github": "en/faqs.md",
|
||||
"value": null,
|
||||
"posts": []
|
||||
},
|
||||
{
|
||||
"title": "Glossary",
|
||||
"slug": "en+glossary",
|
||||
|
134
documentation/en/faqs.md
Normal file
134
documentation/en/faqs.md
Normal file
@ -0,0 +1,134 @@
|
||||
# Frequently Asked Questions
|
||||
|
||||
Here are some FAQs concerning the Lotus implementation and participation in
|
||||
Testnet.
|
||||
For questions concerning the broader Filecoin project, please
|
||||
go [here](https://filecoin.io/faqs/).
|
||||
|
||||
## Introduction to Lotus
|
||||
|
||||
### What is Lotus?
|
||||
|
||||
Lotus is an implementation of the **Filecoin Distributed Storage Network**, written in Go.
|
||||
It is designed to be modular and interoperable with any other implementation of the Filecoin Protocol.
|
||||
More information about Lotus can be found [here](https://lotu.sh/).
|
||||
|
||||
### What are the components of Lotus?
|
||||
|
||||
Lotus is composed of two separate pieces that can talk to each other:
|
||||
|
||||
The Lotus Node can sync the blockchain, validating all blocks, transfers, and deals
|
||||
along the way. It can also facilitate the creation of new storage deals. If you are not
|
||||
interested in providing your own storage to the network, and do not want to produce blocks
|
||||
yourself, then the Lotus Node is all you need!
|
||||
|
||||
The Lotus Storage Miner does everything you need for the registration of storage, and the
|
||||
production of new blocks. The Lotus Storage Miner communicates with the network
|
||||
by talking to a Lotus Node over the JSON-RPC API.
|
||||
|
||||
## Setting up a Lotus Node
|
||||
|
||||
### How do I set up a Lotus Node?
|
||||
|
||||
Follow the instructions found [here](https://docs.lotu.sh/en+getting-started).
|
||||
|
||||
### Where can I get the latest version of Lotus?
|
||||
|
||||
Download the binary tagged as the `Latest Release` from the
|
||||
[Lotus Github repo](https://github.com/filecoin-project/lotus/releases).
|
||||
|
||||
### What operating systems can Lotus run on?
|
||||
|
||||
Lotus can build and run on most Linux and MacOS systems with at least
|
||||
8GB of RAM. Windows is not yet supported.
|
||||
|
||||
### How can I update to the latest version of Lotus?
|
||||
|
||||
To update Lotus, follow the instructions [here](https://lotu.sh/en+updating-lotus).
|
||||
|
||||
### How do I prepare a fresh installation of Lotus?
|
||||
|
||||
Stop the Lotus daemon, and delete all related files, including sealed and chain data by
|
||||
running `rm ~/.lotus ~/.lotusstorage`.
|
||||
|
||||
Then, install Lotus afresh by following the instructions
|
||||
found [here](https://docs.lotu.sh/en+getting-started).
|
||||
|
||||
## Interacting with a Lotus Node
|
||||
|
||||
### How can I communicate with a Lotus Node?
|
||||
|
||||
Lotus Nodes have a command-line interface, as well as a JSON-RPC API.
|
||||
|
||||
### What are the commands I can send using the command-line interface?
|
||||
|
||||
The command-line interface is self-documenting, try running `lotus --help` from the `lotus` home
|
||||
directory for more.
|
||||
|
||||
### How can I send a request over the JSON-RPC API?
|
||||
|
||||
Information on how to send a `cURL` request to the JSON-RPC API can be found
|
||||
[here](https://lotu.sh/en+api). A JavaScript client is under development.
|
||||
|
||||
### What are the requests I can send over the JSON-RPC API?
|
||||
|
||||
Please have a look at the
|
||||
[source code](https://github.com/filecoin-project/lotus/blob/master/api/api_common.go)
|
||||
for a list of methods supported by the JSON-RPC API.
|
||||
## The Test Network
|
||||
|
||||
### What is Testnet?
|
||||
|
||||
Testnet is a live network of Lotus Nodes run by the
|
||||
community for testing purposes.
|
||||
It has 2 PiB of storage (and growing!) dedicated to it.
|
||||
|
||||
### Is FIL on the Testnet worth anything?
|
||||
|
||||
Nothing at all! Real-world incentives may be provided in a future phase of Testnet, but this is
|
||||
yet to be confirmed.
|
||||
|
||||
### Will there be future phases of Testnet?
|
||||
|
||||
Yes, there will be at least one more phase of Testnet. We plan on introducing interoperable
|
||||
[go-filecoin nodes](https://github.com/filecoin-project/go-filecoin#filecoin-go-filecoin)
|
||||
in a future phase.
|
||||
|
||||
### How can I see the status of Testnet?
|
||||
|
||||
The [dashboard](https://stats.testnet.filecoin.io/) displays the status of the network as
|
||||
well as a ton
|
||||
of other metrics you might find interesting.
|
||||
|
||||
## Mining with a Lotus Node on Testnet
|
||||
|
||||
### How do I get started mining with Lotus?
|
||||
|
||||
Follow the instructions found [here](https://lotu.sh/en+mining).
|
||||
|
||||
### What are the minimum hardware requirements?
|
||||
|
||||
An example test configuration, and minimum hardware requirements can be found
|
||||
[here](https://lotu.sh/en+hardware-mining).
|
||||
|
||||
Note that these might NOT be the minimum requirements for mining on Mainnet.
|
||||
|
||||
### What are some GPUs that have been tested?
|
||||
|
||||
A list of benchmarked GPUs can be found [here](https://lotu.sh/en+hardware-mining#benchmarked-gpus-7393).
|
||||
|
||||
## Advanced questions
|
||||
|
||||
### Is there a Docker image for lotus?
|
||||
|
||||
Community-contributed Docker and Docker Compose examples are available
|
||||
[here](https://github.com/filecoin-project/lotus/tree/master/tools/dockers/docker-examples).
|
||||
|
||||
### How can I run two miners on the same machine?
|
||||
|
||||
You can do so by changing the storage path variable for the second miner, e.g.,
|
||||
`LOTUS_STORAGE_PATH=~/.lotusstorage2`. You will also need to make sure that no ports collide.
|
||||
|
||||
### How do I setup my own local devnet?
|
||||
|
||||
Follow the instructions found [here](https://lotu.sh/en+setup-local-dev-net).
|
@ -36,7 +36,7 @@ In order to connect to the network, you need to be connected to at least 1 peer.
|
||||
|
||||
## Chain sync
|
||||
|
||||
While the daemon is running, the next requirement is to sync the chain. Run the command below to start the chain sync progress. To see current chain height, visit the [network stats page](http://stats.testnet.filecoin.io/).
|
||||
While the daemon is running, the next requirement is to sync the chain. Run the command below to start the chain sync progress. To see current chain height, visit the [network stats page](https://stats.testnet.filecoin.io/).
|
||||
|
||||
```sh
|
||||
lotus sync wait
|
||||
@ -50,9 +50,11 @@ lotus sync wait
|
||||
Initialize a new wallet:
|
||||
|
||||
```sh
|
||||
lotus wallet new
|
||||
lotus wallet new
|
||||
```
|
||||
|
||||
Sometimes your operating system may limit file name length to under 150 characters. You need to use a file system that supports long filenames.
|
||||
|
||||
Here is an example of the response:
|
||||
|
||||
```sh
|
||||
|
@ -34,7 +34,7 @@ Then, in another console, import the genesis miner key:
|
||||
Set up the genesis miner:
|
||||
|
||||
```sh
|
||||
./lotus-storage-miner init --genesis-miner --actor=t01000 --sector-size=1024 --pre-sealed-sectors=~/.genesis-sectors --nosync
|
||||
./lotus-storage-miner init --genesis-miner --actor=t01000 --sector-size=1024 --pre-sealed-sectors=~/.genesis-sectors --pre-sealed-metadata=~/.genesis-sectors/pre-seal-t0101.json --nosync
|
||||
```
|
||||
|
||||
Now, finally, start up the miner:
|
||||
|
@ -14,12 +14,18 @@ IPFS_GATEWAY="https://proof-parameters.s3.cn-south-1.jdcloud-oss.com/ipfs/"
|
||||
|
||||
## Get started
|
||||
|
||||
Please ensure that at least one **BLS address** in your wallet exists with the following command:
|
||||
Please ensure that at least one **BLS address** (starts with `t3`) in your wallet exists with the following command:
|
||||
|
||||
```sh
|
||||
lotus wallet list
|
||||
```
|
||||
|
||||
If you do not have a bls address, create a new bls wallet:
|
||||
|
||||
```sh
|
||||
lotus wallet new bls
|
||||
```
|
||||
|
||||
With your wallet address:
|
||||
|
||||
- Visit the [faucet](https://lotus-faucet.kittyhawk.wtf/miner.html)
|
||||
|
17
gen/main.go
17
gen/main.go
@ -53,6 +53,15 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err = gen.WriteTupleEncodersToFile("./node/hello/cbor_gen.go", "hello",
|
||||
hello.HelloMessage{},
|
||||
hello.LatencyMessage{},
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err = gen.WriteTupleEncodersToFile("./chain/blocksync/cbor_gen.go", "blocksync",
|
||||
blocksync.BlockSyncRequest{},
|
||||
blocksync.BlockSyncResponse{},
|
||||
@ -83,12 +92,4 @@ func main() {
|
||||
fmt.Printf("%+v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err = gen.WriteMapEncodersToFile("./node/hello/cbor_gen.go", "hello",
|
||||
hello.Message{},
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("%+v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
9
go.mod
9
go.mod
@ -8,7 +8,7 @@ require (
|
||||
github.com/GeertJohan/go.rice v1.0.0
|
||||
github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
|
||||
github.com/coreos/go-systemd v0.0.0-00010101000000-000000000000
|
||||
github.com/coreos/go-systemd/v22 v22.0.0
|
||||
github.com/docker/go-units v0.4.0
|
||||
github.com/filecoin-project/chain-validation v0.0.3
|
||||
github.com/filecoin-project/filecoin-ffi v0.0.0-20191219131535-bb699517a590
|
||||
@ -30,7 +30,7 @@ require (
|
||||
github.com/gorilla/mux v1.7.3
|
||||
github.com/gorilla/websocket v1.4.1
|
||||
github.com/hashicorp/go-multierror v1.0.0
|
||||
github.com/hashicorp/golang-lru v0.5.3
|
||||
github.com/hashicorp/golang-lru v0.5.4
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e
|
||||
github.com/ipfs/go-bitswap v0.1.8
|
||||
github.com/ipfs/go-block-format v0.0.2
|
||||
@ -67,7 +67,7 @@ require (
|
||||
github.com/libp2p/go-libp2p-mplex v0.2.1
|
||||
github.com/libp2p/go-libp2p-peer v0.2.0
|
||||
github.com/libp2p/go-libp2p-peerstore v0.1.4
|
||||
github.com/libp2p/go-libp2p-pubsub v0.2.3
|
||||
github.com/libp2p/go-libp2p-pubsub v0.2.6
|
||||
github.com/libp2p/go-libp2p-quic-transport v0.1.1
|
||||
github.com/libp2p/go-libp2p-record v0.1.1
|
||||
github.com/libp2p/go-libp2p-routing-helpers v0.1.0
|
||||
@ -85,6 +85,7 @@ require (
|
||||
github.com/multiformats/go-multihash v0.0.13
|
||||
github.com/multiformats/go-varint v0.0.5
|
||||
github.com/opentracing/opentracing-go v1.1.0
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829
|
||||
github.com/prometheus/common v0.4.0
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba
|
||||
@ -113,5 +114,3 @@ require (
|
||||
replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v1.18.0
|
||||
|
||||
replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi
|
||||
|
||||
replace github.com/coreos/go-systemd => github.com/coreos/go-systemd/v22 v22.0.0
|
||||
|
29
go.sum
29
go.sum
@ -33,6 +33,7 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
|
||||
github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
|
||||
github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
|
||||
@ -113,8 +114,6 @@ github.com/filecoin-project/go-data-transfer v0.0.0-20191219005021-4accf56bd2ce
|
||||
github.com/filecoin-project/go-data-transfer v0.0.0-20191219005021-4accf56bd2ce/go.mod h1:b14UWxhxVCAjrQUYvVGrQRRsjAh79wXYejw9RbUcAww=
|
||||
github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 h1:yvQJCW9mmi9zy+51xA01Ea2X7/dL7r8eKDPuGUjRmbo=
|
||||
github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5/go.mod h1:JbkIgFF/Z9BDlvrJO1FuKkaWsH673/UdFaiVS6uIHlA=
|
||||
github.com/filecoin-project/go-fil-markets v0.0.0-20200220181918-bfd030852a59 h1:AULXvl86fSjh1gS3V/xo2YEWntAOSe3HGAHO0+S2h8k=
|
||||
github.com/filecoin-project/go-fil-markets v0.0.0-20200220181918-bfd030852a59/go.mod h1:ftsiBbjLjNLAZ52FVDigkdCp73ltdcvAzAXav6drSLA=
|
||||
github.com/filecoin-project/go-fil-markets v0.0.0-20200223154807-f7afd8e927f9 h1:uFS5r3K3AgIuR7cGBYY8k+vgwn/UXhin9NR2yCXVe7o=
|
||||
github.com/filecoin-project/go-fil-markets v0.0.0-20200223154807-f7afd8e927f9/go.mod h1:ftsiBbjLjNLAZ52FVDigkdCp73ltdcvAzAXav6drSLA=
|
||||
github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:92PET+sx1Hb4W/8CgFwGuxaKbttwY+UNspYZTvXY0vs=
|
||||
@ -129,12 +128,6 @@ github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZO
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf h1:fbxBG12yrxilPFV1EG2lYqpUyAlRZWkvtqjk2svSeXY=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200220011005-b2a2fbf40362/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200221171119-030c8eaad3ba h1:KXxG0UblgNdQeAxdQZNXdECYV4FCJC/noXrIjvElO/0=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200221171119-030c8eaad3ba/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200223193531-f9e06ceb423b h1:E19WAsPkbYgle7f5RwTutpc+Ijzk/PXN+V66BaCfQuk=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200223193531-f9e06ceb423b/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200223194434-40d9fd965c67 h1:vpjeC/VS2TyqRCgjJ0ehhIHPaWUqJiKqLC2TAEJuOw0=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200223194434-40d9fd965c67/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200223194852-39976038b18d h1:vukVHqbLQnXc+ZfhK+Cor3kaQx9SQbSZISqSeGjhYcE=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200223194852-39976038b18d/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
@ -205,6 +198,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
@ -397,6 +392,8 @@ github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UG
|
||||
github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s=
|
||||
github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8=
|
||||
github.com/libp2p/go-flow-metrics v0.0.3 h1:8tAs/hSdNvUiLgtlSy3mxwxWP4I9y/jlkPFT7epKdeM=
|
||||
github.com/libp2p/go-flow-metrics v0.0.3 h1:8tAs/hSdNvUiLgtlSy3mxwxWP4I9y/jlkPFT7epKdeM=
|
||||
github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs=
|
||||
github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs=
|
||||
github.com/libp2p/go-libp2p v0.0.30/go.mod h1:XWT8FGHlhptAv1+3V/+J5mEpzyui/5bvFsNuWYs611A=
|
||||
github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM=
|
||||
@ -432,6 +429,8 @@ github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZV
|
||||
github.com/libp2p/go-libp2p-core v0.2.4 h1:Et6ykkTwI6PU44tr8qUF9k43vP0aduMNniShAbUJJw8=
|
||||
github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g=
|
||||
github.com/libp2p/go-libp2p-core v0.3.0 h1:F7PqduvrztDtFsAa/bcheQ3azmNo+Nq7m8hQY5GiUW8=
|
||||
github.com/libp2p/go-libp2p-core v0.3.0 h1:F7PqduvrztDtFsAa/bcheQ3azmNo+Nq7m8hQY5GiUW8=
|
||||
github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw=
|
||||
github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw=
|
||||
github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE=
|
||||
github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I=
|
||||
@ -486,8 +485,8 @@ github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVd
|
||||
github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s=
|
||||
github.com/libp2p/go-libp2p-protocol v0.1.0 h1:HdqhEyhg0ToCaxgMhnOmUO8snQtt/kQlcjVk3UoJU3c=
|
||||
github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.2.3 h1:qJRnRnM7Z4xnHb4i6EBb3DKQXRPgtFWlKP4AmfJudLQ=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.2.3/go.mod h1:Jscj3fk23R5mCrOwb625xjVs5ZEyTZcx/OlTwMDqU+g=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.2.6 h1:ypZaukCFrtD8cNeeb9nnWG4MD2Y1T0p22aQ+f7FKJig=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.2.6/go.mod h1:5jEp7R3ItQ0pgcEMrPZYE9DQTg/H3CTc7Mu1j2G4Y5o=
|
||||
github.com/libp2p/go-libp2p-quic-transport v0.1.1 h1:MFMJzvsxIEDEVKzO89BnB/FgvMj9WI4GDGUW2ArDPUA=
|
||||
github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU=
|
||||
github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q=
|
||||
@ -593,6 +592,7 @@ github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/miekg/dns v1.1.12 h1:WMhc1ik4LNkTg8U9l3hI1LvxKmIL+f1+WV/SZtCbDDA=
|
||||
@ -650,6 +650,8 @@ github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wS
|
||||
github.com/multiformats/go-multistream v0.0.4/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg=
|
||||
github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ=
|
||||
github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg=
|
||||
github.com/multiformats/go-multistream v0.1.1 h1:JlAdpIFhBhGRLxe9W6Om0w++Gd6KMWoFPZL/dEnm9nI=
|
||||
github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38=
|
||||
github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
||||
github.com/multiformats/go-varint v0.0.2 h1:6sUvyh2YHpJCb8RZ6eYzj6iJQ4+chWYmyIHxszqlPTA=
|
||||
github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
||||
@ -692,14 +694,17 @@ github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXx
|
||||
github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a h1:hjZfReYVLbqFkAtr2us7vdy04YWz3LVAirzP7reh8+M=
|
||||
github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 h1:D+CiwcpGTW6pL6bv6KI3KbyEyCKyS+1JWS2h8PNDnGA=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f h1:BVwpUVJDADN2ufcGik7W992pyps0wZ888b/y9GXcLTU=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 h1:/K3IL0Z1quvmJ7X0A1AwNEK7CRkVK3YwfOU/QAL4WGg=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk=
|
||||
@ -767,9 +772,9 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20191216205031-b047b6acb3c0/go.mod h1:x
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158 h1:WXhVOwj2USAXB5oMDwRl3piOux2XMV9TANaYxXHdkoE=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200206220010-03c9665e2a66 h1:LolR9FiEfQNn5U031bAhn/46po2JgWHKadYbcWFIJ+0=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200206220010-03c9665e2a66 h1:LolR9FiEfQNn5U031bAhn/46po2JgWHKadYbcWFIJ+0=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200206220010-03c9665e2a66/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200206220010-03c9665e2a66/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200213013405-80352c7ae952 h1:YGoOfwBeeb6A8t3eSe2nmPtMsyYPa6WzBmTbSPLRNK8=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200213013405-80352c7ae952/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200222160900-51052a1e8191 h1:TeuxLwKwQy612jEhfVhGJTqLsM2EwMi1eJE052ug+NY=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200222160900-51052a1e8191/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
|
||||
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E=
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"reflect"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
@ -18,11 +19,15 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var log = logging.Logger("rpc")
|
||||
const (
|
||||
methodRetryFrequency = time.Second * 3
|
||||
)
|
||||
|
||||
var (
|
||||
errorType = reflect.TypeOf(new(error)).Elem()
|
||||
contextType = reflect.TypeOf(new(context.Context)).Elem()
|
||||
|
||||
log = logging.Logger("rpc")
|
||||
)
|
||||
|
||||
// ErrClient is an error which occurred on the client side the library
|
||||
@ -78,12 +83,21 @@ type client struct {
|
||||
|
||||
// NewMergeClient is like NewClient, but allows to specify multiple structs
|
||||
// to be filled in the same namespace, using one connection
|
||||
func NewMergeClient(addr string, namespace string, outs []interface{}, requestHeader http.Header) (ClientCloser, error) {
|
||||
conn, _, err := websocket.DefaultDialer.Dial(addr, requestHeader)
|
||||
func NewMergeClient(addr string, namespace string, outs []interface{}, requestHeader http.Header, opts ...Option) (ClientCloser, error) {
|
||||
connFactory := func() (*websocket.Conn, error) {
|
||||
conn, _, err := websocket.DefaultDialer.Dial(addr, requestHeader)
|
||||
return conn, err
|
||||
}
|
||||
conn, err := connFactory()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var config Config
|
||||
for _, o := range opts {
|
||||
o(&config)
|
||||
}
|
||||
|
||||
c := client{
|
||||
namespace: namespace,
|
||||
}
|
||||
@ -95,11 +109,13 @@ func NewMergeClient(addr string, namespace string, outs []interface{}, requestHe
|
||||
|
||||
handlers := map[string]rpcHandler{}
|
||||
go (&wsConn{
|
||||
conn: conn,
|
||||
handler: handlers,
|
||||
requests: c.requests,
|
||||
stop: stop,
|
||||
exiting: exiting,
|
||||
conn: conn,
|
||||
connFactory: connFactory,
|
||||
reconnectInterval: config.ReconnectInterval,
|
||||
handler: handlers,
|
||||
requests: c.requests,
|
||||
stop: stop,
|
||||
exiting: exiting,
|
||||
}).handleWsConn(context.TODO())
|
||||
|
||||
for _, handler := range outs {
|
||||
@ -269,6 +285,8 @@ type rpcFunc struct {
|
||||
|
||||
hasCtx int
|
||||
retCh bool
|
||||
|
||||
retry bool
|
||||
}
|
||||
|
||||
func (fn *rpcFunc) processResponse(resp clientResponse, rval reflect.Value) []reflect.Value {
|
||||
@ -344,27 +362,38 @@ func (fn *rpcFunc) handleRpcCall(args []reflect.Value) (results []reflect.Value)
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := fn.client.sendRequest(ctx, req, chCtor)
|
||||
if err != nil {
|
||||
return fn.processError(fmt.Errorf("sendRequest failed: %w", err))
|
||||
}
|
||||
|
||||
if resp.ID != *req.ID {
|
||||
return fn.processError(xerrors.New("request and response id didn't match"))
|
||||
}
|
||||
|
||||
if fn.valOut != -1 && !fn.retCh {
|
||||
val := reflect.New(fn.ftyp.Out(fn.valOut))
|
||||
|
||||
if resp.Result != nil {
|
||||
log.Debugw("rpc result", "type", fn.ftyp.Out(fn.valOut))
|
||||
if err := json.Unmarshal(resp.Result, val.Interface()); err != nil {
|
||||
log.Warnw("unmarshaling failed", "message", string(resp.Result))
|
||||
return fn.processError(xerrors.Errorf("unmarshaling result: %w", err))
|
||||
}
|
||||
var resp clientResponse
|
||||
var err error
|
||||
// keep retrying if got a forced closed websocket conn and calling method
|
||||
// has retry annotation
|
||||
for {
|
||||
resp, err = fn.client.sendRequest(ctx, req, chCtor)
|
||||
if err != nil {
|
||||
return fn.processError(fmt.Errorf("sendRequest failed: %w", err))
|
||||
}
|
||||
|
||||
retVal = func() reflect.Value { return val.Elem() }
|
||||
if resp.ID != *req.ID {
|
||||
return fn.processError(xerrors.New("request and response id didn't match"))
|
||||
}
|
||||
|
||||
if fn.valOut != -1 && !fn.retCh {
|
||||
val := reflect.New(fn.ftyp.Out(fn.valOut))
|
||||
|
||||
if resp.Result != nil {
|
||||
log.Debugw("rpc result", "type", fn.ftyp.Out(fn.valOut))
|
||||
if err := json.Unmarshal(resp.Result, val.Interface()); err != nil {
|
||||
log.Warnw("unmarshaling failed", "message", string(resp.Result))
|
||||
return fn.processError(xerrors.Errorf("unmarshaling result: %w", err))
|
||||
}
|
||||
}
|
||||
|
||||
retVal = func() reflect.Value { return val.Elem() }
|
||||
}
|
||||
retry := resp.Error != nil && resp.Error.Code == 2 && fn.retry
|
||||
if !retry {
|
||||
break
|
||||
}
|
||||
time.Sleep(methodRetryFrequency)
|
||||
}
|
||||
|
||||
return fn.processResponse(resp, retVal())
|
||||
@ -380,6 +409,7 @@ func (c *client) makeRpcFunc(f reflect.StructField) (reflect.Value, error) {
|
||||
client: c,
|
||||
ftyp: ftyp,
|
||||
name: f.Name,
|
||||
retry: f.Tag.Get("retry") == "true",
|
||||
}
|
||||
fun.valOut, fun.errOut, fun.nout = processFuncOut(ftyp)
|
||||
|
||||
|
19
lib/jsonrpc/options.go
Normal file
19
lib/jsonrpc/options.go
Normal file
@ -0,0 +1,19 @@
|
||||
package jsonrpc
|
||||
|
||||
import "time"
|
||||
|
||||
type Config struct {
|
||||
ReconnectInterval time.Duration
|
||||
}
|
||||
|
||||
var defaultConfig = Config{
|
||||
ReconnectInterval: time.Second * 5,
|
||||
}
|
||||
|
||||
type Option func(c *Config)
|
||||
|
||||
func WithReconnectInterval(d time.Duration) func(c *Config) {
|
||||
return func(c *Config) {
|
||||
c.ReconnectInterval = d
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ import (
|
||||
"reflect"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"golang.org/x/xerrors"
|
||||
@ -42,11 +43,13 @@ type outChanReg struct {
|
||||
|
||||
type wsConn struct {
|
||||
// outside params
|
||||
conn *websocket.Conn
|
||||
handler handlers
|
||||
requests <-chan clientRequest
|
||||
stop <-chan struct{}
|
||||
exiting chan struct{}
|
||||
conn *websocket.Conn
|
||||
connFactory func() (*websocket.Conn, error)
|
||||
reconnectInterval time.Duration
|
||||
handler handlers
|
||||
requests <-chan clientRequest
|
||||
stop <-chan struct{}
|
||||
exiting chan struct{}
|
||||
|
||||
// incoming messages
|
||||
incoming chan io.Reader
|
||||
@ -419,6 +422,35 @@ func (c *wsConn) handleFrame(ctx context.Context, frame frame) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *wsConn) closeInFlight() {
|
||||
for id, req := range c.inflight {
|
||||
req.ready <- clientResponse{
|
||||
Jsonrpc: "2.0",
|
||||
ID: id,
|
||||
Error: &respError{
|
||||
Message: "handler: websocket connection closed",
|
||||
Code: 2,
|
||||
},
|
||||
}
|
||||
|
||||
c.handlingLk.Lock()
|
||||
for _, cancel := range c.handling {
|
||||
cancel()
|
||||
}
|
||||
c.handlingLk.Unlock()
|
||||
}
|
||||
c.inflight = map[int64]clientRequest{}
|
||||
c.handling = map[int64]context.CancelFunc{}
|
||||
}
|
||||
|
||||
func (c *wsConn) closeChans() {
|
||||
for chid := range c.chanHandlers {
|
||||
hnd := c.chanHandlers[chid]
|
||||
delete(c.chanHandlers, chid)
|
||||
hnd(nil, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *wsConn) handleWsConn(ctx context.Context) {
|
||||
c.incoming = make(chan io.Reader)
|
||||
c.inflight = map[int64]clientRequest{}
|
||||
@ -432,27 +464,10 @@ func (c *wsConn) handleWsConn(ctx context.Context) {
|
||||
|
||||
// on close, make sure to return from all pending calls, and cancel context
|
||||
// on all calls we handle
|
||||
defer func() {
|
||||
for id, req := range c.inflight {
|
||||
req.ready <- clientResponse{
|
||||
Jsonrpc: "2.0",
|
||||
ID: id,
|
||||
Error: &respError{
|
||||
Message: "handler: websocket connection closed",
|
||||
},
|
||||
}
|
||||
|
||||
c.handlingLk.Lock()
|
||||
for _, cancel := range c.handling {
|
||||
cancel()
|
||||
}
|
||||
c.handlingLk.Unlock()
|
||||
}
|
||||
}()
|
||||
defer c.closeInFlight()
|
||||
|
||||
// wait for the first message
|
||||
go c.nextMessage()
|
||||
|
||||
for {
|
||||
select {
|
||||
case r, ok := <-c.incoming:
|
||||
@ -460,6 +475,28 @@ func (c *wsConn) handleWsConn(ctx context.Context) {
|
||||
if c.incomingErr != nil {
|
||||
if !websocket.IsCloseError(c.incomingErr, websocket.CloseNormalClosure) {
|
||||
log.Debugw("websocket error", "error", c.incomingErr)
|
||||
// connection dropped unexpectedly, do our best to recover it
|
||||
c.closeInFlight()
|
||||
c.closeChans()
|
||||
c.incoming = make(chan io.Reader) // listen again for responses
|
||||
go func() {
|
||||
var conn *websocket.Conn
|
||||
for conn == nil {
|
||||
time.Sleep(c.reconnectInterval)
|
||||
var err error
|
||||
if conn, err = c.connFactory(); err != nil {
|
||||
log.Debugw("websocket connection retried failed", "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
c.writeLk.Lock()
|
||||
c.conn = conn
|
||||
c.incomingErr = nil
|
||||
c.writeLk.Unlock()
|
||||
|
||||
go c.nextMessage()
|
||||
}()
|
||||
continue
|
||||
}
|
||||
}
|
||||
return // remote closed
|
||||
@ -477,9 +514,23 @@ func (c *wsConn) handleWsConn(ctx context.Context) {
|
||||
c.handleFrame(ctx, frame)
|
||||
go c.nextMessage()
|
||||
case req := <-c.requests:
|
||||
c.writeLk.Lock()
|
||||
if req.req.ID != nil {
|
||||
if c.incomingErr != nil { // No conn?, immediate fail
|
||||
req.ready <- clientResponse{
|
||||
Jsonrpc: "2.0",
|
||||
ID: *req.req.ID,
|
||||
Error: &respError{
|
||||
Message: "handler: websocket connection closed",
|
||||
Code: 2,
|
||||
},
|
||||
}
|
||||
c.writeLk.Unlock()
|
||||
break
|
||||
}
|
||||
c.inflight[*req.req.ID] = req
|
||||
}
|
||||
c.writeLk.Unlock()
|
||||
c.sendRequest(req.req)
|
||||
case <-c.stop:
|
||||
c.writeLk.Lock()
|
||||
|
@ -167,7 +167,8 @@ func (api *api) SpawnStorage(fullNodeRepo string) (nodeInfo, error) {
|
||||
|
||||
initArgs := []string{"init", "--nosync"}
|
||||
if fullNodeRepo == api.running[1].meta.Repo {
|
||||
initArgs = []string{"init", "--actor=t01000", "--genesis-miner", "--pre-sealed-sectors=" + filepath.Join(fullNodeRepo, "preseal")}
|
||||
presealPrefix := filepath.Join(fullNodeRepo, "preseal")
|
||||
initArgs = []string{"init", "--actor=t01000", "--genesis-miner", "--pre-sealed-sectors=" + presealPrefix, "--pre-sealed-metadata=" + filepath.Join(presealPrefix, "pre-seal-t0101.json")}
|
||||
}
|
||||
|
||||
id := atomic.AddInt32(&api.cmds, 1)
|
||||
|
@ -63,7 +63,7 @@ func (n *ClientNodeAdapter) ListStorageProviders(ctx context.Context) ([]*storag
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addresses, err := n.StateListMiners(ctx, ts)
|
||||
addresses, err := n.StateListMiners(ctx, ts.Key())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -71,17 +71,17 @@ func (n *ClientNodeAdapter) ListStorageProviders(ctx context.Context) ([]*storag
|
||||
var out []*storagemarket.StorageProviderInfo
|
||||
|
||||
for _, addr := range addresses {
|
||||
workerAddr, err := n.StateMinerWorker(ctx, addr, ts)
|
||||
workerAddr, err := n.StateMinerWorker(ctx, addr, ts.Key())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sectorSize, err := n.StateMinerSectorSize(ctx, addr, ts)
|
||||
sectorSize, err := n.StateMinerSectorSize(ctx, addr, ts.Key())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
peerId, err := n.StateMinerPeerID(ctx, addr, ts)
|
||||
peerId, err := n.StateMinerPeerID(ctx, addr, ts.Key())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -98,7 +98,7 @@ func (n *ClientNodeAdapter) VerifySignature(sig crypto.Signature, addr address.A
|
||||
}
|
||||
|
||||
func (n *ClientNodeAdapter) ListClientDeals(ctx context.Context, addr address.Address) ([]storagemarket.StorageDeal, error) {
|
||||
allDeals, err := n.StateMarketDeals(ctx, nil)
|
||||
allDeals, err := n.StateMarketDeals(ctx, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -151,7 +151,7 @@ func (n *ClientNodeAdapter) EnsureFunds(ctx context.Context, addr address.Addres
|
||||
}
|
||||
|
||||
func (n *ClientNodeAdapter) GetBalance(ctx context.Context, addr address.Address) (storagemarket.Balance, error) {
|
||||
bal, err := n.StateMarketBalance(ctx, addr, nil)
|
||||
bal, err := n.StateMarketBalance(ctx, addr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return storagemarket.Balance{}, err
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ func NewProviderNodeAdapter(dag dtypes.StagingDAG, secb *sectorblocks.SectorBloc
|
||||
func (n *ProviderNodeAdapter) PublishDeals(ctx context.Context, deal storagemarket.MinerDeal) (storagemarket.DealID, cid.Cid, error) {
|
||||
log.Info("publishing deal")
|
||||
|
||||
worker, err := n.StateMinerWorker(ctx, deal.Proposal.Provider, nil)
|
||||
worker, err := n.StateMinerWorker(ctx, deal.Proposal.Provider, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return 0, cid.Undef, err
|
||||
}
|
||||
@ -114,7 +114,7 @@ func (n *ProviderNodeAdapter) VerifySignature(sig crypto.Signature, addr address
|
||||
}
|
||||
|
||||
func (n *ProviderNodeAdapter) ListProviderDeals(ctx context.Context, addr address.Address) ([]storagemarket.StorageDeal, error) {
|
||||
allDeals, err := n.StateMarketDeals(ctx, nil)
|
||||
allDeals, err := n.StateMarketDeals(ctx, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -132,7 +132,7 @@ func (n *ProviderNodeAdapter) ListProviderDeals(ctx context.Context, addr addres
|
||||
}
|
||||
|
||||
func (n *ProviderNodeAdapter) GetMinerWorker(ctx context.Context, miner address.Address) (address.Address, error) {
|
||||
addr, err := n.StateMinerWorker(ctx, miner, nil)
|
||||
addr, err := n.StateMinerWorker(ctx, miner, types.EmptyTSK)
|
||||
return addr, err
|
||||
}
|
||||
|
||||
@ -180,7 +180,7 @@ func (n *ProviderNodeAdapter) AddFunds(ctx context.Context, addr address.Address
|
||||
}
|
||||
|
||||
func (n *ProviderNodeAdapter) GetBalance(ctx context.Context, addr address.Address) (storagemarket.Balance, error) {
|
||||
bal, err := n.StateMarketBalance(ctx, addr, nil)
|
||||
bal, err := n.StateMarketBalance(ctx, addr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return storagemarket.Balance{}, err
|
||||
}
|
||||
@ -220,7 +220,7 @@ func (n *ProviderNodeAdapter) LocatePieceForDealWithinSector(ctx context.Context
|
||||
|
||||
func (n *ProviderNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider address.Address, dealID uint64, cb storagemarket.DealSectorCommittedCallback) error {
|
||||
checkFunc := func(ts *types.TipSet) (done bool, more bool, err error) {
|
||||
sd, err := n.StateMarketStorageDeal(ctx, abi.DealID(dealID), ts)
|
||||
sd, err := n.StateMarketStorageDeal(ctx, abi.DealID(dealID), ts.Key())
|
||||
|
||||
if err != nil {
|
||||
// TODO: This may be fine for some errors
|
||||
@ -247,7 +247,7 @@ func (n *ProviderNodeAdapter) OnDealSectorCommitted(ctx context.Context, provide
|
||||
return false, nil
|
||||
}
|
||||
|
||||
sd, err := n.StateMarketStorageDeal(ctx, abi.DealID(dealID), ts)
|
||||
sd, err := n.StateMarketStorageDeal(ctx, abi.DealID(dealID), ts.Key())
|
||||
if err != nil {
|
||||
return false, xerrors.Errorf("failed to look up deal on chain: %w", err)
|
||||
}
|
||||
|
@ -259,11 +259,11 @@ func (m *Miner) GetBestMiningCandidate(ctx context.Context) (*MiningBase, error)
|
||||
return m.lastWork, nil
|
||||
}
|
||||
|
||||
btsw, err := m.api.ChainTipSetWeight(ctx, bts)
|
||||
btsw, err := m.api.ChainTipSetWeight(ctx, bts.Key())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ltsw, err := m.api.ChainTipSetWeight(ctx, m.lastWork.ts)
|
||||
ltsw, err := m.api.ChainTipSetWeight(ctx, m.lastWork.ts.Key())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -278,7 +278,7 @@ func (m *Miner) GetBestMiningCandidate(ctx context.Context) (*MiningBase, error)
|
||||
}
|
||||
|
||||
func (m *Miner) hasPower(ctx context.Context, addr address.Address, ts *types.TipSet) (bool, error) {
|
||||
power, err := m.api.StateMinerPower(ctx, addr, ts)
|
||||
power, err := m.api.StateMinerPower(ctx, addr, ts.Key())
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@ -318,7 +318,7 @@ func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningB
|
||||
}
|
||||
|
||||
// get pending messages early,
|
||||
pending, err := m.api.MpoolPending(context.TODO(), base.ts)
|
||||
pending, err := m.api.MpoolPending(context.TODO(), base.ts.Key())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get pending messages: %w", err)
|
||||
}
|
||||
@ -343,7 +343,7 @@ func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningB
|
||||
}
|
||||
|
||||
func (m *Miner) computeTicket(ctx context.Context, addr address.Address, base *MiningBase) (*types.Ticket, error) {
|
||||
w, err := m.api.StateMinerWorker(ctx, addr, nil)
|
||||
w, err := m.api.StateMinerWorker(ctx, addr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -379,10 +379,10 @@ func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *type
|
||||
nheight := base.ts.Height() + base.nullRounds + 1
|
||||
|
||||
// why even return this? that api call could just submit it for us
|
||||
return m.api.MinerCreateBlock(context.TODO(), addr, base.ts, ticket, proof, msgs, nheight, uint64(uts))
|
||||
return m.api.MinerCreateBlock(context.TODO(), addr, base.ts.Key(), ticket, proof, msgs, nheight, uint64(uts))
|
||||
}
|
||||
|
||||
type ActorLookup func(context.Context, address.Address, *types.TipSet) (*types.Actor, error)
|
||||
type ActorLookup func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error)
|
||||
|
||||
func countFrom(msgs []*types.SignedMessage, from address.Address) (out int) {
|
||||
for _, msg := range msgs {
|
||||
@ -409,7 +409,7 @@ func SelectMessages(ctx context.Context, al ActorLookup, ts *types.TipSet, msgs
|
||||
from := msg.Message.From
|
||||
|
||||
if _, ok := inclNonces[from]; !ok {
|
||||
act, err := al(ctx, from, ts)
|
||||
act, err := al(ctx, from, ts.Key())
|
||||
if err != nil {
|
||||
log.Warnf("failed to check message sender balance, skipping message: %+v", err)
|
||||
continue
|
||||
|
@ -33,7 +33,7 @@ func TestMessageFiltering(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
af := func(ctx context.Context, addr address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
af := func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||
return actors[addr], nil
|
||||
}
|
||||
|
||||
|
@ -92,6 +92,7 @@ const (
|
||||
|
||||
RunHelloKey
|
||||
RunBlockSyncKey
|
||||
RunChainGraphsync
|
||||
RunPeerMgrKey
|
||||
|
||||
HandleIncomingBlocksKey
|
||||
@ -159,7 +160,7 @@ func libp2p() Option {
|
||||
Override(AddrsFactoryKey, lp2p.AddrsFactory(nil, nil)),
|
||||
Override(SmuxTransportKey, lp2p.SmuxTransport(true)),
|
||||
Override(RelayKey, lp2p.Relay(true, false)),
|
||||
Override(SecurityKey, lp2p.Security(true, false)),
|
||||
Override(SecurityKey, lp2p.Security(true, true)),
|
||||
|
||||
Override(BaseRoutingKey, lp2p.BaseRouting),
|
||||
Override(new(routing.Routing), lp2p.Routing),
|
||||
@ -228,6 +229,7 @@ func Online() Option {
|
||||
|
||||
Override(RunHelloKey, modules.RunHello),
|
||||
Override(RunBlockSyncKey, modules.RunBlockSync),
|
||||
Override(RunChainGraphsync, modules.ChainGraphsync),
|
||||
Override(RunPeerMgrKey, modules.RunPeerMgr),
|
||||
Override(HandleIncomingBlocksKey, modules.HandleIncomingBlocks),
|
||||
|
||||
|
@ -6,34 +6,23 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
xerrors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var _ = xerrors.Errorf
|
||||
|
||||
func (t *Message) MarshalCBOR(w io.Writer) error {
|
||||
func (t *HelloMessage) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write([]byte{165}); err != nil {
|
||||
if _, err := w.Write([]byte{132}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.HeaviestTipSet ([]cid.Cid) (slice)
|
||||
if len("HeaviestTipSet") > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field \"HeaviestTipSet\" was too long")
|
||||
}
|
||||
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("HeaviestTipSet")))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write([]byte("HeaviestTipSet")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(t.HeaviestTipSet) > cbg.MaxLength {
|
||||
return xerrors.Errorf("Slice value in field t.HeaviestTipSet was too long")
|
||||
}
|
||||
@ -47,50 +36,110 @@ func (t *Message) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
}
|
||||
|
||||
// t.HeaviestTipSetWeight (big.Int) (struct)
|
||||
if len("HeaviestTipSetWeight") > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field \"HeaviestTipSetWeight\" was too long")
|
||||
}
|
||||
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("HeaviestTipSetWeight")))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write([]byte("HeaviestTipSetWeight")); err != nil {
|
||||
// t.HeaviestTipSetHeight (uint64) (uint64)
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.HeaviestTipSetHeight))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.HeaviestTipSetWeight (types.BigInt) (struct)
|
||||
if err := t.HeaviestTipSetWeight.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.GenesisHash (cid.Cid) (struct)
|
||||
if len("GenesisHash") > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field \"GenesisHash\" was too long")
|
||||
}
|
||||
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("GenesisHash")))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write([]byte("GenesisHash")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := cbg.WriteCid(w, t.GenesisHash); err != nil {
|
||||
return xerrors.Errorf("failed to write cid field t.GenesisHash: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *HelloMessage) UnmarshalCBOR(r io.Reader) error {
|
||||
br := cbg.GetPeeker(r)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeader(br)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 4 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.HeaviestTipSet ([]cid.Cid) (slice)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeader(br)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if extra > cbg.MaxLength {
|
||||
return fmt.Errorf("t.HeaviestTipSet: array too large (%d)", extra)
|
||||
}
|
||||
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("expected cbor array")
|
||||
}
|
||||
if extra > 0 {
|
||||
t.HeaviestTipSet = make([]cid.Cid, extra)
|
||||
}
|
||||
for i := 0; i < int(extra); i++ {
|
||||
|
||||
c, err := cbg.ReadCid(br)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("reading cid field t.HeaviestTipSet failed: %w", err)
|
||||
}
|
||||
t.HeaviestTipSet[i] = c
|
||||
}
|
||||
|
||||
// t.HeaviestTipSetHeight (uint64) (uint64)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeader(br)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajUnsignedInt {
|
||||
return fmt.Errorf("wrong type for uint64 field")
|
||||
}
|
||||
t.HeaviestTipSetHeight = uint64(extra)
|
||||
// t.HeaviestTipSetWeight (types.BigInt) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.HeaviestTipSetWeight.UnmarshalCBOR(br); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
// t.GenesisHash (cid.Cid) (struct)
|
||||
|
||||
{
|
||||
|
||||
c, err := cbg.ReadCid(br)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to read cid field t.GenesisHash: %w", err)
|
||||
}
|
||||
|
||||
t.GenesisHash = c
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *LatencyMessage) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write([]byte{130}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.TArrial (int64) (int64)
|
||||
if len("TArrial") > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field \"TArrial\" was too long")
|
||||
}
|
||||
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("TArrial")))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write([]byte("TArrial")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if t.TArrial >= 0 {
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.TArrial))); err != nil {
|
||||
return err
|
||||
@ -102,17 +151,6 @@ func (t *Message) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
|
||||
// t.TSent (int64) (int64)
|
||||
if len("TSent") > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field \"TSent\" was too long")
|
||||
}
|
||||
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("TSent")))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write([]byte("TSent")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if t.TSent >= 0 {
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.TSent))); err != nil {
|
||||
return err
|
||||
@ -125,143 +163,70 @@ func (t *Message) MarshalCBOR(w io.Writer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Message) UnmarshalCBOR(r io.Reader) error {
|
||||
func (t *LatencyMessage) UnmarshalCBOR(r io.Reader) error {
|
||||
br := cbg.GetPeeker(r)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeader(br)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajMap {
|
||||
return fmt.Errorf("cbor input should be of type map")
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra > cbg.MaxLength {
|
||||
return fmt.Errorf("Message: map struct too large (%d)", extra)
|
||||
if extra != 2 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
var name string
|
||||
n := extra
|
||||
|
||||
for i := uint64(0); i < n; i++ {
|
||||
|
||||
{
|
||||
sval, err := cbg.ReadString(br)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
name = string(sval)
|
||||
// t.TArrial (int64) (int64)
|
||||
{
|
||||
maj, extra, err := cbg.CborReadHeader(br)
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch name {
|
||||
// t.HeaviestTipSet ([]cid.Cid) (slice)
|
||||
case "HeaviestTipSet":
|
||||
|
||||
maj, extra, err = cbg.CborReadHeader(br)
|
||||
if err != nil {
|
||||
return err
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
|
||||
if extra > cbg.MaxLength {
|
||||
return fmt.Errorf("t.HeaviestTipSet: array too large (%d)", extra)
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("expected cbor array")
|
||||
}
|
||||
if extra > 0 {
|
||||
t.HeaviestTipSet = make([]cid.Cid, extra)
|
||||
}
|
||||
for i := 0; i < int(extra); i++ {
|
||||
|
||||
c, err := cbg.ReadCid(br)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("reading cid field t.HeaviestTipSet failed: %w", err)
|
||||
}
|
||||
t.HeaviestTipSet[i] = c
|
||||
}
|
||||
|
||||
// t.HeaviestTipSetWeight (big.Int) (struct)
|
||||
case "HeaviestTipSetWeight":
|
||||
|
||||
{
|
||||
|
||||
if err := t.HeaviestTipSetWeight.UnmarshalCBOR(br); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
// t.GenesisHash (cid.Cid) (struct)
|
||||
case "GenesisHash":
|
||||
|
||||
{
|
||||
|
||||
c, err := cbg.ReadCid(br)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to read cid field t.GenesisHash: %w", err)
|
||||
}
|
||||
|
||||
t.GenesisHash = c
|
||||
|
||||
}
|
||||
// t.TArrial (int64) (int64)
|
||||
case "TArrial":
|
||||
{
|
||||
maj, extra, err := cbg.CborReadHeader(br)
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
|
||||
t.TArrial = int64(extraI)
|
||||
}
|
||||
// t.TSent (int64) (int64)
|
||||
case "TSent":
|
||||
{
|
||||
maj, extra, err := cbg.CborReadHeader(br)
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
|
||||
t.TSent = int64(extraI)
|
||||
}
|
||||
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("unknown struct field %d: '%s'", i, name)
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
}
|
||||
|
||||
t.TArrial = int64(extraI)
|
||||
}
|
||||
// t.TSent (int64) (int64)
|
||||
{
|
||||
maj, extra, err := cbg.CborReadHeader(br)
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
|
||||
t.TSent = int64(extraI)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
protocol "github.com/libp2p/go-libp2p-core/protocol"
|
||||
|
||||
"github.com/filecoin-project/go-cbor-util"
|
||||
cborutil "github.com/filecoin-project/go-cbor-util"
|
||||
"github.com/filecoin-project/lotus/chain"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@ -23,11 +23,13 @@ const ProtocolID = "/fil/hello/1.0.0"
|
||||
|
||||
var log = logging.Logger("hello")
|
||||
|
||||
type Message struct {
|
||||
type HelloMessage struct {
|
||||
HeaviestTipSet []cid.Cid
|
||||
HeaviestTipSetHeight uint64
|
||||
HeaviestTipSetWeight big.Int
|
||||
GenesisHash cid.Cid
|
||||
|
||||
}
|
||||
type LatencyMessage struct {
|
||||
TArrial int64
|
||||
TSent int64
|
||||
}
|
||||
@ -57,7 +59,7 @@ func NewHelloService(h host.Host, cs *store.ChainStore, syncer *chain.Syncer, pm
|
||||
|
||||
func (hs *Service) HandleStream(s inet.Stream) {
|
||||
|
||||
var hmsg Message
|
||||
var hmsg HelloMessage
|
||||
if err := cborutil.ReadCborRPC(s, &hmsg); err != nil {
|
||||
log.Infow("failed to read hello message, diconnecting", "error", err)
|
||||
s.Conn().Close()
|
||||
@ -79,7 +81,7 @@ func (hs *Service) HandleStream(s inet.Stream) {
|
||||
defer s.Close()
|
||||
|
||||
sent := time.Now()
|
||||
msg := &Message{
|
||||
msg := &LatencyMessage{
|
||||
TArrial: arrived.UnixNano(),
|
||||
TSent: sent.UnixNano(),
|
||||
}
|
||||
@ -124,8 +126,9 @@ func (hs *Service) SayHello(ctx context.Context, pid peer.ID) error {
|
||||
return err
|
||||
}
|
||||
|
||||
hmsg := &Message{
|
||||
hmsg := &HelloMessage{
|
||||
HeaviestTipSet: hts.Cids(),
|
||||
HeaviestTipSetHeight: hts.Height(),
|
||||
HeaviestTipSetWeight: weight,
|
||||
GenesisHash: gen.Cid(),
|
||||
}
|
||||
@ -139,10 +142,12 @@ func (hs *Service) SayHello(ctx context.Context, pid peer.ID) error {
|
||||
go func() {
|
||||
defer s.Close()
|
||||
|
||||
hmsg = &Message{}
|
||||
lmsg := &LatencyMessage{}
|
||||
s.SetReadDeadline(time.Now().Add(10 * time.Second))
|
||||
err := cborutil.ReadCborRPC(s, hmsg)
|
||||
ok := err == nil
|
||||
err := cborutil.ReadCborRPC(s, lmsg)
|
||||
if err != nil {
|
||||
log.Infow("reading latency message", "error", err)
|
||||
}
|
||||
|
||||
t3 := time.Now()
|
||||
lat := t3.Sub(t0)
|
||||
@ -151,10 +156,10 @@ func (hs *Service) SayHello(ctx context.Context, pid peer.ID) error {
|
||||
hs.pmgr.SetPeerLatency(pid, lat)
|
||||
}
|
||||
|
||||
if ok {
|
||||
if hmsg.TArrial != 0 && hmsg.TSent != 0 {
|
||||
t1 := time.Unix(0, hmsg.TArrial)
|
||||
t2 := time.Unix(0, hmsg.TSent)
|
||||
if err == nil {
|
||||
if lmsg.TArrial != 0 && lmsg.TSent != 0 {
|
||||
t1 := time.Unix(0, lmsg.TArrial)
|
||||
t2 := time.Unix(0, lmsg.TSent)
|
||||
offset := t0.Sub(t1) + t3.Sub(t2)
|
||||
offset /= 2
|
||||
log.Infow("time offset", "offset", offset.Seconds(), "peerid", pid.String())
|
||||
|
@ -67,12 +67,12 @@ func (a *API) ClientStartDeal(ctx context.Context, data cid.Cid, addr address.Ad
|
||||
return nil, xerrors.Errorf("provided address doesn't exist in wallet")
|
||||
}
|
||||
|
||||
pid, err := a.StateMinerPeerID(ctx, miner, nil)
|
||||
pid, err := a.StateMinerPeerID(ctx, miner, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed getting peer ID: %w", err)
|
||||
}
|
||||
|
||||
mw, err := a.StateMinerWorker(ctx, miner, nil)
|
||||
mw, err := a.StateMinerWorker(ctx, miner, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed getting miner worker: %w", err)
|
||||
}
|
||||
@ -279,7 +279,7 @@ func (a *API) ClientListImports(ctx context.Context) ([]api.Import, error) {
|
||||
|
||||
func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, path string) error {
|
||||
if order.MinerPeerID == "" {
|
||||
pid, err := a.StateMinerPeerID(ctx, order.Miner, nil)
|
||||
pid, err := a.StateMinerPeerID(ctx, order.Miner, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -2,6 +2,9 @@ package impl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/filecoin-project/lotus/node/modules/lp2p"
|
||||
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
|
||||
"github.com/gbrlsnchs/jwt/v3"
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
@ -21,6 +24,7 @@ type CommonAPI struct {
|
||||
|
||||
APISecret *dtypes.APIAlg
|
||||
Host host.Host
|
||||
Router lp2p.BaseIpfsRouting
|
||||
}
|
||||
|
||||
type jwtPayload struct {
|
||||
@ -79,6 +83,10 @@ func (a *CommonAPI) NetDisconnect(ctx context.Context, p peer.ID) error {
|
||||
return a.Host.Network().ClosePeer(p)
|
||||
}
|
||||
|
||||
func (a *CommonAPI) NetFindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, error) {
|
||||
return a.Router.FindPeer(ctx, p)
|
||||
}
|
||||
|
||||
func (a *CommonAPI) ID(context.Context) (peer.ID, error) {
|
||||
return a.Host.ID(), nil
|
||||
}
|
||||
@ -92,4 +100,12 @@ func (a *CommonAPI) Version(context.Context) (api.Version, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *CommonAPI) LogList(context.Context) ([]string, error) {
|
||||
return logging.GetSubsystems(), nil
|
||||
}
|
||||
|
||||
func (a *CommonAPI) LogSetLevel(ctx context.Context, subsystem, level string) error {
|
||||
return logging.SetLogLevel(subsystem, level)
|
||||
}
|
||||
|
||||
var _ api.Common = &CommonAPI{}
|
||||
|
@ -164,7 +164,11 @@ func (a *ChainAPI) ChainGetParentReceipts(ctx context.Context, bcid cid.Cid) ([]
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (a *ChainAPI) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, ts *types.TipSet) (*types.TipSet, error) {
|
||||
func (a *ChainAPI) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return a.Chain.GetTipsetByHeight(ctx, h, ts)
|
||||
}
|
||||
|
||||
@ -181,7 +185,11 @@ func (a *ChainAPI) ChainHasObj(ctx context.Context, obj cid.Cid) (bool, error) {
|
||||
return a.Chain.Blockstore().Has(obj)
|
||||
}
|
||||
|
||||
func (a *ChainAPI) ChainSetHead(ctx context.Context, ts *types.TipSet) error {
|
||||
func (a *ChainAPI) ChainSetHead(ctx context.Context, tsk types.TipSetKey) error {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return a.Chain.SetHead(ts)
|
||||
}
|
||||
|
||||
@ -194,7 +202,11 @@ func (a *ChainAPI) ChainGetGenesis(ctx context.Context) (*types.TipSet, error) {
|
||||
return types.NewTipSet([]*types.BlockHeader{genb})
|
||||
}
|
||||
|
||||
func (a *ChainAPI) ChainTipSetWeight(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
|
||||
func (a *ChainAPI) ChainTipSetWeight(ctx context.Context, tsk types.TipSetKey) (types.BigInt, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return types.EmptyInt, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return a.Chain.Weight(ctx, ts)
|
||||
}
|
||||
|
||||
@ -327,7 +339,11 @@ func (a *ChainAPI) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Mess
|
||||
return cm.VMMessage(), nil
|
||||
}
|
||||
|
||||
func (a *ChainAPI) ChainExport(ctx context.Context, ts *types.TipSet) (<-chan []byte, error) {
|
||||
func (a *ChainAPI) ChainExport(ctx context.Context, tsk types.TipSetKey) (<-chan []byte, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
r, w := io.Pipe()
|
||||
out := make(chan []byte)
|
||||
go func() {
|
||||
|
@ -24,7 +24,11 @@ type MpoolAPI struct {
|
||||
Mpool *messagepool.MessagePool
|
||||
}
|
||||
|
||||
func (a *MpoolAPI) MpoolPending(ctx context.Context, ts *types.TipSet) ([]*types.SignedMessage, error) {
|
||||
func (a *MpoolAPI) MpoolPending(ctx context.Context, tsk types.TipSetKey) ([]*types.SignedMessage, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
pending, mpts := a.Mpool.Pending()
|
||||
|
||||
haveCids := map[cid.Cid]struct{}{}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/prometheus/common/log"
|
||||
"strconv"
|
||||
|
||||
"github.com/filecoin-project/go-amt-ipld/v2"
|
||||
@ -45,15 +46,27 @@ type StateAPI struct {
|
||||
Chain *store.ChainStore
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerSectors(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*api.ChainSectorInfo, error) {
|
||||
func (a *StateAPI) StateMinerSectors(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return stmgr.GetMinerSectorSet(ctx, a.StateManager, ts, addr)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerProvingSet(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*api.ChainSectorInfo, error) {
|
||||
func (a *StateAPI) StateMinerProvingSet(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return stmgr.GetMinerProvingSet(ctx, a.StateManager, ts, addr)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerPower(ctx context.Context, maddr address.Address, ts *types.TipSet) (api.MinerPower, error) {
|
||||
func (a *StateAPI) StateMinerPower(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (api.MinerPower, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return api.MinerPower{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
mpow, tpow, err := stmgr.GetPower(ctx, a.StateManager, ts, maddr)
|
||||
if err != nil {
|
||||
return api.MinerPower{}, err
|
||||
@ -75,28 +88,53 @@ func (a *StateAPI) StateMinerPower(ctx context.Context, maddr address.Address, t
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerWorker(ctx context.Context, m address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
func (a *StateAPI) StateMinerWorker(ctx context.Context, m address.Address, tsk types.TipSetKey) (address.Address, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return stmgr.GetMinerWorker(ctx, a.StateManager, ts, m)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerPeerID(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error) {
|
||||
func (a *StateAPI) StateMinerPeerID(ctx context.Context, m address.Address, tsk types.TipSetKey) (peer.ID, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return "", xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return stmgr.GetMinerPeerID(ctx, a.StateManager, ts, m)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerPostState(ctx context.Context, actor address.Address, ts *types.TipSet) (*miner.PoStState, error) {
|
||||
func (a *StateAPI) StateMinerPostState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*miner.PoStState, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return stmgr.GetMinerPostState(ctx, a.StateManager, ts, actor)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerSectorSize(ctx context.Context, actor address.Address, ts *types.TipSet) (abi.SectorSize, error) {
|
||||
func (a *StateAPI) StateMinerSectorSize(ctx context.Context, actor address.Address, tsk types.TipSetKey) (abi.SectorSize, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return 0, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return stmgr.GetMinerSectorSize(ctx, a.StateManager, ts, actor)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerFaults(ctx context.Context, addr address.Address, ts *types.TipSet) ([]abi.SectorNumber, error) {
|
||||
func (a *StateAPI) StateMinerFaults(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]abi.SectorNumber, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return stmgr.GetMinerFaults(ctx, a.StateManager, ts, addr)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StatePledgeCollateral(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
|
||||
/*param, err := actors.SerializeParams(&actors.PledgeCollateralParams{Size: types.NewInt(0)})
|
||||
func (a *StateAPI) StatePledgeCollateral(ctx context.Context, tsk types.TipSetKey) (types.BigInt, error) {
|
||||
/*ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return types.EmptyInt, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
|
||||
param, err := actors.SerializeParams(&actors.PledgeCollateralParams{Size: types.NewInt(0)})
|
||||
if err != nil {
|
||||
return types.NewInt(0), err
|
||||
}
|
||||
@ -117,14 +155,23 @@ func (a *StateAPI) StatePledgeCollateral(ctx context.Context, ts *types.TipSet)
|
||||
}
|
||||
|
||||
return types.BigFromBytes(ret.Return), nil*/
|
||||
log.Error("TODO StatePledgeCollateral")
|
||||
return big.Zero(), nil
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*api.MethodCall, error) {
|
||||
func (a *StateAPI) StateCall(ctx context.Context, msg *types.Message, tsk types.TipSetKey) (*api.MethodCall, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return a.StateManager.Call(ctx, msg, ts)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateReplay(ctx context.Context, ts *types.TipSet, mc cid.Cid) (*api.ReplayResults, error) {
|
||||
func (a *StateAPI) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid.Cid) (*api.ReplayResults, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
m, r, err := a.StateManager.Replay(ctx, ts, mc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -157,7 +204,11 @@ func (a *StateAPI) stateForTs(ctx context.Context, ts *types.TipSet) (*state.Sta
|
||||
return state.LoadStateTree(cst, st)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
func (a *StateAPI) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
state, err := a.stateForTs(ctx, ts)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("computing tipset state failed: %w", err)
|
||||
@ -166,7 +217,11 @@ func (a *StateAPI) StateGetActor(ctx context.Context, actor address.Address, ts
|
||||
return state.GetActor(actor)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateLookupID(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
func (a *StateAPI) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
state, err := a.stateForTs(ctx, ts)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
@ -175,7 +230,11 @@ func (a *StateAPI) StateLookupID(ctx context.Context, addr address.Address, ts *
|
||||
return state.LookupID(addr)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*api.ActorState, error) {
|
||||
func (a *StateAPI) StateReadState(ctx context.Context, act *types.Actor, tsk types.TipSetKey) (*api.ActorState, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
state, err := a.stateForTs(ctx, ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -198,7 +257,11 @@ func (a *StateAPI) StateReadState(ctx context.Context, act *types.Actor, ts *typ
|
||||
}
|
||||
|
||||
// This is on StateAPI because miner.Miner requires this, and MinerAPI requires miner.Miner
|
||||
func (a *StateAPI) MinerCreateBlock(ctx context.Context, addr address.Address, parents *types.TipSet, ticket *types.Ticket, proof *types.EPostProof, msgs []*types.SignedMessage, height abi.ChainEpoch, ts uint64) (*types.BlockMsg, error) {
|
||||
func (a *StateAPI) MinerCreateBlock(ctx context.Context, addr address.Address, parentsTSK types.TipSetKey, ticket *types.Ticket, proof *types.EPostProof, msgs []*types.SignedMessage, height abi.ChainEpoch, ts uint64) (*types.BlockMsg, error) {
|
||||
parents, err := a.Chain.GetTipSetFromKey(parentsTSK)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", parentsTSK, err)
|
||||
}
|
||||
fblk, err := gen.MinerCreateBlock(ctx, a.StateManager, a.Wallet, addr, parents, ticket, proof, msgs, height, ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -230,26 +293,46 @@ func (a *StateAPI) StateWaitMsg(ctx context.Context, msg cid.Cid) (*api.MsgWait,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateGetReceipt(ctx context.Context, msg cid.Cid, ts *types.TipSet) (*types.MessageReceipt, error) {
|
||||
func (a *StateAPI) StateGetReceipt(ctx context.Context, msg cid.Cid, tsk types.TipSetKey) (*types.MessageReceipt, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return a.StateManager.GetReceipt(ctx, msg, ts)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateListMiners(ctx context.Context, ts *types.TipSet) ([]address.Address, error) {
|
||||
func (a *StateAPI) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return stmgr.ListMinerActors(ctx, a.StateManager, ts)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateListActors(ctx context.Context, ts *types.TipSet) ([]address.Address, error) {
|
||||
func (a *StateAPI) StateListActors(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return a.StateManager.ListAllActors(ctx, ts)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMarketBalance(ctx context.Context, addr address.Address, ts *types.TipSet) (api.MarketBalance, error) {
|
||||
func (a *StateAPI) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return api.MarketBalance{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return a.StateManager.MarketBalance(ctx, addr, ts)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMarketParticipants(ctx context.Context, ts *types.TipSet) (map[string]api.MarketBalance, error) {
|
||||
func (a *StateAPI) StateMarketParticipants(ctx context.Context, tsk types.TipSetKey) (map[string]api.MarketBalance, error) {
|
||||
out := map[string]api.MarketBalance{}
|
||||
|
||||
var state actors.StorageMarketState
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
if _, err := a.StateManager.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -291,10 +374,14 @@ func (a *StateAPI) StateMarketParticipants(ctx context.Context, ts *types.TipSet
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMarketDeals(ctx context.Context, ts *types.TipSet) (map[string]api.MarketDeal, error) {
|
||||
func (a *StateAPI) StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (map[string]api.MarketDeal, error) {
|
||||
out := map[string]api.MarketDeal{}
|
||||
|
||||
var state actors.StorageMarketState
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
if _, err := a.StateManager.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -331,7 +418,11 @@ func (a *StateAPI) StateMarketDeals(ctx context.Context, ts *types.TipSet) (map[
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, ts *types.TipSet) (*api.MarketDeal, error) {
|
||||
func (a *StateAPI) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return stmgr.GetStorageDeal(ctx, a.StateManager, dealId, ts)
|
||||
}
|
||||
|
||||
@ -386,11 +477,19 @@ func (a *StateAPI) StateChangedActors(ctx context.Context, old cid.Cid, new cid.
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerSectorCount(ctx context.Context, addr address.Address, ts *types.TipSet) (api.MinerSectors, error) {
|
||||
func (a *StateAPI) StateMinerSectorCount(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MinerSectors, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return api.MinerSectors{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return stmgr.SectorSetSizes(ctx, a.StateManager, addr, ts)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateListMessages(ctx context.Context, match *types.Message, ts *types.TipSet, toheight abi.ChainEpoch) ([]cid.Cid, error) {
|
||||
func (a *StateAPI) StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toheight abi.ChainEpoch) ([]cid.Cid, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
if ts == nil {
|
||||
ts = a.Chain.GetHeaviestTipSet()
|
||||
}
|
||||
@ -439,13 +538,18 @@ func (a *StateAPI) StateListMessages(ctx context.Context, match *types.Message,
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateCompute(ctx context.Context, height abi.ChainEpoch, msgs []*types.Message, ts *types.TipSet) (cid.Cid, error) {
|
||||
func (a *StateAPI) StateCompute(ctx context.Context, height abi.ChainEpoch, msgs []*types.Message, tsk types.TipSetKey) (cid.Cid, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return stmgr.ComputeState(ctx, a.StateManager, height, msgs, ts)
|
||||
}
|
||||
|
||||
func (a *StateAPI) MsigGetAvailableBalance(ctx context.Context, addr address.Address, ts *types.TipSet) (types.BigInt, error) {
|
||||
if ts == nil {
|
||||
ts = a.Chain.GetHeaviestTipSet()
|
||||
func (a *StateAPI) MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return types.EmptyInt, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
|
||||
var st samsig.State
|
||||
|
@ -88,3 +88,12 @@ func (a *SyncAPI) SyncMarkBad(ctx context.Context, bcid cid.Cid) error {
|
||||
a.Syncer.MarkBad(bcid)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *SyncAPI) SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error) {
|
||||
reason, ok := a.Syncer.CheckBadBlockCache(bcid)
|
||||
if !ok {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return reason, nil
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package impl
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"io"
|
||||
"mime"
|
||||
"net/http"
|
||||
@ -170,7 +171,7 @@ func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error
|
||||
}
|
||||
|
||||
func (sm *StorageMinerAPI) ActorSectorSize(ctx context.Context, addr address.Address) (abi.SectorSize, error) {
|
||||
return sm.Full.StateMinerSectorSize(ctx, addr, nil)
|
||||
return sm.Full.StateMinerSectorSize(ctx, addr, types.EmptyTSK)
|
||||
}
|
||||
|
||||
func (sm *StorageMinerAPI) PledgeSector(ctx context.Context) error {
|
||||
|
@ -10,6 +10,10 @@ import (
|
||||
"github.com/ipfs/go-blockservice"
|
||||
"github.com/ipfs/go-car"
|
||||
"github.com/ipfs/go-datastore"
|
||||
graphsync "github.com/ipfs/go-graphsync/impl"
|
||||
"github.com/ipfs/go-graphsync/ipldbridge"
|
||||
gsnet "github.com/ipfs/go-graphsync/network"
|
||||
"github.com/ipfs/go-graphsync/storeutil"
|
||||
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
"github.com/libp2p/go-libp2p-core/routing"
|
||||
@ -74,6 +78,15 @@ func ChainBlockservice(bs dtypes.ChainBlockstore, rem dtypes.ChainExchange) dtyp
|
||||
return blockservice.New(bs, rem)
|
||||
}
|
||||
|
||||
func ChainGraphsync(mctx helpers.MetricsCtx, lc fx.Lifecycle, ibs dtypes.ChainGCBlockstore, h host.Host) dtypes.ClientGraphsync {
|
||||
graphsyncNetwork := gsnet.NewFromLibp2pHost(h)
|
||||
ipldBridge := ipldbridge.NewIPLDBridge()
|
||||
loader := storeutil.LoaderForBlockstore(ibs)
|
||||
gs := graphsync.New(helpers.LifecycleCtx(mctx, lc), graphsyncNetwork, ipldBridge, loader, nil)
|
||||
|
||||
return gs
|
||||
}
|
||||
|
||||
func ChainStore(lc fx.Lifecycle, bs dtypes.ChainBlockstore, ds dtypes.MetadataDS, syscalls runtime.Syscalls) *store.ChainStore {
|
||||
chain := store.NewChainStore(bs, ds, syscalls)
|
||||
|
||||
|
@ -3,10 +3,12 @@ package modules
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"github.com/filecoin-project/lotus/api/apistruct"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/filecoin-project/lotus/api/apistruct"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/addrutil"
|
||||
@ -38,7 +40,8 @@ type jwtPayload struct {
|
||||
|
||||
func APISecret(keystore types.KeyStore, lr repo.LockedRepo) (*dtypes.APIAlg, error) {
|
||||
key, err := keystore.Get(JWTSecretName)
|
||||
if err != nil {
|
||||
|
||||
if errors.Is(err, types.ErrKeyInfoNotFound) {
|
||||
log.Warn("Generating new API secret")
|
||||
|
||||
sk, err := ioutil.ReadAll(io.LimitReader(rand.Reader, 32))
|
||||
@ -68,6 +71,8 @@ func APISecret(keystore types.KeyStore, lr repo.LockedRepo) (*dtypes.APIAlg, err
|
||||
if err := lr.SetAPIToken(cliToken); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if err != nil {
|
||||
return nil, xerrors.Errorf("could not get JWT Token: %w", err)
|
||||
}
|
||||
|
||||
return (*dtypes.APIAlg)(jwt.NewHS256(key.PrivateKey)), nil
|
||||
|
@ -24,6 +24,7 @@ type ChainGCLocker blockstore.GCLocker
|
||||
type ChainGCBlockstore blockstore.GCBlockstore
|
||||
type ChainExchange exchange.Interface
|
||||
type ChainBlockService bserv.BlockService
|
||||
type ChainGraphsync graphsync.GraphExchange
|
||||
|
||||
type ClientFilestore *filestore.Filestore
|
||||
type ClientBlockstore blockstore.Blockstore
|
||||
|
@ -47,7 +47,8 @@ func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (RawHost,
|
||||
libp2p.Peerstore(params.Peerstore),
|
||||
libp2p.NoListenAddrs,
|
||||
libp2p.Ping(true),
|
||||
libp2p.UserAgent("lotus-" + build.UserVersion)}
|
||||
libp2p.UserAgent("lotus-" + build.UserVersion),
|
||||
}
|
||||
for _, o := range params.Opts {
|
||||
opts = append(opts, o...)
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ func Security(enabled, preferTLS bool) interface{} {
|
||||
if !enabled {
|
||||
return func() (opts Libp2pOpts) {
|
||||
// TODO: shouldn't this be Errorf to guarantee visibility?
|
||||
log.Warnf(`Your IPFS node has been configured to run WITHOUT ENCRYPTED CONNECTIONS.
|
||||
log.Warnf(`Your lotus node has been configured to run WITHOUT ENCRYPTED CONNECTIONS.
|
||||
You will not be able to connect to any nodes configured to use encrypted connections`)
|
||||
opts.Opts = append(opts.Opts, libp2p.NoSecurity)
|
||||
return opts
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
inet "github.com/libp2p/go-libp2p-core/network"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||
"go.uber.org/fx"
|
||||
|
||||
@ -15,12 +16,16 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/blocksync"
|
||||
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||
"github.com/filecoin-project/lotus/chain/sub"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/peermgr"
|
||||
"github.com/filecoin-project/lotus/node/hello"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
"github.com/filecoin-project/lotus/node/modules/helpers"
|
||||
)
|
||||
|
||||
const BlocksTopic = "/fil/blocks"
|
||||
const MessagesTopic = "/fil/messages"
|
||||
|
||||
func RunHello(mctx helpers.MetricsCtx, lc fx.Lifecycle, h host.Host, svc *hello.Service) {
|
||||
h.SetStreamHandler(hello.ProtocolID, svc.HandleStream)
|
||||
|
||||
@ -45,25 +50,49 @@ func RunBlockSync(h host.Host, svc *blocksync.BlockSyncService) {
|
||||
h.SetStreamHandler(blocksync.BlockSyncProtocolID, svc.HandleStream)
|
||||
}
|
||||
|
||||
func HandleIncomingBlocks(mctx helpers.MetricsCtx, lc fx.Lifecycle, pubsub *pubsub.PubSub, s *chain.Syncer, h host.Host) {
|
||||
func HandleIncomingBlocks(mctx helpers.MetricsCtx, lc fx.Lifecycle, ps *pubsub.PubSub, s *chain.Syncer, h host.Host) {
|
||||
ctx := helpers.LifecycleCtx(mctx, lc)
|
||||
|
||||
blocksub, err := pubsub.Subscribe("/fil/blocks")
|
||||
blocksub, err := ps.Subscribe(BlocksTopic)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
v := sub.NewBlockValidator(func(p peer.ID) {
|
||||
ps.BlacklistPeer(p)
|
||||
h.ConnManager().TagPeer(p, "badblock", -1000)
|
||||
})
|
||||
|
||||
if err := ps.RegisterTopicValidator(BlocksTopic, v.Validate); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
go sub.HandleIncomingBlocks(ctx, blocksub, s, h.ConnManager())
|
||||
}
|
||||
|
||||
func HandleIncomingMessages(mctx helpers.MetricsCtx, lc fx.Lifecycle, pubsub *pubsub.PubSub, mpool *messagepool.MessagePool) {
|
||||
func HandleIncomingMessages(mctx helpers.MetricsCtx, lc fx.Lifecycle, ps *pubsub.PubSub, mpool *messagepool.MessagePool) {
|
||||
ctx := helpers.LifecycleCtx(mctx, lc)
|
||||
|
||||
msgsub, err := pubsub.Subscribe("/fil/messages")
|
||||
msgsub, err := ps.Subscribe(MessagesTopic)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
v := func(ctx context.Context, pid peer.ID, msg *pubsub.Message) bool {
|
||||
m, err := types.DecodeSignedMessage(msg.GetData())
|
||||
if err != nil {
|
||||
log.Errorf("got incorrectly formatted Message: %s", err)
|
||||
return false
|
||||
}
|
||||
|
||||
msg.ValidatorData = m
|
||||
return true
|
||||
}
|
||||
|
||||
if err := ps.RegisterTopicValidator(MessagesTopic, v); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
go sub.HandleIncomingMessages(ctx, mpool, msgsub)
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package modules
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"math"
|
||||
"reflect"
|
||||
|
||||
@ -74,7 +75,7 @@ func SectorBuilderConfig(storage []fs.PathConfig, threads uint, noprecommit, noc
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ssize, err := api.StateMinerSectorSize(context.TODO(), minerAddr, nil)
|
||||
ssize, err := api.StateMinerSectorSize(context.TODO(), minerAddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -113,7 +114,7 @@ func StorageMiner(mctx helpers.MetricsCtx, lc fx.Lifecycle, api api.FullNode, h
|
||||
|
||||
ctx := helpers.LifecycleCtx(mctx, lc)
|
||||
|
||||
worker, err := api.StateMinerWorker(ctx, maddr, nil)
|
||||
worker, err := api.StateMinerWorker(ctx, maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -346,7 +346,7 @@ func (fsr *fsLockedRepo) Get(name string) (types.KeyInfo, error) {
|
||||
}
|
||||
|
||||
if fstat.Mode()&0077 != 0 {
|
||||
return types.KeyInfo{}, xerrors.Errorf(kstrPermissionMsg, name, err)
|
||||
return types.KeyInfo{}, xerrors.Errorf(kstrPermissionMsg, name, fstat.Mode())
|
||||
}
|
||||
|
||||
file, err := os.Open(keyPath)
|
||||
|
52
scripts/build-bundle.sh
Executable file
52
scripts/build-bundle.sh
Executable file
@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
|
||||
ARCHS=(
|
||||
"darwin"
|
||||
"linux"
|
||||
)
|
||||
|
||||
REQUIRED=(
|
||||
"ipfs"
|
||||
"sha512sum"
|
||||
)
|
||||
for REQUIRE in "${REQUIRED[@]}"
|
||||
do
|
||||
command -v "${REQUIRE}" >/dev/null 2>&1 || echo >&2 "'${REQUIRE}' must be installed"
|
||||
done
|
||||
|
||||
mkdir bundle
|
||||
pushd bundle
|
||||
|
||||
BINARIES=(
|
||||
"lotus"
|
||||
"lotus-storage-miner"
|
||||
"lotus-seal-worker"
|
||||
)
|
||||
|
||||
export IPFS_PATH=`mktemp -d`
|
||||
ipfs init
|
||||
ipfs daemon &
|
||||
PID="$!"
|
||||
trap "kill -9 ${PID}" EXIT
|
||||
sleep 30
|
||||
|
||||
for ARCH in "${ARCHS[@]}"
|
||||
do
|
||||
mkdir -p "${ARCH}/lotus"
|
||||
pushd "${ARCH}"
|
||||
for BINARY in "${BINARIES[@]}"
|
||||
do
|
||||
cp "../../${ARCH}/${BINARY}" "lotus/"
|
||||
chmod +x "lotus/${BINARY}"
|
||||
done
|
||||
|
||||
tar -zcvf "../lotus_${CIRCLE_TAG}_${ARCH}-amd64.tar.gz" lotus
|
||||
popd
|
||||
rm -rf "${ARCH}"
|
||||
|
||||
sha512sum "lotus_${CIRCLE_TAG}_${ARCH}-amd64.tar.gz" | cut -d" " -f1 > "lotus_${CIRCLE_TAG}_${ARCH}-amd64.tar.gz.sha512"
|
||||
|
||||
ipfs add "lotus_${CIRCLE_TAG}_${ARCH}-amd64.tar.gz" | cut -d" " -f2 > "lotus_${CIRCLE_TAG}_${ARCH}-amd64.tar.gz.cid"
|
||||
done
|
||||
popd
|
@ -4,4 +4,4 @@ set -o xtrace
|
||||
|
||||
export TRUST_PARAMS=1
|
||||
|
||||
go run -tags=debug ./cmd/lotus-storage-miner init --actor=t0101 --genesis-miner --pre-sealed-sectors=~/.genesis-sectors
|
||||
go run -tags=debug ./cmd/lotus-storage-miner init --actor=t0101 --genesis-miner --pre-sealed-sectors=~/.genesis-sectors --pre-sealed-metadata=~/.genesis-sectors/pre-seal-t0101.json
|
||||
|
@ -86,12 +86,12 @@ mdt0111=$(mktemp -d)
|
||||
mdt0222=$(mktemp -d)
|
||||
mdt0333=$(mktemp -d)
|
||||
|
||||
env LOTUS_PATH="${ldt0111}" LOTUS_STORAGE_PATH="${mdt0111}" ./lotus-storage-miner init --genesis-miner --actor=t0111 --pre-sealed-sectors="${sdt0111}" --nosync=true --sector-size="${SECTOR_SIZE}" || true
|
||||
env LOTUS_PATH="${ldt0111}" LOTUS_STORAGE_PATH="${mdt0111}" ./lotus-storage-miner init --genesis-miner --actor=t0111 --pre-sealed-sectors="${sdt0111}" --pre-sealed-metadata="${sdt0111}/pre-seal-t0111.json" --nosync=true --sector-size="${SECTOR_SIZE}" || true
|
||||
env LOTUS_PATH="${ldt0111}" LOTUS_STORAGE_PATH="${mdt0111}" ./lotus-storage-miner run --nosync &
|
||||
mpid=$!
|
||||
|
||||
env LOTUS_PATH="${ldt0222}" LOTUS_STORAGE_PATH="${mdt0222}" ./lotus-storage-miner init --actor=t0222 --pre-sealed-sectors="${sdt0222}" --nosync=true --sector-size="${SECTOR_SIZE}" || true
|
||||
env LOTUS_PATH="${ldt0333}" LOTUS_STORAGE_PATH="${mdt0333}" ./lotus-storage-miner init --actor=t0333 --pre-sealed-sectors="${sdt0333}" --nosync=true --sector-size="${SECTOR_SIZE}" || true
|
||||
env LOTUS_PATH="${ldt0222}" LOTUS_STORAGE_PATH="${mdt0222}" ./lotus-storage-miner init --actor=t0222 --pre-sealed-sectors="${sdt0222}" --pre-sealed-metadata="${sdt0222}/pre-seal-t0222.json" --nosync=true --sector-size="${SECTOR_SIZE}" || true
|
||||
env LOTUS_PATH="${ldt0333}" LOTUS_STORAGE_PATH="${mdt0333}" ./lotus-storage-miner init --actor=t0333 --pre-sealed-sectors="${sdt0333}" --pre-sealed-metadata="${sdt0333}/pre-seal-t0333.json" --nosync=true --sector-size="${SECTOR_SIZE}" || true
|
||||
|
||||
kill $mpid
|
||||
wait $mpid
|
||||
|
94
scripts/publish-release.sh
Executable file
94
scripts/publish-release.sh
Executable file
@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
pushd bundle
|
||||
|
||||
# make sure we have a token set, api requests won't work otherwise
|
||||
if [ -z "${GITHUB_TOKEN}" ]; then
|
||||
echo "\${GITHUB_TOKEN} not set, publish failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
REQUIRED=(
|
||||
"jq"
|
||||
"curl"
|
||||
)
|
||||
for REQUIRE in "${REQUIRED[@]}"
|
||||
do
|
||||
command -v "${REQUIRE}" >/dev/null 2>&1 || echo >&2 "'${REQUIRE}' must be installed"
|
||||
done
|
||||
|
||||
#see if the release already exists by tag
|
||||
RELEASE_RESPONSE=`
|
||||
curl \
|
||||
--header "Authorization: token ${GITHUB_TOKEN}" \
|
||||
"https://api.github.com/repos/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/releases/tags/${CIRCLE_TAG}"
|
||||
`
|
||||
RELEASE_ID=`echo "${RELEASE_RESPONSE}" | jq '.id'`
|
||||
|
||||
if [ "${RELEASE_ID}" = "null" ]; then
|
||||
echo "creating release"
|
||||
|
||||
RELEASE_DATA="{
|
||||
\"tag_name\": \"${CIRCLE_TAG}\",
|
||||
\"target_commitish\": \"${CIRCLE_SHA1}\",
|
||||
\"name\": \"${CIRCLE_TAG}\",
|
||||
\"body\": \"\",
|
||||
\"prerelease\": false
|
||||
}"
|
||||
|
||||
# create it if it doesn't exist yet
|
||||
RELEASE_RESPONSE=`
|
||||
curl \
|
||||
--request POST \
|
||||
--header "Authorization: token ${GITHUB_TOKEN}" \
|
||||
--header "Content-Type: application/json" \
|
||||
--data "${RELEASE_DATA}" \
|
||||
"https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/${CIRCLE_PROJECT_REPONAME}/releases"
|
||||
`
|
||||
else
|
||||
echo "release already exists"
|
||||
fi
|
||||
|
||||
RELEASE_UPLOAD_URL=`echo "${RELEASE_RESPONSE}" | jq -r '.upload_url' | cut -d'{' -f1`
|
||||
|
||||
bundles=(
|
||||
"lotus_${CIRCLE_TAG}_linux-amd64.tar.gz"
|
||||
"lotus_${CIRCLE_TAG}_linux-amd64.tar.gz.cid"
|
||||
"lotus_${CIRCLE_TAG}_linux-amd64.tar.gz.sha512"
|
||||
"lotus_${CIRCLE_TAG}_darwin-amd64.tar.gz"
|
||||
"lotus_${CIRCLE_TAG}_darwin-amd64.tar.gz.cid"
|
||||
"lotus_${CIRCLE_TAG}_darwin-amd64.tar.gz.sha512"
|
||||
)
|
||||
for RELEASE_FILE in "${bundles[@]}"
|
||||
do
|
||||
echo "Uploading release bundle: ${RELEASE_FILE}"
|
||||
curl \
|
||||
--request POST \
|
||||
--header "Authorization: token ${GITHUB_TOKEN}" \
|
||||
--header "Content-Type: application/octet-stream" \
|
||||
--data-binary "@${RELEASE_FILE}" \
|
||||
"$RELEASE_UPLOAD_URL?name=$(basename "${RELEASE_FILE}")"
|
||||
|
||||
echo "Release bundle uploaded: ${RELEASE_FILE}"
|
||||
done
|
||||
|
||||
popd
|
||||
|
||||
miscellaneous=(
|
||||
"README.md"
|
||||
"LICENSE-MIT"
|
||||
"LICENSE-APACHE"
|
||||
)
|
||||
for MISC in "${miscellaneous[@]}"
|
||||
do
|
||||
echo "Uploading release bundle: ${MISC}"
|
||||
curl \
|
||||
--request POST \
|
||||
--header "Authorization: token ${GITHUB_TOKEN}" \
|
||||
--header "Content-Type: application/octet-stream" \
|
||||
--data-binary "@${MISC}" \
|
||||
"$RELEASE_UPLOAD_URL?name=$(basename "${MISC}")"
|
||||
|
||||
echo "Release bundle uploaded: ${MISC}"
|
||||
done
|
@ -97,7 +97,7 @@ func (s *FPoStScheduler) checkFaults(ctx context.Context, ssi sectorbuilder.Sort
|
||||
declaredFaults := map[abi.SectorNumber]struct{}{}
|
||||
|
||||
{
|
||||
chainFaults, err := s.api.StateMinerFaults(ctx, s.actor, nil)
|
||||
chainFaults, err := s.api.StateMinerFaults(ctx, s.actor, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("checking on-chain faults: %w", err)
|
||||
}
|
||||
@ -210,7 +210,7 @@ func (s *FPoStScheduler) runPost(ctx context.Context, eps abi.ChainEpoch, ts *ty
|
||||
}
|
||||
|
||||
func (s *FPoStScheduler) sortedSectorInfo(ctx context.Context, ts *types.TipSet) (sectorbuilder.SortedPublicSectorInfo, error) {
|
||||
sset, err := s.api.StateMinerProvingSet(ctx, s.actor, ts)
|
||||
sset, err := s.api.StateMinerProvingSet(ctx, s.actor, ts.Key())
|
||||
if err != nil {
|
||||
return sectorbuilder.SortedPublicSectorInfo{}, xerrors.Errorf("failed to get proving set for miner (tsH: %d): %w", ts.Height(), err)
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ func (s *FPoStScheduler) abortActivePoSt() {
|
||||
}
|
||||
|
||||
func (s *FPoStScheduler) shouldFallbackPost(ctx context.Context, ts *types.TipSet) (abi.ChainEpoch, bool, error) {
|
||||
ps, err := s.api.StateMinerPostState(ctx, s.actor, ts)
|
||||
ps, err := s.api.StateMinerPostState(ctx, s.actor, ts.Key())
|
||||
if err != nil {
|
||||
return 0, false, xerrors.Errorf("getting ElectionPeriodStart: %w", err)
|
||||
}
|
||||
|
@ -43,24 +43,24 @@ type Miner struct {
|
||||
|
||||
type storageMinerApi interface {
|
||||
// Call a read only method on actors (no interaction with the chain required)
|
||||
StateCall(context.Context, *types.Message, *types.TipSet) (*api.MethodCall, error)
|
||||
StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error)
|
||||
StateMinerPostState(ctx context.Context, actor address.Address, ts *types.TipSet) (*miner.PoStState, error)
|
||||
StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error)
|
||||
StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error)
|
||||
StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (abi.SectorSize, error)
|
||||
StateCall(context.Context, *types.Message, types.TipSetKey) (*api.MethodCall, error)
|
||||
StateMinerWorker(context.Context, address.Address, types.TipSetKey) (address.Address, error)
|
||||
StateMinerPostState(ctx context.Context, actor address.Address, ts types.TipSetKey) (*miner.PoStState, error)
|
||||
StateMinerSectors(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error)
|
||||
StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error)
|
||||
StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error)
|
||||
StateWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error) // TODO: removeme eventually
|
||||
StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error)
|
||||
StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error)
|
||||
StateMarketStorageDeal(context.Context, abi.DealID, *types.TipSet) (*api.MarketDeal, error)
|
||||
StateMinerFaults(context.Context, address.Address, *types.TipSet) ([]abi.SectorNumber, error)
|
||||
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
||||
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
|
||||
StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error)
|
||||
StateMinerFaults(context.Context, address.Address, types.TipSetKey) ([]abi.SectorNumber, error)
|
||||
|
||||
MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error)
|
||||
|
||||
ChainHead(context.Context) (*types.TipSet, error)
|
||||
ChainHead(context.Context) (types.TipSetKey, error)
|
||||
ChainNotify(context.Context) (<-chan []*store.HeadChange, error)
|
||||
ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
|
||||
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error)
|
||||
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error)
|
||||
ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error)
|
||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||
|
@ -49,7 +49,7 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error {
|
||||
}
|
||||
continue
|
||||
}
|
||||
deal, err := api.StateMarketStorageDeal(ctx, *piece.DealID, nil)
|
||||
deal, err := api.StateMarketStorageDeal(ctx, *piece.DealID, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return &ErrApi{xerrors.Errorf("getting deal %d for piece %d: %w", piece.DealID, i, err)}
|
||||
}
|
||||
@ -83,7 +83,7 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se
|
||||
return &ErrApi{xerrors.Errorf("getting chain head: %w", err)}
|
||||
}
|
||||
|
||||
ssize, err := api.StateMinerSectorSize(ctx, maddr, head)
|
||||
ssize, err := api.StateMinerSectorSize(ctx, maddr, head.Key())
|
||||
if err != nil {
|
||||
return &ErrApi{err}
|
||||
}
|
||||
@ -105,7 +105,7 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se
|
||||
Method: builtin.MethodsMarket.ComputeDataCommitment,
|
||||
Params: ccparams,
|
||||
}
|
||||
r, err := api.StateCall(ctx, ccmt, nil)
|
||||
r, err := api.StateCall(ctx, ccmt, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return &ErrApi{xerrors.Errorf("calling ComputeDataCommitment: %w", err)}
|
||||
}
|
||||
|
@ -32,23 +32,23 @@ type TicketFn func(context.Context) (*sectorbuilder.SealTicket, error)
|
||||
|
||||
type sealingApi interface { // TODO: trim down
|
||||
// Call a read only method on actors (no interaction with the chain required)
|
||||
StateCall(context.Context, *types.Message, *types.TipSet) (*api.MethodCall, error)
|
||||
StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error)
|
||||
StateMinerPostState(ctx context.Context, actor address.Address, ts *types.TipSet) (*miner.PoStState, error)
|
||||
StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error)
|
||||
StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error)
|
||||
StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (abi.SectorSize, error)
|
||||
StateCall(context.Context, *types.Message, types.TipSetKey) (*api.MethodCall, error)
|
||||
StateMinerWorker(context.Context, address.Address, types.TipSetKey) (address.Address, error)
|
||||
StateMinerPostState(ctx context.Context, actor address.Address, ts types.TipSetKey) (*miner.PoStState, error)
|
||||
StateMinerSectors(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error)
|
||||
StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error)
|
||||
StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error)
|
||||
StateWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error) // TODO: removeme eventually
|
||||
StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error)
|
||||
StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error)
|
||||
StateMarketStorageDeal(context.Context, abi.DealID, *types.TipSet) (*api.MarketDeal, error)
|
||||
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
||||
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
|
||||
StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error)
|
||||
|
||||
MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error)
|
||||
|
||||
ChainHead(context.Context) (*types.TipSet, error)
|
||||
ChainHead(context.Context) (types.TipSetKey, error)
|
||||
ChainNotify(context.Context) (<-chan []*store.HeadChange, error)
|
||||
ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
|
||||
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error)
|
||||
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error)
|
||||
ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error)
|
||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/api/apibstore"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/statemachine"
|
||||
)
|
||||
|
||||
@ -33,7 +34,7 @@ func failedCooldown(ctx statemachine.Context, sector SectorInfo) error {
|
||||
}
|
||||
|
||||
func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) (*miner.SectorPreCommitOnChainInfo, bool) {
|
||||
act, err := m.api.StateGetActor(ctx.Context(), m.maddr, nil)
|
||||
act, err := m.api.StateGetActor(ctx.Context(), m.maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorID, err)
|
||||
return nil, true
|
||||
|
@ -137,7 +137,7 @@ func RecordTipsetPoints(ctx context.Context, api api.FullNode, pl *PointList, ti
|
||||
}
|
||||
|
||||
func RecordTipsetStatePoints(ctx context.Context, api api.FullNode, pl *PointList, tipset *types.TipSet) error {
|
||||
pc, err := api.StatePledgeCollateral(ctx, tipset)
|
||||
pc, err := api.StatePledgeCollateral(ctx, tipset.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -159,7 +159,7 @@ func RecordTipsetStatePoints(ctx context.Context, api api.FullNode, pl *PointLis
|
||||
p = NewPoint("network.balance", netBalFilFloat)
|
||||
pl.AddPoint(p)
|
||||
|
||||
power, err := api.StateMinerPower(ctx, address.Address{}, tipset)
|
||||
power, err := api.StateMinerPower(ctx, address.Address{}, tipset.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -167,9 +167,9 @@ func RecordTipsetStatePoints(ctx context.Context, api api.FullNode, pl *PointLis
|
||||
p = NewPoint("chain.power", power.TotalPower.Int64())
|
||||
pl.AddPoint(p)
|
||||
|
||||
miners, err := api.StateListMiners(ctx, tipset)
|
||||
miners, err := api.StateListMiners(ctx, tipset.Key())
|
||||
for _, miner := range miners {
|
||||
power, err := api.StateMinerPower(ctx, miner, tipset)
|
||||
power, err := api.StateMinerPower(ctx, miner, tipset.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -218,7 +218,7 @@ func RecordTipsetMessagesPoints(ctx context.Context, api api.FullNode, pl *Point
|
||||
p = NewPoint("chain.message_size", len(bs))
|
||||
pl.AddPoint(p)
|
||||
|
||||
actor, err := api.StateGetActor(ctx, msg.Message.To, tipset)
|
||||
actor, err := api.StateGetActor(ctx, msg.Message.To, tipset.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user