Compare commits
58
Commits
interop.6.16.0
...
v0.4.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ffa7be86fe | ||
|
|
c41c210ced | ||
|
|
b99b8f55f6 | ||
|
|
c0a50a2143 | ||
|
|
382734b057 | ||
|
|
90fbbea372 | ||
|
|
55d9ad0b55 | ||
|
|
e5e5d0d9e4 | ||
|
|
324b659d33 | ||
|
|
edcf899be1 | ||
|
|
2bf781d591 | ||
|
|
cc179c5270 | ||
|
|
b417725e3e | ||
|
|
c02d8225a8 | ||
|
|
659f570cfc | ||
|
|
c7e470bd5e | ||
|
|
fe4efa0e0e | ||
|
|
02234d00b7 | ||
|
|
bef5bfcbb6 | ||
|
|
290512ee68 | ||
|
|
d129d6eada | ||
|
|
5c5a3f2264 | ||
|
|
d4644a28c1 | ||
|
|
d66c70d1e6 | ||
|
|
b91e7a9860 | ||
|
|
fcdfda8ba2 | ||
|
|
2800fd919b | ||
|
|
512bbb99ca | ||
|
|
ed5b74b1ae | ||
|
|
791dff5a87 | ||
|
|
402cd8be19 | ||
|
|
bdcb1e3592 | ||
|
|
e60dd219dc | ||
|
|
9d7be5dcbf | ||
|
|
70e964d9f9 | ||
|
|
673a643184 | ||
|
|
2761872ea7 | ||
|
|
fc7195f19a | ||
|
|
8b8bb5e833 | ||
|
|
5d4f1bb3f1 | ||
|
|
139c3297ab | ||
|
|
2676892886 | ||
|
|
5acf5bf102 | ||
|
|
ec693008d7 | ||
|
|
4ba1846c11 | ||
|
|
5eceed81e1 | ||
|
|
8b725b4b8c | ||
|
|
6253c39100 | ||
|
|
b845013836 | ||
|
|
9690bc9c63 | ||
|
|
c6a8fe16c6 | ||
|
|
ec9a334f93 | ||
|
|
35d9de6b6e | ||
|
|
4d0df5d599 | ||
|
|
7fd082e941 | ||
|
|
9d17e0be9d | ||
|
|
f8c4b64782 | ||
|
|
01c4726fd5 |
+8
-2
@@ -13,11 +13,13 @@ import (
|
||||
)
|
||||
|
||||
type Common interface {
|
||||
// Auth
|
||||
|
||||
// MethodGroup: Auth
|
||||
|
||||
AuthVerify(ctx context.Context, token string) ([]auth.Permission, error)
|
||||
AuthNew(ctx context.Context, perms []auth.Permission) ([]byte, error)
|
||||
|
||||
// network
|
||||
// MethodGroup: Net
|
||||
|
||||
NetConnectedness(context.Context, peer.ID) (network.Connectedness, error)
|
||||
NetPeers(context.Context) ([]peer.AddrInfo, error)
|
||||
@@ -27,6 +29,8 @@ type Common interface {
|
||||
NetFindPeer(context.Context, peer.ID) (peer.AddrInfo, error)
|
||||
NetPubsubScores(context.Context) ([]PubsubScore, error)
|
||||
|
||||
// MethodGroup: Common
|
||||
|
||||
// ID returns peerID of libp2p node backing this API
|
||||
ID(context.Context) (peer.ID, error)
|
||||
|
||||
@@ -38,6 +42,8 @@ type Common interface {
|
||||
|
||||
// trigger graceful shutdown
|
||||
Shutdown(context.Context) error
|
||||
|
||||
Closing(context.Context) (<-chan struct{}, error)
|
||||
}
|
||||
|
||||
// Version provides various build-time information
|
||||
|
||||
+73
-5
@@ -35,26 +35,71 @@ type FullNode interface {
|
||||
// ChainNotify returns channel with chain head updates
|
||||
// First message is guaranteed to be of len == 1, and type == 'current'
|
||||
ChainNotify(context.Context) (<-chan []*HeadChange, error)
|
||||
|
||||
// ChainHead returns the current head of the chain
|
||||
ChainHead(context.Context) (*types.TipSet, error)
|
||||
|
||||
// ChainGetRandomness is used to sample the chain for randomness
|
||||
ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
|
||||
|
||||
// ChainGetBlock returns the block specified by the given CID
|
||||
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
|
||||
ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error)
|
||||
ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error)
|
||||
ChainGetParentReceipts(context.Context, cid.Cid) ([]*types.MessageReceipt, error)
|
||||
ChainGetParentMessages(context.Context, cid.Cid) ([]Message, error)
|
||||
|
||||
// ChainGetBlockMessages returns messages stored in the specified block
|
||||
ChainGetBlockMessages(ctx context.Context, blockCid cid.Cid) (*BlockMessages, error)
|
||||
|
||||
// ChainGetParentReceipts returns receipts for messages in parent tipset of
|
||||
// the specified block
|
||||
ChainGetParentReceipts(ctx context.Context, blockCid cid.Cid) ([]*types.MessageReceipt, error)
|
||||
|
||||
// ChainGetParentReceipts returns messages stored in parent tipset of the
|
||||
// specified block
|
||||
ChainGetParentMessages(ctx context.Context, blockCid cid.Cid) ([]Message, error)
|
||||
|
||||
// ChainGetTipSetByHeight looks back for a tipset at the specified epoch.
|
||||
// If there are no blocks at the specified epoch, a tipset at higher epoch
|
||||
// will be returned
|
||||
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error)
|
||||
|
||||
// ChainReadObj reads ipld nodes referenced by the specified CID from chain
|
||||
// blockstore and returns raw bytes
|
||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||
|
||||
// ChainHasObj checks if a given CID exists in the chain blockstore
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||
ChainStatObj(context.Context, cid.Cid, cid.Cid) (ObjStat, error)
|
||||
|
||||
// ChainSetHead forcefully sets current chain head. Use with caution
|
||||
ChainSetHead(context.Context, types.TipSetKey) error
|
||||
|
||||
// ChainGetGenesis returns the genesis tipset
|
||||
ChainGetGenesis(context.Context) (*types.TipSet, error)
|
||||
|
||||
// ChainTipSetWeight computes weight for the specified tipset
|
||||
ChainTipSetWeight(context.Context, types.TipSetKey) (types.BigInt, error)
|
||||
ChainGetNode(ctx context.Context, p string) (*IpldObject, error)
|
||||
|
||||
// ChainGetMessage reads a message referenced by the specified CID from the
|
||||
// chain blockstore
|
||||
ChainGetMessage(context.Context, cid.Cid) (*types.Message, error)
|
||||
|
||||
// ChainGetPath returns a set of revert/apply operations needed to get from
|
||||
// one tipset to another, for example:
|
||||
//```
|
||||
// to
|
||||
// ^
|
||||
// from tAA
|
||||
// ^ ^
|
||||
// tBA tAB
|
||||
// ^---*--^
|
||||
// ^
|
||||
// tRR
|
||||
//```
|
||||
// Would return `[revert(tBA), apply(tAB), apply(tAA)]`
|
||||
ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*HeadChange, error)
|
||||
|
||||
// ChainExport returns a stream of bytes with CAR dump of chain data
|
||||
ChainExport(context.Context, types.TipSetKey) (<-chan []byte, error)
|
||||
|
||||
// MethodGroup: Sync
|
||||
@@ -63,23 +108,45 @@ type FullNode interface {
|
||||
|
||||
// SyncState returns the current status of the lotus sync system
|
||||
SyncState(context.Context) (*SyncState, error)
|
||||
|
||||
// SyncSubmitBlock can be used to submit a newly created block to the
|
||||
// network through this node
|
||||
SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error
|
||||
|
||||
// SyncIncomingBlocks returns a channel streaming incoming, potentially not
|
||||
// yet synced block headers.
|
||||
SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error)
|
||||
|
||||
// SyncMarkBad marks a blocks as bad, meaning that it won't ever by synced.
|
||||
// Use with extreme caution
|
||||
SyncMarkBad(ctx context.Context, bcid cid.Cid) error
|
||||
|
||||
// SyncCheckBad checks if a block was marked as bad, and if it was, returns
|
||||
// the reason
|
||||
SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error)
|
||||
|
||||
// MethodGroup: Mpool
|
||||
// The Mpool methods are for interacting with the message pool. The message pool
|
||||
// manages all incoming and outgoing 'messages' going over the network.
|
||||
|
||||
// MpoolPending returns pending mempool messages
|
||||
MpoolPending(context.Context, types.TipSetKey) ([]*types.SignedMessage, error)
|
||||
|
||||
// MpoolPush pushes a signed message to mempool
|
||||
MpoolPush(context.Context, *types.SignedMessage) (cid.Cid, error)
|
||||
MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) // get nonce, sign, push
|
||||
|
||||
// MpoolPushMessage atomically assigns a nonce, signs, and pushes a message
|
||||
// to mempool
|
||||
MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error)
|
||||
|
||||
// MpoolGetNonce gets next nonce for the specified sender.
|
||||
// Note that this method may not be atomic. Use MpoolPushMessage instead
|
||||
MpoolGetNonce(context.Context, address.Address) (uint64, error)
|
||||
MpoolSub(context.Context) (<-chan MpoolUpdate, error)
|
||||
MpoolEstimateGasPrice(context.Context, uint64, address.Address, int64, types.TipSetKey) (types.BigInt, error)
|
||||
|
||||
// MpoolEstimateGasPrice estimates what gas price should be used for a
|
||||
// message to have high likelihood of inclusion in `nblocksincl` epochs
|
||||
MpoolEstimateGasPrice(ctx context.Context, nblocksincl uint64, sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error)
|
||||
|
||||
// MethodGroup: Miner
|
||||
|
||||
@@ -118,6 +185,7 @@ type FullNode interface {
|
||||
ClientListDeals(ctx context.Context) ([]DealInfo, error)
|
||||
ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error)
|
||||
ClientFindData(ctx context.Context, root cid.Cid) ([]QueryOffer, error)
|
||||
ClientMinerQueryOffer(ctx context.Context, root cid.Cid, miner address.Address) (QueryOffer, error)
|
||||
ClientRetrieve(ctx context.Context, order RetrievalOrder, ref *FileRef) error
|
||||
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error)
|
||||
ClientCalcCommP(ctx context.Context, inpath string, miner address.Address) (*CommPRet, error)
|
||||
|
||||
+2
-1
@@ -50,7 +50,8 @@ type StorageMiner interface {
|
||||
MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error
|
||||
MarketListDeals(ctx context.Context) ([]storagemarket.StorageDeal, error)
|
||||
MarketListIncompleteDeals(ctx context.Context) ([]storagemarket.MinerDeal, error)
|
||||
MarketSetPrice(context.Context, types.BigInt) error
|
||||
MarketSetAsk(ctx context.Context, price types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error
|
||||
MarketGetAsk(ctx context.Context) (*storagemarket.SignedStorageAsk, error)
|
||||
|
||||
DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error
|
||||
DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error)
|
||||
|
||||
+33
-18
@@ -50,7 +50,8 @@ type CommonStruct struct {
|
||||
LogList func(context.Context) ([]string, error) `perm:"write"`
|
||||
LogSetLevel func(context.Context, string, string) error `perm:"write"`
|
||||
|
||||
Shutdown func(context.Context) error `perm:"admin"`
|
||||
Shutdown func(context.Context) error `perm:"admin"`
|
||||
Closing func(context.Context) (<-chan struct{}, error) `perm:"read"`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,17 +109,18 @@ type FullNodeStruct struct {
|
||||
WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"`
|
||||
WalletDelete func(context.Context, address.Address) error `perm:"write"`
|
||||
|
||||
ClientImport func(ctx context.Context, ref api.FileRef) (cid.Cid, error) `perm:"admin"`
|
||||
ClientListImports func(ctx context.Context) ([]api.Import, error) `perm:"write"`
|
||||
ClientHasLocal func(ctx context.Context, root cid.Cid) (bool, error) `perm:"write"`
|
||||
ClientFindData func(ctx context.Context, root cid.Cid) ([]api.QueryOffer, error) `perm:"read"`
|
||||
ClientStartDeal func(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) `perm:"admin"`
|
||||
ClientGetDealInfo func(context.Context, cid.Cid) (*api.DealInfo, error) `perm:"read"`
|
||||
ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"`
|
||||
ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error `perm:"admin"`
|
||||
ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) `perm:"read"`
|
||||
ClientCalcCommP func(ctx context.Context, inpath string, miner address.Address) (*api.CommPRet, error) `perm:"read"`
|
||||
ClientGenCar func(ctx context.Context, ref api.FileRef, outpath string) error `perm:"write"`
|
||||
ClientImport func(ctx context.Context, ref api.FileRef) (cid.Cid, error) `perm:"admin"`
|
||||
ClientListImports func(ctx context.Context) ([]api.Import, error) `perm:"write"`
|
||||
ClientHasLocal func(ctx context.Context, root cid.Cid) (bool, error) `perm:"write"`
|
||||
ClientFindData func(ctx context.Context, root cid.Cid) ([]api.QueryOffer, error) `perm:"read"`
|
||||
ClientMinerQueryOffer func(ctx context.Context, root cid.Cid, miner address.Address) (api.QueryOffer, error) `perm:"read"`
|
||||
ClientStartDeal func(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) `perm:"admin"`
|
||||
ClientGetDealInfo func(context.Context, cid.Cid) (*api.DealInfo, error) `perm:"read"`
|
||||
ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"`
|
||||
ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error `perm:"admin"`
|
||||
ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) `perm:"read"`
|
||||
ClientCalcCommP func(ctx context.Context, inpath string, miner address.Address) (*api.CommPRet, error) `perm:"read"`
|
||||
ClientGenCar func(ctx context.Context, ref api.FileRef, outpath string) error `perm:"write"`
|
||||
|
||||
StateNetworkName func(context.Context) (dtypes.NetworkName, error) `perm:"read"`
|
||||
StateMinerSectors func(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
|
||||
@@ -192,10 +194,11 @@ type StorageMinerStruct struct {
|
||||
|
||||
MiningBase func(context.Context) (*types.TipSet, error) `perm:"read"`
|
||||
|
||||
MarketImportDealData func(context.Context, cid.Cid, string) error `perm:"write"`
|
||||
MarketListDeals func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"`
|
||||
MarketListIncompleteDeals func(ctx context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"`
|
||||
MarketSetPrice func(context.Context, types.BigInt) error `perm:"admin"`
|
||||
MarketImportDealData func(context.Context, cid.Cid, string) error `perm:"write"`
|
||||
MarketListDeals func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"`
|
||||
MarketListIncompleteDeals func(ctx context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"`
|
||||
MarketSetAsk func(ctx context.Context, price types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error `perm:"admin"`
|
||||
MarketGetAsk func(ctx context.Context) (*storagemarket.SignedStorageAsk, error) `perm:"read"`
|
||||
|
||||
PledgeSector func(context.Context) error `perm:"write"`
|
||||
|
||||
@@ -313,6 +316,10 @@ func (c *CommonStruct) Shutdown(ctx context.Context) error {
|
||||
return c.Internal.Shutdown(ctx)
|
||||
}
|
||||
|
||||
func (c *CommonStruct) Closing(ctx context.Context) (<-chan struct{}, error) {
|
||||
return c.Internal.Closing(ctx)
|
||||
}
|
||||
|
||||
// FullNodeStruct
|
||||
|
||||
func (c *FullNodeStruct) ClientListImports(ctx context.Context) ([]api.Import, error) {
|
||||
@@ -331,6 +338,10 @@ func (c *FullNodeStruct) ClientFindData(ctx context.Context, root cid.Cid) ([]ap
|
||||
return c.Internal.ClientFindData(ctx, root)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ClientMinerQueryOffer(ctx context.Context, root cid.Cid, miner address.Address) (api.QueryOffer, error) {
|
||||
return c.Internal.ClientMinerQueryOffer(ctx, root, miner)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ClientStartDeal(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) {
|
||||
return c.Internal.ClientStartDeal(ctx, params)
|
||||
}
|
||||
@@ -841,8 +852,12 @@ func (c *StorageMinerStruct) MarketListIncompleteDeals(ctx context.Context) ([]s
|
||||
return c.Internal.MarketListIncompleteDeals(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) MarketSetPrice(ctx context.Context, p types.BigInt) error {
|
||||
return c.Internal.MarketSetPrice(ctx, p)
|
||||
func (c *StorageMinerStruct) MarketSetAsk(ctx context.Context, price types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error {
|
||||
return c.Internal.MarketSetAsk(ctx, price, duration, minPieceSize, maxPieceSize)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) MarketGetAsk(ctx context.Context) (*storagemarket.SignedStorageAsk, error) {
|
||||
return c.Internal.MarketGetAsk(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error {
|
||||
|
||||
+44
-19
@@ -73,9 +73,13 @@ func init() {
|
||||
|
||||
addExample(bitfield.NewFromSet([]uint64{5}))
|
||||
addExample(abi.RegisteredSealProof_StackedDrg32GiBV1)
|
||||
addExample(abi.RegisteredPoStProof_StackedDrgWindow32GiBV1)
|
||||
addExample(abi.ChainEpoch(10101))
|
||||
addExample(crypto.SigTypeBLS)
|
||||
addExample(int64(9))
|
||||
addExample(12.3)
|
||||
addExample(123)
|
||||
addExample(uintptr(0))
|
||||
addExample(abi.MethodNum(1))
|
||||
addExample(exitcode.ExitCode(0))
|
||||
addExample(crypto.DomainSeparationTag_ElectionProofProduction)
|
||||
@@ -94,17 +98,17 @@ func init() {
|
||||
addExample(api.PCHInbound)
|
||||
addExample(time.Minute)
|
||||
addExample(&types.ExecutionTrace{
|
||||
Msg: exampleValue(reflect.TypeOf(&types.Message{})).(*types.Message),
|
||||
MsgRct: exampleValue(reflect.TypeOf(&types.MessageReceipt{})).(*types.MessageReceipt),
|
||||
Msg: exampleValue(reflect.TypeOf(&types.Message{}), nil).(*types.Message),
|
||||
MsgRct: exampleValue(reflect.TypeOf(&types.MessageReceipt{}), nil).(*types.MessageReceipt),
|
||||
})
|
||||
addExample(map[string]types.Actor{
|
||||
"t01236": exampleValue(reflect.TypeOf(types.Actor{})).(types.Actor),
|
||||
"t01236": exampleValue(reflect.TypeOf(types.Actor{}), nil).(types.Actor),
|
||||
})
|
||||
addExample(map[string]api.MarketDeal{
|
||||
"t026363": exampleValue(reflect.TypeOf(api.MarketDeal{})).(api.MarketDeal),
|
||||
"t026363": exampleValue(reflect.TypeOf(api.MarketDeal{}), nil).(api.MarketDeal),
|
||||
})
|
||||
addExample(map[string]api.MarketBalance{
|
||||
"t026363": exampleValue(reflect.TypeOf(api.MarketBalance{})).(api.MarketBalance),
|
||||
"t026363": exampleValue(reflect.TypeOf(api.MarketBalance{}), nil).(api.MarketBalance),
|
||||
})
|
||||
|
||||
maddr, err := multiaddr.NewMultiaddr("/ip4/52.36.61.156/tcp/1347/p2p/12D3KooWFETiESTf1v4PGUvtnxMAcEFMzLZbJGg4tjWfGEimYior")
|
||||
@@ -117,7 +121,7 @@ func init() {
|
||||
|
||||
}
|
||||
|
||||
func exampleValue(t reflect.Type) interface{} {
|
||||
func exampleValue(t, parent reflect.Type) interface{} {
|
||||
v, ok := ExampleValues[t]
|
||||
if ok {
|
||||
return v
|
||||
@@ -126,25 +130,25 @@ func exampleValue(t reflect.Type) interface{} {
|
||||
switch t.Kind() {
|
||||
case reflect.Slice:
|
||||
out := reflect.New(t).Elem()
|
||||
reflect.Append(out, reflect.ValueOf(exampleValue(t.Elem())))
|
||||
reflect.Append(out, reflect.ValueOf(exampleValue(t.Elem(), t)))
|
||||
return out.Interface()
|
||||
case reflect.Chan:
|
||||
return exampleValue(t.Elem())
|
||||
return exampleValue(t.Elem(), nil)
|
||||
case reflect.Struct:
|
||||
es := exampleStruct(t)
|
||||
es := exampleStruct(t, parent)
|
||||
v := reflect.ValueOf(es).Elem().Interface()
|
||||
ExampleValues[t] = v
|
||||
return v
|
||||
case reflect.Array:
|
||||
out := reflect.New(t).Elem()
|
||||
for i := 0; i < t.Len(); i++ {
|
||||
out.Index(i).Set(reflect.ValueOf(exampleValue(t.Elem())))
|
||||
out.Index(i).Set(reflect.ValueOf(exampleValue(t.Elem(), t)))
|
||||
}
|
||||
return out.Interface()
|
||||
|
||||
case reflect.Ptr:
|
||||
if t.Elem().Kind() == reflect.Struct {
|
||||
es := exampleStruct(t.Elem())
|
||||
es := exampleStruct(t.Elem(), t)
|
||||
//ExampleValues[t] = es
|
||||
return es
|
||||
}
|
||||
@@ -155,12 +159,15 @@ func exampleValue(t reflect.Type) interface{} {
|
||||
panic(fmt.Sprintf("No example value for type: %s", t))
|
||||
}
|
||||
|
||||
func exampleStruct(t reflect.Type) interface{} {
|
||||
func exampleStruct(t, parent reflect.Type) interface{} {
|
||||
ns := reflect.New(t)
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
if f.Type == parent {
|
||||
continue
|
||||
}
|
||||
if strings.Title(f.Name) == f.Name {
|
||||
ns.Elem().Field(i).Set(reflect.ValueOf(exampleValue(f.Type)))
|
||||
ns.Elem().Field(i).Set(reflect.ValueOf(exampleValue(f.Type, t)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,17 +293,17 @@ func main() {
|
||||
ft := m.Func.Type()
|
||||
for j := 2; j < ft.NumIn(); j++ {
|
||||
inp := ft.In(j)
|
||||
args = append(args, exampleValue(inp))
|
||||
args = append(args, exampleValue(inp, nil))
|
||||
}
|
||||
|
||||
v, err := json.Marshal(args)
|
||||
v, err := json.MarshalIndent(args, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
outv := exampleValue(ft.Out(0))
|
||||
outv := exampleValue(ft.Out(0), nil)
|
||||
|
||||
ov, err := json.Marshal(outv)
|
||||
ov, err := json.MarshalIndent(outv, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -318,6 +325,15 @@ func main() {
|
||||
return groupslice[i].GroupName < groupslice[j].GroupName
|
||||
})
|
||||
|
||||
fmt.Printf("# Groups\n")
|
||||
|
||||
for _, g := range groupslice {
|
||||
fmt.Printf("* [%s](#%s)\n", g.GroupName, g.GroupName)
|
||||
for _, method := range g.Methods {
|
||||
fmt.Printf(" * [%s](#%s)\n", method.Name, method.Name)
|
||||
}
|
||||
}
|
||||
|
||||
for _, g := range groupslice {
|
||||
g := g
|
||||
fmt.Printf("## %s\n", g.GroupName)
|
||||
@@ -331,8 +347,17 @@ func main() {
|
||||
fmt.Printf("### %s\n", m.Name)
|
||||
fmt.Printf("%s\n\n", m.Comment)
|
||||
|
||||
fmt.Printf("Inputs: `%s`\n\n", m.InputExample)
|
||||
fmt.Printf("Response: `%s`\n\n", m.ResponseExample)
|
||||
if strings.Count(m.InputExample, "\n") > 0 {
|
||||
fmt.Printf("Inputs:\n```json\n%s\n```\n\n", m.InputExample)
|
||||
} else {
|
||||
fmt.Printf("Inputs: `%s`\n\n", m.InputExample)
|
||||
}
|
||||
|
||||
if strings.Count(m.ResponseExample, "\n") > 0 {
|
||||
fmt.Printf("Response:\n```json\n%s\n```\n\n", m.ResponseExample)
|
||||
} else {
|
||||
fmt.Printf("Response: `%s`\n\n", m.ResponseExample)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/dns4/bootstrap-0-sin.fil-test.net/tcp/1347/p2p/12D3KooWKNF7vNFEhnvB45E9mw2B5z6t419W3ziZPLdUDVnLLKGs
|
||||
/ip4/86.109.15.57/tcp/1347/p2p/12D3KooWKNF7vNFEhnvB45E9mw2B5z6t419W3ziZPLdUDVnLLKGs
|
||||
/dns4/bootstrap-0-dfw.fil-test.net/tcp/1347/p2p/12D3KooWECJTm7RUPyGfNbRwm6y2fK4wA7EB8rDJtWsq5AKi7iDr
|
||||
/ip4/139.178.84.45/tcp/1347/p2p/12D3KooWECJTm7RUPyGfNbRwm6y2fK4wA7EB8rDJtWsq5AKi7iDr
|
||||
/dns4/bootstrap-0-fra.fil-test.net/tcp/1347/p2p/12D3KooWC7MD6m7iNCuDsYtNr7xVtazihyVUizBbhmhEiyMAm9ym
|
||||
/ip4/136.144.49.17/tcp/1347/p2p/12D3KooWC7MD6m7iNCuDsYtNr7xVtazihyVUizBbhmhEiyMAm9ym
|
||||
/dns4/bootstrap-1-sin.fil-test.net/tcp/1347/p2p/12D3KooWD8eYqsKcEMFax6EbWN3rjA7qFsxCez2rmN8dWqkzgNaN
|
||||
/ip4/86.109.15.55/tcp/1347/p2p/12D3KooWD8eYqsKcEMFax6EbWN3rjA7qFsxCez2rmN8dWqkzgNaN
|
||||
/dns4/bootstrap-1-dfw.fil-test.net/tcp/1347/p2p/12D3KooWLB3RR8frLAmaK4ntHC2dwrAjyGzQgyUzWxAum1FxyyqD
|
||||
/ip4/139.178.84.41/tcp/1347/p2p/12D3KooWLB3RR8frLAmaK4ntHC2dwrAjyGzQgyUzWxAum1FxyyqD
|
||||
/dns4/bootstrap-1-fra.fil-test.net/tcp/1347/p2p/12D3KooWGPDJAw3HW4uVU3JEQBfFaZ1kdpg4HvvwRMVpUYbzhsLQ
|
||||
/ip4/136.144.49.131/tcp/1347/p2p/12D3KooWGPDJAw3HW4uVU3JEQBfFaZ1kdpg4HvvwRMVpUYbzhsLQ
|
||||
/dns4/bootstrap-0-sin.fil-test.net/tcp/1347/p2p/12D3KooWPdUquftaQvoQEtEdsRBAhwD6jopbF2oweVTzR59VbHEd
|
||||
/ip4/86.109.15.57/tcp/1347/p2p/12D3KooWPdUquftaQvoQEtEdsRBAhwD6jopbF2oweVTzR59VbHEd
|
||||
/dns4/bootstrap-0-dfw.fil-test.net/tcp/1347/p2p/12D3KooWQSCkHCzosEyrh8FgYfLejKgEPM5VB6qWzZE3yDAuXn8d
|
||||
/ip4/139.178.84.45/tcp/1347/p2p/12D3KooWQSCkHCzosEyrh8FgYfLejKgEPM5VB6qWzZE3yDAuXn8d
|
||||
/dns4/bootstrap-0-fra.fil-test.net/tcp/1347/p2p/12D3KooWEXN2eQmoyqnNjde9PBAQfQLHN67jcEdWU6JougWrgXJK
|
||||
/ip4/136.144.49.17/tcp/1347/p2p/12D3KooWEXN2eQmoyqnNjde9PBAQfQLHN67jcEdWU6JougWrgXJK
|
||||
/dns4/bootstrap-1-sin.fil-test.net/tcp/1347/p2p/12D3KooWLmJkZd33mJhjg5RrpJ6NFep9SNLXWc4uVngV4TXKwzYw
|
||||
/ip4/86.109.15.123/tcp/1347/p2p/12D3KooWLmJkZd33mJhjg5RrpJ6NFep9SNLXWc4uVngV4TXKwzYw
|
||||
/dns4/bootstrap-1-dfw.fil-test.net/tcp/1347/p2p/12D3KooWGXLHjiz6pTRu7x2pkgTVCoxcCiVxcNLpMnWcJ3JiNEy5
|
||||
/ip4/139.178.86.3/tcp/1347/p2p/12D3KooWGXLHjiz6pTRu7x2pkgTVCoxcCiVxcNLpMnWcJ3JiNEy5
|
||||
/dns4/bootstrap-1-fra.fil-test.net/tcp/1347/p2p/12D3KooW9szZmKttS9A1FafH3Zc2pxKwwmvCWCGKkRP4KmbhhC4R
|
||||
/ip4/136.144.49.131/tcp/1347/p2p/12D3KooW9szZmKttS9A1FafH3Zc2pxKwwmvCWCGKkRP4KmbhhC4R
|
||||
|
||||
Binary file not shown.
@@ -12,11 +12,10 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
power.ConsensusMinerMinPower = big.NewInt(1024 << 20)
|
||||
power.ConsensusMinerMinPower = big.NewInt(1024 << 30)
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg512MiBV1: {},
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1: {},
|
||||
abi.RegisteredSealProof_StackedDrg64GiBV1: {},
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1: {},
|
||||
abi.RegisteredSealProof_StackedDrg64GiBV1: {},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-1
@@ -186,6 +186,15 @@ func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte
|
||||
}
|
||||
|
||||
func (ps pricedSyscalls) BatchVerifySeals(inp map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error) {
|
||||
ps.chargeGas(newGasCharge("BatchVerifySeals", 0, 0)) // TODO: this is only called by the cron actor. Should we even charge gas?
|
||||
var gasChargeSum GasCharge
|
||||
gasChargeSum.Name = "BatchVerifySeals"
|
||||
ps.chargeGas(gasChargeSum) // TODO: this is only called by the cron actor. Should we even charge gas?
|
||||
|
||||
for _, svis := range inp {
|
||||
for _, svi := range svis {
|
||||
ch := ps.pl.OnVerifySeal(svi)
|
||||
ps.chargeGas(newGasCharge("BatchVerifySingle", 0, 0).WithVirtual(ch.VirtualCompute+ch.ComputeGas, 0))
|
||||
}
|
||||
}
|
||||
return ps.under.BatchVerifySeals(inp)
|
||||
}
|
||||
|
||||
+5
-5
@@ -103,17 +103,17 @@ func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.M
|
||||
if methodNum != builtin.MethodSend {
|
||||
ret += pl.sendInvokeMethod
|
||||
}
|
||||
return newGasCharge("OnMethodInvocation", ret, 0)
|
||||
return newGasCharge("OnMethodInvocation", ret, 0).WithVirtual(ret*15000, 0)
|
||||
}
|
||||
|
||||
// OnIpldGet returns the gas used for storing an object
|
||||
func (pl *pricelistV0) OnIpldGet(dataSize int) GasCharge {
|
||||
return newGasCharge("OnIpldGet", pl.ipldGetBase+int64(dataSize)*pl.ipldGetPerByte, 0).WithExtra(dataSize)
|
||||
return newGasCharge("OnIpldGet", pl.ipldGetBase+int64(dataSize)*pl.ipldGetPerByte, 0).WithExtra(dataSize).WithVirtual(pl.ipldGetBase*13750+(pl.ipldGetPerByte*100), 0)
|
||||
}
|
||||
|
||||
// OnIpldPut returns the gas used for storing an object
|
||||
func (pl *pricelistV0) OnIpldPut(dataSize int) GasCharge {
|
||||
return newGasCharge("OnIpldPut", pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte).WithExtra(dataSize)
|
||||
return newGasCharge("OnIpldPut", pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte).WithExtra(dataSize).WithVirtual(pl.ipldPutBase*8700+(pl.ipldPutPerByte*100), 0)
|
||||
}
|
||||
|
||||
// OnCreateActor returns the gas used for creating an actor
|
||||
@@ -144,13 +144,13 @@ func (pl *pricelistV0) OnHashing(dataSize int) GasCharge {
|
||||
// OnComputeUnsealedSectorCid
|
||||
func (pl *pricelistV0) OnComputeUnsealedSectorCid(proofType abi.RegisteredSealProof, pieces []abi.PieceInfo) GasCharge {
|
||||
// TODO: this needs more cost tunning, check with @lotus
|
||||
return newGasCharge("OnComputeUnsealedSectorCid", pl.computeUnsealedSectorCidBase, 0)
|
||||
return newGasCharge("OnComputeUnsealedSectorCid", pl.computeUnsealedSectorCidBase, 0).WithVirtual(pl.computeUnsealedSectorCidBase*24500, 0)
|
||||
}
|
||||
|
||||
// OnVerifySeal
|
||||
func (pl *pricelistV0) OnVerifySeal(info abi.SealVerifyInfo) GasCharge {
|
||||
// TODO: this needs more cost tunning, check with @lotus
|
||||
return newGasCharge("OnVerifySeal", pl.verifySealBase, 0)
|
||||
return newGasCharge("OnVerifySeal", pl.verifySealBase, 0).WithVirtual(pl.verifySealBase*177500, 0)
|
||||
}
|
||||
|
||||
// OnVerifyPost
|
||||
|
||||
+11
-3
@@ -253,7 +253,7 @@ func (rt *Runtime) CreateActor(codeID cid.Cid, address address.Address) {
|
||||
rt.Abortf(exitcode.SysErrorIllegalArgument, "Actor address already exists")
|
||||
}
|
||||
|
||||
rt.ChargeGas(rt.Pricelist().OnCreateActor())
|
||||
rt.chargeGas(rt.Pricelist().OnCreateActor())
|
||||
|
||||
err = rt.state.SetActor(address, &types.Actor{
|
||||
Code: codeID,
|
||||
@@ -267,7 +267,7 @@ func (rt *Runtime) CreateActor(codeID cid.Cid, address address.Address) {
|
||||
}
|
||||
|
||||
func (rt *Runtime) DeleteActor(addr address.Address) {
|
||||
rt.ChargeGas(rt.Pricelist().OnDeleteActor())
|
||||
rt.chargeGas(rt.Pricelist().OnDeleteActor())
|
||||
act, err := rt.state.GetActor(rt.Message().Receiver())
|
||||
if err != nil {
|
||||
if xerrors.Is(err, types.ErrActorNotFound) {
|
||||
@@ -496,7 +496,15 @@ func (rt *Runtime) finilizeGasTracing() {
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *Runtime) ChargeGas(gas GasCharge) {
|
||||
// ChargeGas is spec actors function
|
||||
func (rt *Runtime) ChargeGas(name string, compute int64, virtual int64) {
|
||||
err := rt.chargeGasInternal(newGasCharge(name, compute, 0).WithVirtual(virtual, 0), 1)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *Runtime) chargeGas(gas GasCharge) {
|
||||
err := rt.chargeGasInternal(gas, 1)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
@@ -241,10 +241,12 @@ func (ss *syscallShim) VerifySignature(sig crypto.Signature, addr address.Addres
|
||||
return sigs.Verify(&sig, kaddr, input)
|
||||
}
|
||||
|
||||
var BatchSealVerifyParallelism = goruntime.NumCPU()
|
||||
|
||||
func (ss *syscallShim) BatchVerifySeals(inp map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error) {
|
||||
out := make(map[address.Address][]bool)
|
||||
|
||||
sema := make(chan struct{}, goruntime.NumCPU())
|
||||
sema := make(chan struct{}, BatchSealVerifyParallelism)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for addr, seals := range inp {
|
||||
|
||||
+33
-12
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
lapi "github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
@@ -391,6 +392,10 @@ var clientRetrieveCmd = &cli.Command{
|
||||
Name: "car",
|
||||
Usage: "export to a car file instead of a regular file",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "miner",
|
||||
Usage: "miner address for retrieval, if not present it'll use local discovery",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if cctx.NArg() != 2 {
|
||||
@@ -398,7 +403,7 @@ var clientRetrieveCmd = &cli.Command{
|
||||
return nil
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
fapi, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -409,7 +414,7 @@ var clientRetrieveCmd = &cli.Command{
|
||||
if cctx.String("address") != "" {
|
||||
payer, err = address.NewFromString(cctx.String("address"))
|
||||
} else {
|
||||
payer, err = api.WalletDefaultAddress(ctx)
|
||||
payer, err = fapi.WalletDefaultAddress(ctx)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -432,23 +437,39 @@ var clientRetrieveCmd = &cli.Command{
|
||||
return nil
|
||||
}*/ // TODO: fix
|
||||
|
||||
offers, err := api.ClientFindData(ctx, file)
|
||||
if err != nil {
|
||||
return err
|
||||
var offer api.QueryOffer
|
||||
minerStrAddr := cctx.String("miner")
|
||||
if minerStrAddr == "" { // Local discovery
|
||||
offers, err := fapi.ClientFindData(ctx, file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: parse offer strings from `client find`, make this smarter
|
||||
if len(offers) < 1 {
|
||||
fmt.Println("Failed to find file")
|
||||
return nil
|
||||
}
|
||||
offer = offers[0]
|
||||
} else { // Directed retrieval
|
||||
minerAddr, err := address.NewFromString(minerStrAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
offer, err = fapi.ClientMinerQueryOffer(ctx, file, minerAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: parse offer strings from `client find`, make this smarter
|
||||
|
||||
if len(offers) < 1 {
|
||||
fmt.Println("Failed to find file")
|
||||
return nil
|
||||
if offer.Err != "" {
|
||||
return fmt.Errorf("The received offer errored: %s", offer.Err)
|
||||
}
|
||||
|
||||
ref := &lapi.FileRef{
|
||||
Path: cctx.Args().Get(1),
|
||||
IsCAR: cctx.Bool("car"),
|
||||
}
|
||||
if err := api.ClientRetrieve(ctx, offers[0].Order(payer), ref); err != nil {
|
||||
if err := fapi.ClientRetrieve(ctx, offer.Order(payer), ref); err != nil {
|
||||
return xerrors.Errorf("Retrieval Failed: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/pprof"
|
||||
"sort"
|
||||
"time"
|
||||
@@ -44,8 +46,14 @@ var importBenchCmd = &cli.Command{
|
||||
Name: "height",
|
||||
Usage: "halt validation after given height",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "batch-seal-verify-threads",
|
||||
Usage: "set the parallelism factor for batch seal verification",
|
||||
Value: runtime.NumCPU(),
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
vm.BatchSealVerifyParallelism = cctx.Int("batch-seal-verify-threads")
|
||||
if !cctx.Args().Present() {
|
||||
fmt.Println("must pass car file of chain to benchmark importing")
|
||||
return nil
|
||||
@@ -162,6 +170,58 @@ type Invocation struct {
|
||||
Invoc *api.InvocResult
|
||||
}
|
||||
|
||||
const GasPerNs = 10
|
||||
|
||||
func countGasCosts(et *types.ExecutionTrace) (int64, int64) {
|
||||
var cgas, vgas int64
|
||||
|
||||
for _, gc := range et.GasCharges {
|
||||
cgas += gc.ComputeGas
|
||||
vgas += gc.VirtualComputeGas
|
||||
}
|
||||
|
||||
for _, sub := range et.Subcalls {
|
||||
c, v := countGasCosts(&sub)
|
||||
cgas += c
|
||||
vgas += v
|
||||
}
|
||||
|
||||
return cgas, vgas
|
||||
}
|
||||
|
||||
func compStats(vals []float64) (float64, float64) {
|
||||
var sum float64
|
||||
|
||||
for _, v := range vals {
|
||||
sum += v
|
||||
}
|
||||
|
||||
av := sum / float64(len(vals))
|
||||
|
||||
var varsum float64
|
||||
for _, v := range vals {
|
||||
delta := av - v
|
||||
varsum += delta * delta
|
||||
}
|
||||
|
||||
return av, math.Sqrt(varsum / float64(len(vals)))
|
||||
}
|
||||
|
||||
func tallyGasCharges(charges map[string][]float64, et *types.ExecutionTrace) {
|
||||
for _, gc := range et.GasCharges {
|
||||
|
||||
compGas := gc.ComputeGas + gc.VirtualComputeGas
|
||||
ratio := float64(compGas) / float64(gc.TimeTaken.Nanoseconds())
|
||||
|
||||
charges[gc.Name] = append(charges[gc.Name], 1/(ratio/GasPerNs))
|
||||
//fmt.Printf("%s: %d, %s: %0.2f\n", gc.Name, compGas, gc.TimeTaken, 1/(ratio/GasPerNs))
|
||||
for _, sub := range et.Subcalls {
|
||||
tallyGasCharges(charges, &sub)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var importAnalyzeCmd = &cli.Command{
|
||||
Name: "analyze",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
@@ -180,6 +240,8 @@ var importAnalyzeCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
chargeDeltas := make(map[string][]float64)
|
||||
|
||||
var invocs []Invocation
|
||||
var totalTime time.Duration
|
||||
for i, r := range results {
|
||||
@@ -191,9 +253,29 @@ var importAnalyzeCmd = &cli.Command{
|
||||
TipSet: r.TipSet,
|
||||
Invoc: inv,
|
||||
})
|
||||
|
||||
cgas, vgas := countGasCosts(&inv.ExecutionTrace)
|
||||
fmt.Printf("Invocation: %d %s: %s %d -> %0.2f\n", inv.Msg.Method, inv.Msg.To, inv.Duration, cgas+vgas, float64(GasPerNs*inv.Duration.Nanoseconds())/float64(cgas+vgas))
|
||||
|
||||
tallyGasCharges(chargeDeltas, &inv.ExecutionTrace)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var keys []string
|
||||
for k := range chargeDeltas {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
fmt.Println("Gas Price Deltas")
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
vals := chargeDeltas[k]
|
||||
av, stdev := compStats(vals)
|
||||
|
||||
fmt.Printf("%s: incr by %f (%f)\n", k, av, stdev)
|
||||
}
|
||||
|
||||
sort.Slice(invocs, func(i, j int) bool {
|
||||
return invocs[i].Invoc.Duration > invocs[j].Invoc.Duration
|
||||
})
|
||||
|
||||
+189
-127
@@ -139,6 +139,10 @@ var sealBenchCmd = &cli.Command{
|
||||
Name: "num-sectors",
|
||||
Value: 1,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "parallel",
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if c.Bool("no-gpu") {
|
||||
@@ -235,7 +239,12 @@ var sealBenchCmd = &cli.Command{
|
||||
|
||||
if robench == "" {
|
||||
var err error
|
||||
sealTimings, sealedSectors, err = runSeals(sb, sbfs, c.Int("num-sectors"), mid, sectorSize, []byte(c.String("ticket-preimage")), c.String("save-commit2-input"), c.Bool("skip-commit2"), c.Bool("skip-unseal"))
|
||||
parCfg := ParCfg{
|
||||
PreCommit1: c.Int("parallel"),
|
||||
PreCommit2: 1,
|
||||
Commit: 1,
|
||||
}
|
||||
sealTimings, sealedSectors, err = runSeals(sb, sbfs, c.Int("num-sectors"), parCfg, mid, sectorSize, []byte(c.String("ticket-preimage")), c.String("save-commit2-input"), c.Bool("skip-commit2"), c.Bool("skip-unseal"))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to run seals: %w", err)
|
||||
}
|
||||
@@ -307,7 +316,7 @@ var sealBenchCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
winnnigpost1 := time.Now()
|
||||
winningpost1 := time.Now()
|
||||
|
||||
log.Info("computing winning post snark (hot)")
|
||||
proof2, err := sb.GenerateWinningPoSt(context.TODO(), mid, candidates, challenge[:])
|
||||
@@ -331,7 +340,7 @@ var sealBenchCmd = &cli.Command{
|
||||
log.Error("post verification failed")
|
||||
}
|
||||
|
||||
verifyWinnnigPost1 := time.Now()
|
||||
verifyWinningPost1 := time.Now()
|
||||
|
||||
pvi2 := abi.WinningPoStVerifyInfo{
|
||||
Randomness: abi.PoStRandomness(challenge[:]),
|
||||
@@ -398,10 +407,10 @@ var sealBenchCmd = &cli.Command{
|
||||
verifyWindowpost2 := time.Now()
|
||||
|
||||
bo.PostGenerateCandidates = gencandidates.Sub(beforePost)
|
||||
bo.PostWinningProofCold = winnnigpost1.Sub(gencandidates)
|
||||
bo.PostWinningProofHot = winnningpost2.Sub(winnnigpost1)
|
||||
bo.VerifyWinningPostCold = verifyWinnnigPost1.Sub(winnningpost2)
|
||||
bo.VerifyWinningPostHot = verifyWinningPost2.Sub(verifyWinnnigPost1)
|
||||
bo.PostWinningProofCold = winningpost1.Sub(gencandidates)
|
||||
bo.PostWinningProofHot = winnningpost2.Sub(winningpost1)
|
||||
bo.VerifyWinningPostCold = verifyWinningPost1.Sub(winnningpost2)
|
||||
bo.VerifyWinningPostHot = verifyWinningPost2.Sub(verifyWinningPost1)
|
||||
|
||||
bo.PostWindowProofCold = windowpost1.Sub(verifyWinningPost2)
|
||||
bo.PostWindowProofHot = windowpost2.Sub(windowpost1)
|
||||
@@ -432,10 +441,10 @@ var sealBenchCmd = &cli.Command{
|
||||
}
|
||||
if !c.Bool("skip-commit2") {
|
||||
fmt.Printf("generate candidates: %s (%s)\n", bo.PostGenerateCandidates, bps(bo.SectorSize*abi.SectorSize(len(bo.SealingResults)), bo.PostGenerateCandidates))
|
||||
fmt.Printf("compute winnnig post proof (cold): %s\n", bo.PostWinningProofCold)
|
||||
fmt.Printf("compute winnnig post proof (hot): %s\n", bo.PostWinningProofHot)
|
||||
fmt.Printf("verify winnnig post proof (cold): %s\n", bo.VerifyWinningPostCold)
|
||||
fmt.Printf("verify winnnig post proof (hot): %s\n\n", bo.VerifyWinningPostHot)
|
||||
fmt.Printf("compute winning post proof (cold): %s\n", bo.PostWinningProofCold)
|
||||
fmt.Printf("compute winning post proof (hot): %s\n", bo.PostWinningProofHot)
|
||||
fmt.Printf("verify winning post proof (cold): %s\n", bo.VerifyWinningPostCold)
|
||||
fmt.Printf("verify winning post proof (hot): %s\n\n", bo.VerifyWinningPostHot)
|
||||
|
||||
fmt.Printf("compute window post proof (cold): %s\n", bo.PostWindowProofCold)
|
||||
fmt.Printf("compute window post proof (hot): %s\n", bo.PostWindowProofHot)
|
||||
@@ -447,9 +456,23 @@ var sealBenchCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, mid abi.ActorID, sectorSize abi.SectorSize, ticketPreimage []byte, saveC2inp string, skipc2, skipunseal bool) ([]SealingResult, []abi.SectorInfo, error) {
|
||||
var sealTimings []SealingResult
|
||||
var sealedSectors []abi.SectorInfo
|
||||
type ParCfg struct {
|
||||
PreCommit1 int
|
||||
PreCommit2 int
|
||||
Commit int
|
||||
}
|
||||
|
||||
func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par ParCfg, mid abi.ActorID, sectorSize abi.SectorSize, ticketPreimage []byte, saveC2inp string, skipc2, skipunseal bool) ([]SealingResult, []abi.SectorInfo, error) {
|
||||
var pieces []abi.PieceInfo
|
||||
sealTimings := make([]SealingResult, numSectors)
|
||||
sealedSectors := make([]abi.SectorInfo, numSectors)
|
||||
|
||||
preCommit2Sema := make(chan struct{}, par.PreCommit2)
|
||||
commitSema := make(chan struct{}, par.Commit)
|
||||
|
||||
if numSectors%par.PreCommit1 != 0 {
|
||||
return nil, nil, fmt.Errorf("parallelism factor must cleanly divide numSectors")
|
||||
}
|
||||
|
||||
for i := abi.SectorNumber(1); i <= abi.SectorNumber(numSectors); i++ {
|
||||
sid := abi.SectorID{
|
||||
@@ -458,7 +481,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, mid
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
log.Info("Writing piece into sector...")
|
||||
log.Infof("[%d] Writing piece into sector...", i)
|
||||
|
||||
r := rand.New(rand.NewSource(100 + int64(i)))
|
||||
|
||||
@@ -467,129 +490,168 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, mid
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
addpiece := time.Now()
|
||||
pieces = append(pieces, pi)
|
||||
|
||||
trand := blake2b.Sum256(ticketPreimage)
|
||||
ticket := abi.SealRandomness(trand[:])
|
||||
sealTimings[i-1].AddPiece = time.Since(start)
|
||||
}
|
||||
|
||||
log.Info("Running replication(1)...")
|
||||
pieces := []abi.PieceInfo{pi}
|
||||
pc1o, err := sb.SealPreCommit1(context.TODO(), sid, ticket, pieces)
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("commit: %w", err)
|
||||
}
|
||||
sectorsPerWorker := numSectors / par.PreCommit1
|
||||
|
||||
precommit1 := time.Now()
|
||||
errs := make(chan error, par.PreCommit1)
|
||||
for wid := 0; wid < par.PreCommit1; wid++ {
|
||||
go func(worker int) {
|
||||
sealerr := func() error {
|
||||
start := 1 + (worker * sectorsPerWorker)
|
||||
end := start + sectorsPerWorker
|
||||
for i := abi.SectorNumber(start); i < abi.SectorNumber(end); i++ {
|
||||
ix := int(i - 1)
|
||||
sid := abi.SectorID{
|
||||
Miner: mid,
|
||||
Number: i,
|
||||
}
|
||||
|
||||
log.Info("Running replication(2)...")
|
||||
cids, err := sb.SealPreCommit2(context.TODO(), sid, pc1o)
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("commit: %w", err)
|
||||
}
|
||||
start := time.Now()
|
||||
|
||||
precommit2 := time.Now()
|
||||
trand := blake2b.Sum256(ticketPreimage)
|
||||
ticket := abi.SealRandomness(trand[:])
|
||||
|
||||
sealedSectors = append(sealedSectors, abi.SectorInfo{
|
||||
SealProof: sb.SealProofType(),
|
||||
SectorNumber: i,
|
||||
SealedCID: cids.Sealed,
|
||||
})
|
||||
log.Infof("[%d] Running replication(1)...", i)
|
||||
pieces := []abi.PieceInfo{pieces[ix]}
|
||||
pc1o, err := sb.SealPreCommit1(context.TODO(), sid, ticket, pieces)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("commit: %w", err)
|
||||
}
|
||||
|
||||
seed := lapi.SealSeed{
|
||||
Epoch: 101,
|
||||
Value: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 255},
|
||||
}
|
||||
precommit1 := time.Now()
|
||||
|
||||
log.Info("Generating PoRep for sector (1)")
|
||||
c1o, err := sb.SealCommit1(context.TODO(), sid, ticket, seed.Value, pieces, cids)
|
||||
preCommit2Sema <- struct{}{}
|
||||
pc2Start := time.Now()
|
||||
log.Infof("[%d] Running replication(2)...", i)
|
||||
cids, err := sb.SealPreCommit2(context.TODO(), sid, pc1o)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("commit: %w", err)
|
||||
}
|
||||
|
||||
precommit2 := time.Now()
|
||||
<-preCommit2Sema
|
||||
|
||||
sealedSectors[ix] = abi.SectorInfo{
|
||||
SealProof: sb.SealProofType(),
|
||||
SectorNumber: i,
|
||||
SealedCID: cids.Sealed,
|
||||
}
|
||||
|
||||
seed := lapi.SealSeed{
|
||||
Epoch: 101,
|
||||
Value: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 255},
|
||||
}
|
||||
|
||||
commitSema <- struct{}{}
|
||||
commitStart := time.Now()
|
||||
log.Infof("[%d] Generating PoRep for sector (1)", i)
|
||||
c1o, err := sb.SealCommit1(context.TODO(), sid, ticket, seed.Value, pieces, cids)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sealcommit1 := time.Now()
|
||||
|
||||
log.Infof("[%d] Generating PoRep for sector (2)", i)
|
||||
|
||||
if saveC2inp != "" {
|
||||
c2in := Commit2In{
|
||||
SectorNum: int64(i),
|
||||
Phase1Out: c1o,
|
||||
SectorSize: uint64(sectorSize),
|
||||
}
|
||||
|
||||
b, err := json.Marshal(&c2in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(saveC2inp, b, 0664); err != nil {
|
||||
log.Warnf("%+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
var proof storage.Proof
|
||||
if !skipc2 {
|
||||
proof, err = sb.SealCommit2(context.TODO(), sid, c1o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
sealcommit2 := time.Now()
|
||||
<-commitSema
|
||||
|
||||
if !skipc2 {
|
||||
svi := abi.SealVerifyInfo{
|
||||
SectorID: abi.SectorID{Miner: mid, Number: i},
|
||||
SealedCID: cids.Sealed,
|
||||
SealProof: sb.SealProofType(),
|
||||
Proof: proof,
|
||||
DealIDs: nil,
|
||||
Randomness: ticket,
|
||||
InteractiveRandomness: seed.Value,
|
||||
UnsealedCID: cids.Unsealed,
|
||||
}
|
||||
|
||||
ok, err := ffiwrapper.ProofVerifier.VerifySeal(svi)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
return xerrors.Errorf("porep proof for sector %d was invalid", i)
|
||||
}
|
||||
}
|
||||
|
||||
verifySeal := time.Now()
|
||||
|
||||
if !skipunseal {
|
||||
log.Infof("[%d] Unsealing sector", i)
|
||||
{
|
||||
p, done, err := sbfs.AcquireSector(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, stores.FTUnsealed, stores.FTNone, true)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("acquire unsealed sector for removing: %w", err)
|
||||
}
|
||||
done()
|
||||
|
||||
if err := os.Remove(p.Unsealed); err != nil {
|
||||
return xerrors.Errorf("removing unsealed sector: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
err := sb.UnsealPiece(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, 0, abi.PaddedPieceSize(sectorSize).Unpadded(), ticket, cids.Unsealed)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
unseal := time.Now()
|
||||
|
||||
sealTimings[ix].PreCommit1 = precommit1.Sub(start)
|
||||
sealTimings[ix].PreCommit2 = precommit2.Sub(pc2Start)
|
||||
sealTimings[ix].Commit1 = sealcommit1.Sub(commitStart)
|
||||
sealTimings[ix].Commit2 = sealcommit2.Sub(sealcommit1)
|
||||
sealTimings[ix].Verify = verifySeal.Sub(sealcommit2)
|
||||
sealTimings[ix].Unseal = unseal.Sub(verifySeal)
|
||||
}
|
||||
return nil
|
||||
}()
|
||||
if sealerr != nil {
|
||||
errs <- sealerr
|
||||
return
|
||||
}
|
||||
errs <- nil
|
||||
}(wid)
|
||||
}
|
||||
|
||||
for i := 0; i < par.PreCommit1; i++ {
|
||||
err := <-errs
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
sealcommit1 := time.Now()
|
||||
|
||||
log.Info("Generating PoRep for sector (2)")
|
||||
|
||||
if saveC2inp != "" {
|
||||
c2in := Commit2In{
|
||||
SectorNum: int64(i),
|
||||
Phase1Out: c1o,
|
||||
SectorSize: uint64(sectorSize),
|
||||
}
|
||||
|
||||
b, err := json.Marshal(&c2in)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(saveC2inp, b, 0664); err != nil {
|
||||
log.Warnf("%+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
var proof storage.Proof
|
||||
if !skipc2 {
|
||||
proof, err = sb.SealCommit2(context.TODO(), sid, c1o)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
sealcommit2 := time.Now()
|
||||
|
||||
if !skipc2 {
|
||||
svi := abi.SealVerifyInfo{
|
||||
SectorID: abi.SectorID{Miner: mid, Number: i},
|
||||
SealedCID: cids.Sealed,
|
||||
SealProof: sb.SealProofType(),
|
||||
Proof: proof,
|
||||
DealIDs: nil,
|
||||
Randomness: ticket,
|
||||
InteractiveRandomness: seed.Value,
|
||||
UnsealedCID: cids.Unsealed,
|
||||
}
|
||||
|
||||
ok, err := ffiwrapper.ProofVerifier.VerifySeal(svi)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if !ok {
|
||||
return nil, nil, xerrors.Errorf("porep proof for sector %d was invalid", i)
|
||||
}
|
||||
}
|
||||
|
||||
verifySeal := time.Now()
|
||||
|
||||
if !skipunseal {
|
||||
log.Info("Unsealing sector")
|
||||
{
|
||||
p, done, err := sbfs.AcquireSector(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, stores.FTUnsealed, stores.FTNone, true)
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("acquire unsealed sector for removing: %w", err)
|
||||
}
|
||||
done()
|
||||
|
||||
if err := os.Remove(p.Unsealed); err != nil {
|
||||
return nil, nil, xerrors.Errorf("removing unsealed sector: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
err := sb.UnsealPiece(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, 0, abi.PaddedPieceSize(sectorSize).Unpadded(), ticket, cids.Unsealed)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
unseal := time.Now()
|
||||
|
||||
sealTimings = append(sealTimings, SealingResult{
|
||||
AddPiece: addpiece.Sub(start),
|
||||
PreCommit1: precommit1.Sub(addpiece),
|
||||
PreCommit2: precommit2.Sub(precommit1),
|
||||
Commit1: sealcommit1.Sub(precommit2),
|
||||
Commit2: sealcommit2.Sub(sealcommit1),
|
||||
Verify: verifySeal.Sub(sealcommit2),
|
||||
Unseal: unseal.Sub(verifySeal),
|
||||
})
|
||||
}
|
||||
|
||||
return sealTimings, sealedSectors, nil
|
||||
|
||||
@@ -3,11 +3,14 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gorilla/mux"
|
||||
@@ -117,11 +120,19 @@ var runCmd = &cli.Command{
|
||||
}
|
||||
|
||||
// Connect to storage-miner
|
||||
|
||||
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting miner api: %w", err)
|
||||
var nodeApi api.StorageMiner
|
||||
var closer func()
|
||||
var err error
|
||||
for {
|
||||
nodeApi, closer, err = lcli.GetStorageMinerAPI(cctx)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
fmt.Printf("\r\x1b[0KConnecting to miner API... (%s)", err)
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
defer closer()
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
@@ -136,6 +147,8 @@ var runCmd = &cli.Command{
|
||||
}
|
||||
log.Infof("Remote version %s", v)
|
||||
|
||||
watchMinerConn(ctx, cctx, nodeApi)
|
||||
|
||||
// Check params
|
||||
|
||||
act, err := nodeApi.ActorAddress(ctx)
|
||||
@@ -317,3 +330,42 @@ var runCmd = &cli.Command{
|
||||
return srv.Serve(nl)
|
||||
},
|
||||
}
|
||||
|
||||
func watchMinerConn(ctx context.Context, cctx *cli.Context, nodeApi api.StorageMiner) {
|
||||
go func() {
|
||||
closing, err := nodeApi.Closing(ctx)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get remote closing channel: %+v", err)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-closing:
|
||||
case <-ctx.Done():
|
||||
}
|
||||
|
||||
if ctx.Err() != nil {
|
||||
return // graceful shutdown
|
||||
}
|
||||
|
||||
log.Warnf("Connection with miner node lost, restarting")
|
||||
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
log.Errorf("getting executable for auto-restart: %+v", err)
|
||||
}
|
||||
|
||||
log.Sync()
|
||||
|
||||
// TODO: there are probably cleaner/more graceful ways to restart,
|
||||
// but this is good enough for now (FSM can recover from the mess this creates)
|
||||
if err := syscall.Exec(exe, []string{exe, "run",
|
||||
fmt.Sprintf("--address=%s", cctx.String("address")),
|
||||
fmt.Sprintf("--no-local-storage=%t", cctx.Bool("no-local-storage")),
|
||||
fmt.Sprintf("--precommit1=%t", cctx.Bool("precommit1")),
|
||||
fmt.Sprintf("--precommit2=%t", cctx.Bool("precommit2")),
|
||||
fmt.Sprintf("--commit=%t", cctx.Bool("commit")),
|
||||
}, os.Environ()); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -92,6 +92,10 @@ func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.Sect
|
||||
return nil, nil, xerrors.Errorf("trim cache: %w", err)
|
||||
}
|
||||
|
||||
if err := cleanupUnsealed(sbfs, sid); err != nil {
|
||||
return nil, nil, xerrors.Errorf("remove unsealed file: %w", err)
|
||||
}
|
||||
|
||||
log.Warn("PreCommitOutput: ", sid, cids.Sealed, cids.Unsealed)
|
||||
sealedSectors = append(sealedSectors, &genesis.PreSeal{
|
||||
CommR: cids.Sealed,
|
||||
@@ -161,6 +165,16 @@ func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.Sect
|
||||
return miner, &minerAddr.KeyInfo, nil
|
||||
}
|
||||
|
||||
func cleanupUnsealed(sbfs *basicfs.Provider, sid abi.SectorID) error {
|
||||
paths, done, err := sbfs.AcquireSector(context.TODO(), sid, stores.FTUnsealed, stores.FTNone, stores.PathSealing)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer done()
|
||||
|
||||
return os.Remove(paths.Unsealed)
|
||||
}
|
||||
|
||||
func WriteGenesisMiner(maddr address.Address, sbroot string, gm *genesis.Miner, key *types.KeyInfo) error {
|
||||
output := map[string]genesis.Miner{
|
||||
maddr.String(): *gm,
|
||||
|
||||
@@ -460,7 +460,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode,
|
||||
}
|
||||
|
||||
if cerr != nil {
|
||||
return xerrors.Errorf("failed to configure storage miner: %w", err)
|
||||
return xerrors.Errorf("failed to configure storage miner: %w", cerr)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ func main() {
|
||||
stopCmd,
|
||||
sectorsCmd,
|
||||
storageCmd,
|
||||
setPriceCmd,
|
||||
workersCmd,
|
||||
provingCmd,
|
||||
}
|
||||
|
||||
@@ -3,11 +3,21 @@ package main
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
)
|
||||
|
||||
var enableCmd = &cli.Command{
|
||||
@@ -40,29 +50,140 @@ var disableCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var setPriceCmd = &cli.Command{
|
||||
Name: "set-price",
|
||||
Usage: "Set price that miner will accept storage deals at (FIL / GiB / Epoch)",
|
||||
Flags: []cli.Flag{},
|
||||
var setAskCmd = &cli.Command{
|
||||
Name: "set-ask",
|
||||
Usage: "Configure the miner's ask",
|
||||
Flags: []cli.Flag{
|
||||
&cli.Uint64Flag{
|
||||
Name: "price",
|
||||
Usage: "Set the price of the ask (specified as FIL / GiB / Epoch) to `PRICE`",
|
||||
Required: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "duration",
|
||||
Usage: "Set duration of ask (a quantity of time after which the ask expires) `DURATION`",
|
||||
DefaultText: "720h0m0s",
|
||||
Value: "720h0m0s",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "min-piece-size",
|
||||
Usage: "Set minimum piece size (w/bit-padding, in bytes) in ask to `SIZE`",
|
||||
DefaultText: "256B",
|
||||
Value: "256B",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "max-piece-size",
|
||||
Usage: "Set maximum piece size (w/bit-padding, in bytes) in ask to `SIZE`",
|
||||
DefaultText: "miner sector size",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
ctx := lcli.DaemonContext(cctx)
|
||||
|
||||
api, closer, err := lcli.GetStorageMinerAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
|
||||
ctx := lcli.DaemonContext(cctx)
|
||||
pri := types.NewInt(cctx.Uint64("price"))
|
||||
|
||||
if !cctx.Args().Present() {
|
||||
return fmt.Errorf("must specify price to set")
|
||||
dur, err := time.ParseDuration(cctx.String("duration"))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("cannot parse duration: %w", err)
|
||||
}
|
||||
|
||||
fp, err := types.ParseFIL(cctx.Args().First())
|
||||
qty := dur.Seconds() / build.BlockDelay
|
||||
|
||||
min, err := units.RAMInBytes(cctx.String("min-piece-size"))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("cannot parse min-piece-size to quantity of bytes: %w", err)
|
||||
}
|
||||
|
||||
if min < 256 {
|
||||
return xerrors.New("minimum piece size (w/bit-padding) is 256B")
|
||||
}
|
||||
|
||||
max, err := units.RAMInBytes(cctx.String("max-piece-size"))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("cannot parse max-piece-size to quantity of bytes: %w", err)
|
||||
}
|
||||
|
||||
maddr, err := api.ActorAddress(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return api.MarketSetPrice(ctx, types.BigInt(fp))
|
||||
ssize, err := api.ActorSectorSize(ctx, maddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
smax := int64(ssize)
|
||||
|
||||
if max == 0 {
|
||||
max = smax
|
||||
}
|
||||
|
||||
if max > smax {
|
||||
return xerrors.Errorf("max piece size (w/bit-padding) %s cannot exceed miner sector size %s", types.SizeStr(types.NewInt(uint64(max))), types.SizeStr(types.NewInt(uint64(smax))))
|
||||
}
|
||||
|
||||
return api.MarketSetAsk(ctx, pri, abi.ChainEpoch(qty), abi.PaddedPieceSize(min), abi.PaddedPieceSize(max))
|
||||
},
|
||||
}
|
||||
|
||||
var getAskCmd = &cli.Command{
|
||||
Name: "get-ask",
|
||||
Usage: "Print the miner's ask",
|
||||
Flags: []cli.Flag{},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
ctx := lcli.DaemonContext(cctx)
|
||||
|
||||
fnapi, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
|
||||
smapi, closer, err := lcli.GetStorageMinerAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
|
||||
sask, err := smapi.MarketGetAsk(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var ask *storagemarket.StorageAsk
|
||||
if sask != nil && sask.Ask != nil {
|
||||
ask = sask.Ask
|
||||
}
|
||||
|
||||
w := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0)
|
||||
fmt.Fprintf(w, "Price per GiB / Epoch\tMin. Piece Size (w/bit-padding)\tMax. Piece Size (w/bit-padding)\tExpiry (Epoch)\tExpiry (Appx. Rem. Time)\tSeq. No.\n")
|
||||
if ask == nil {
|
||||
fmt.Fprintf(w, "<miner does not have an ask>\n")
|
||||
|
||||
return w.Flush()
|
||||
}
|
||||
|
||||
head, err := fnapi.ChainHead(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dlt := ask.Expiry - head.Height()
|
||||
rem := "<expired>"
|
||||
if dlt > 0 {
|
||||
rem = (time.Second * time.Duration(dlt*build.BlockDelay)).String()
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "%s\t%s\t%s\t%d\t%s\t%d\n", ask.Price, types.SizeStr(types.NewInt(uint64(ask.MinPieceSize))), types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize))), ask.Expiry, rem, ask.SeqNo)
|
||||
|
||||
return w.Flush()
|
||||
},
|
||||
}
|
||||
|
||||
@@ -74,6 +195,8 @@ var dealsCmd = &cli.Command{
|
||||
dealsListCmd,
|
||||
enableCmd,
|
||||
disableCmd,
|
||||
setAskCmd,
|
||||
getAskCmd,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -51,4 +51,4 @@ To get the number of cores for your GPU, you will need to check your card’s sp
|
||||
|
||||
## Benchmarking
|
||||
|
||||
Here is a [benchmarking tool](https://github.com/filecoin-project/lotus/tree/testnet-staging/cmd/lotus-bench) and a [GitHub issue thread](https://github.com/filecoin-project/lotus/issues/694) for those who wish to experiment with and contribute hardware setups for the **Filecoin Testnet**.
|
||||
Here is a [benchmarking tool](https://github.com/filecoin-project/lotus/tree/master/cmd/lotus-bench) and a [GitHub issue thread](https://github.com/filecoin-project/lotus/issues/694) for those who wish to experiment with and contribute hardware setups for the **Filecoin Testnet**.
|
||||
|
||||
@@ -29,10 +29,10 @@ require (
|
||||
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca
|
||||
github.com/filecoin-project/go-statestore v0.1.0
|
||||
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b
|
||||
github.com/filecoin-project/sector-storage v0.0.0-20200615192001-42c9e08595b7
|
||||
github.com/filecoin-project/specs-actors v0.6.1
|
||||
github.com/filecoin-project/sector-storage v0.0.0-20200618073200-d9de9b7cb4b4
|
||||
github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121
|
||||
github.com/filecoin-project/specs-storage v0.1.0
|
||||
github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743
|
||||
github.com/filecoin-project/storage-fsm v0.0.0-20200617183754-4380106d3e94
|
||||
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
|
||||
github.com/go-kit/kit v0.10.0
|
||||
github.com/go-ole/go-ole v1.2.4 // indirect
|
||||
|
||||
@@ -253,18 +253,17 @@ github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZO
|
||||
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg=
|
||||
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8=
|
||||
github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM=
|
||||
github.com/filecoin-project/sector-storage v0.0.0-20200615192001-42c9e08595b7 h1:cjsOpQKvZosPx9/qqq2bucHVdRyXzvBR1f37atiR3/0=
|
||||
github.com/filecoin-project/sector-storage v0.0.0-20200615192001-42c9e08595b7/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM=
|
||||
github.com/filecoin-project/sector-storage v0.0.0-20200618073200-d9de9b7cb4b4 h1:lQC8Fbyn31/H4QxYAYwVV3PYZ9vS61EmjktZc5CaiYs=
|
||||
github.com/filecoin-project/sector-storage v0.0.0-20200618073200-d9de9b7cb4b4/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA=
|
||||
github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y=
|
||||
github.com/filecoin-project/specs-actors v0.6.0 h1:IepUsmDGY60QliENVTkBTAkwqGWw9kNbbHOcU/9oiC0=
|
||||
github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY=
|
||||
github.com/filecoin-project/specs-actors v0.6.1 h1:rhHlEzqcuuQU6oKc4csuq+/kQBDZ4EXtSomoN2XApCA=
|
||||
github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY=
|
||||
github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 h1:oRA+b4iN4H86xXDXbU3TOyvmBZp7//c5VqTc0oJ6nLg=
|
||||
github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY=
|
||||
github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94=
|
||||
github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k=
|
||||
github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743 h1:a8f1p6UdeD+ZINBKJN4FhEos8uaKeASOAabq5RCpQdg=
|
||||
github.com/filecoin-project/storage-fsm v0.0.0-20200615162749-494c3bc48743/go.mod h1:q1YCutTSMq/yGYvDPHReT37bPfDLHltnwJutzR9kOY0=
|
||||
github.com/filecoin-project/storage-fsm v0.0.0-20200617183754-4380106d3e94 h1:zPKiZPMgkFF0Lq13hsk8lcWlxeVAs6vvJaa3uHn9v70=
|
||||
github.com/filecoin-project/storage-fsm v0.0.0-20200617183754-4380106d3e94/go.mod h1:q1YCutTSMq/yGYvDPHReT37bPfDLHltnwJutzR9kOY0=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
|
||||
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||
|
||||
+41
-14
@@ -3,6 +3,7 @@ package client
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-fil-markets/pieceio"
|
||||
basicnode "github.com/ipld/go-ipld-prime/node/basic"
|
||||
@@ -201,25 +202,51 @@ func (a *API) ClientFindData(ctx context.Context, root cid.Cid) ([]api.QueryOffe
|
||||
|
||||
out := make([]api.QueryOffer, len(peers))
|
||||
for k, p := range peers {
|
||||
queryResponse, err := a.Retrieval.Query(ctx, p, root, retrievalmarket.QueryParams{})
|
||||
if err != nil {
|
||||
out[k] = api.QueryOffer{Err: err.Error(), Miner: p.Address, MinerPeerID: p.ID}
|
||||
} else {
|
||||
out[k] = api.QueryOffer{
|
||||
Root: root,
|
||||
Size: queryResponse.Size,
|
||||
MinPrice: queryResponse.PieceRetrievalPrice(),
|
||||
PaymentInterval: queryResponse.MaxPaymentInterval,
|
||||
PaymentIntervalIncrease: queryResponse.MaxPaymentIntervalIncrease,
|
||||
Miner: queryResponse.PaymentAddress, // TODO: check
|
||||
MinerPeerID: p.ID,
|
||||
}
|
||||
}
|
||||
out[k] = a.makeRetrievalQuery(ctx, p, root, retrievalmarket.QueryParams{})
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (a *API) ClientMinerQueryOffer(ctx context.Context, payload cid.Cid, miner address.Address) (api.QueryOffer, error) {
|
||||
mi, err := a.StateMinerInfo(ctx, miner, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return api.QueryOffer{}, err
|
||||
}
|
||||
rp := retrievalmarket.RetrievalPeer{
|
||||
Address: miner,
|
||||
ID: mi.PeerId,
|
||||
}
|
||||
return a.makeRetrievalQuery(ctx, rp, payload, retrievalmarket.QueryParams{}), nil
|
||||
}
|
||||
|
||||
func (a *API) makeRetrievalQuery(ctx context.Context, rp retrievalmarket.RetrievalPeer, payload cid.Cid, qp retrievalmarket.QueryParams) api.QueryOffer {
|
||||
queryResponse, err := a.Retrieval.Query(ctx, rp, payload, qp)
|
||||
if err != nil {
|
||||
return api.QueryOffer{Err: err.Error(), Miner: rp.Address, MinerPeerID: rp.ID}
|
||||
}
|
||||
var errStr string
|
||||
switch queryResponse.Status {
|
||||
case retrievalmarket.QueryResponseAvailable:
|
||||
errStr = ""
|
||||
case retrievalmarket.QueryResponseUnavailable:
|
||||
errStr = fmt.Sprintf("retrieval query offer was unavailable: %s", queryResponse.Message)
|
||||
case retrievalmarket.QueryResponseError:
|
||||
errStr = fmt.Sprintf("retrieval query offer errored: %s", queryResponse.Message)
|
||||
}
|
||||
|
||||
return api.QueryOffer{
|
||||
Root: payload,
|
||||
Size: queryResponse.Size,
|
||||
MinPrice: queryResponse.PieceRetrievalPrice(),
|
||||
PaymentInterval: queryResponse.MaxPaymentInterval,
|
||||
PaymentIntervalIncrease: queryResponse.MaxPaymentIntervalIncrease,
|
||||
Miner: queryResponse.PaymentAddress, // TODO: check
|
||||
MinerPeerID: rp.ID,
|
||||
Err: errStr,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *API) ClientImport(ctx context.Context, ref api.FileRef) (cid.Cid, error) {
|
||||
|
||||
bufferedDS := ipld.NewBufferedDAG(ctx, a.LocalDAG)
|
||||
|
||||
@@ -139,4 +139,8 @@ func (a *CommonAPI) Shutdown(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *CommonAPI) Closing(ctx context.Context) (<-chan struct{}, error) {
|
||||
return make(chan struct{}), nil // relies on jsonrpc closing
|
||||
}
|
||||
|
||||
var _ api.Common = &CommonAPI{}
|
||||
|
||||
+11
-2
@@ -201,8 +201,17 @@ func (sm *StorageMinerAPI) MarketListIncompleteDeals(ctx context.Context) ([]sto
|
||||
return sm.StorageProvider.ListLocalDeals()
|
||||
}
|
||||
|
||||
func (sm *StorageMinerAPI) MarketSetPrice(ctx context.Context, p types.BigInt) error {
|
||||
return sm.StorageProvider.SetAsk(p, 60*60*24*100) // lasts for 100 days?
|
||||
func (sm *StorageMinerAPI) MarketSetAsk(ctx context.Context, price types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error {
|
||||
options := []storagemarket.StorageAskOption{
|
||||
storagemarket.MinPieceSize(minPieceSize),
|
||||
storagemarket.MaxPieceSize(maxPieceSize),
|
||||
}
|
||||
|
||||
return sm.StorageProvider.SetAsk(price, duration, options...)
|
||||
}
|
||||
|
||||
func (sm *StorageMinerAPI) MarketGetAsk(ctx context.Context) (*storagemarket.SignedStorageAsk, error) {
|
||||
return sm.StorageProvider.GetAsk(), nil
|
||||
}
|
||||
|
||||
func (sm *StorageMinerAPI) DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) {
|
||||
|
||||
@@ -99,10 +99,6 @@ func (s *WindowPoStScheduler) checkSectors(ctx context.Context, check *abi.BitFi
|
||||
|
||||
log.Warnw("Checked sectors", "checked", len(tocheck), "good", len(sectors))
|
||||
|
||||
if len(sectors) == 0 { // nothing to recover
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
sbf := bitfield.New()
|
||||
for s := range sectors {
|
||||
(&sbf).Set(uint64(s.Number))
|
||||
|
||||
Reference in New Issue
Block a user