2019-06-25 11:42:17 +00:00
|
|
|
package api
|
|
|
|
|
2019-06-29 09:19:06 +00:00
|
|
|
import (
|
|
|
|
"context"
|
2019-10-09 20:18:53 +00:00
|
|
|
"fmt"
|
2019-09-13 21:00:36 +00:00
|
|
|
|
2019-10-23 09:18:22 +00:00
|
|
|
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
|
2019-08-26 10:04:57 +00:00
|
|
|
"github.com/ipfs/go-cid"
|
|
|
|
"github.com/ipfs/go-filestore"
|
|
|
|
cbor "github.com/ipfs/go-ipld-cbor"
|
2019-07-25 00:55:19 +00:00
|
|
|
"github.com/libp2p/go-libp2p-core/network"
|
2019-07-24 00:09:34 +00:00
|
|
|
"github.com/libp2p/go-libp2p-core/peer"
|
|
|
|
|
2019-10-18 04:47:41 +00:00
|
|
|
"github.com/filecoin-project/lotus/build"
|
2019-10-22 11:29:41 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/actors"
|
2019-10-18 04:47:41 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/address"
|
|
|
|
"github.com/filecoin-project/lotus/chain/store"
|
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
2019-06-29 09:19:06 +00:00
|
|
|
)
|
|
|
|
|
2019-08-26 10:04:57 +00:00
|
|
|
func init() {
|
|
|
|
cbor.RegisterCborType(SealedRef{})
|
|
|
|
}
|
|
|
|
|
2019-07-24 00:09:34 +00:00
|
|
|
type Common interface {
|
2019-07-23 17:27:45 +00:00
|
|
|
// Auth
|
2019-10-23 09:18:22 +00:00
|
|
|
AuthVerify(ctx context.Context, token string) ([]Permission, error)
|
|
|
|
AuthNew(ctx context.Context, perms []Permission) ([]byte, error)
|
2019-07-23 17:27:45 +00:00
|
|
|
|
2019-07-24 00:09:34 +00:00
|
|
|
// network
|
|
|
|
|
2019-07-25 00:55:19 +00:00
|
|
|
NetConnectedness(context.Context, peer.ID) (network.Connectedness, error)
|
2019-07-24 00:09:34 +00:00
|
|
|
NetPeers(context.Context) ([]peer.AddrInfo, error)
|
|
|
|
NetConnect(context.Context, peer.AddrInfo) error
|
|
|
|
NetAddrsListen(context.Context) (peer.AddrInfo, error)
|
2019-07-25 00:55:19 +00:00
|
|
|
NetDisconnect(context.Context, peer.ID) error
|
2019-07-24 00:09:34 +00:00
|
|
|
|
|
|
|
// 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)
|
|
|
|
}
|
|
|
|
|
|
|
|
// FullNode API is a low-level interface to the Filecoin network full node
|
|
|
|
type FullNode interface {
|
|
|
|
Common
|
|
|
|
|
|
|
|
// chain
|
2019-09-18 11:01:52 +00:00
|
|
|
|
|
|
|
// ChainNotify returns channel with chain head updates
|
|
|
|
// First message is guaranteed to be of len == 1, and type == 'current'
|
|
|
|
ChainNotify(context.Context) (<-chan []*store.HeadChange, error)
|
2019-10-14 14:21:37 +00:00
|
|
|
ChainHead(context.Context) (*types.TipSet, error)
|
2019-09-06 06:26:02 +00:00
|
|
|
ChainGetRandomness(context.Context, *types.TipSet, []*types.Ticket, int) ([]byte, error)
|
2019-07-25 22:15:03 +00:00
|
|
|
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
|
2019-10-11 06:25:25 +00:00
|
|
|
ChainGetTipSet(context.Context, []cid.Cid) (*types.TipSet, error)
|
2019-08-02 03:51:34 +00:00
|
|
|
ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error)
|
2019-10-03 20:22:21 +00:00
|
|
|
ChainGetParentReceipts(context.Context, cid.Cid) ([]*types.MessageReceipt, error)
|
2019-10-06 00:37:28 +00:00
|
|
|
ChainGetParentMessages(context.Context, cid.Cid) ([]Message, error)
|
2019-09-18 00:08:49 +00:00
|
|
|
ChainGetTipSetByHeight(context.Context, uint64, *types.TipSet) (*types.TipSet, error)
|
2019-10-01 16:28:07 +00:00
|
|
|
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
2019-10-10 03:50:50 +00:00
|
|
|
ChainSetHead(context.Context, *types.TipSet) error
|
2019-10-11 02:14:22 +00:00
|
|
|
ChainGetGenesis(context.Context) (*types.TipSet, error)
|
2019-10-15 05:00:30 +00:00
|
|
|
ChainTipSetWeight(context.Context, *types.TipSet) (types.BigInt, error)
|
2019-06-25 11:42:17 +00:00
|
|
|
|
2019-09-30 21:06:47 +00:00
|
|
|
// syncer
|
|
|
|
SyncState(context.Context) (*SyncState, error)
|
2019-10-14 14:21:37 +00:00
|
|
|
SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error
|
2019-09-30 21:06:47 +00:00
|
|
|
|
2019-06-25 11:42:17 +00:00
|
|
|
// messages
|
2019-07-26 04:54:22 +00:00
|
|
|
MpoolPending(context.Context, *types.TipSet) ([]*types.SignedMessage, error)
|
2019-10-08 09:17:03 +00:00
|
|
|
MpoolPush(context.Context, *types.SignedMessage) error // TODO: remove
|
2019-09-17 08:15:26 +00:00
|
|
|
MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) // get nonce, sign, push
|
2019-07-31 07:13:49 +00:00
|
|
|
MpoolGetNonce(context.Context, address.Address) (uint64, error)
|
2019-06-25 11:42:17 +00:00
|
|
|
|
2019-07-24 00:09:34 +00:00
|
|
|
// FullNodeStruct
|
2019-06-25 11:42:17 +00:00
|
|
|
|
|
|
|
// miner
|
|
|
|
|
2019-08-20 16:50:17 +00:00
|
|
|
MinerRegister(context.Context, address.Address) error
|
2019-08-20 18:05:17 +00:00
|
|
|
MinerUnregister(context.Context, address.Address) error
|
2019-08-21 15:14:38 +00:00
|
|
|
MinerAddresses(context.Context) ([]address.Address, error)
|
2019-09-18 02:50:03 +00:00
|
|
|
MinerCreateBlock(context.Context, address.Address, *types.TipSet, []*types.Ticket, types.ElectionProof, []*types.SignedMessage, uint64) (*types.BlockMsg, error)
|
2019-06-25 11:42:17 +00:00
|
|
|
|
|
|
|
// // UX ?
|
|
|
|
|
|
|
|
// wallet
|
|
|
|
|
2019-07-13 00:41:32 +00:00
|
|
|
WalletNew(context.Context, string) (address.Address, error)
|
2019-08-08 17:29:23 +00:00
|
|
|
WalletHas(context.Context, address.Address) (bool, error)
|
2019-07-13 00:41:32 +00:00
|
|
|
WalletList(context.Context) ([]address.Address, error)
|
2019-07-18 20:26:04 +00:00
|
|
|
WalletBalance(context.Context, address.Address) (types.BigInt, error)
|
2019-07-24 05:38:16 +00:00
|
|
|
WalletSign(context.Context, address.Address, []byte) (*types.Signature, error)
|
2019-08-09 15:59:12 +00:00
|
|
|
WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error)
|
2019-07-17 03:05:55 +00:00
|
|
|
WalletDefaultAddress(context.Context) (address.Address, error)
|
2019-10-17 10:18:40 +00:00
|
|
|
WalletSetDefault(context.Context, address.Address) error
|
2019-10-08 09:46:36 +00:00
|
|
|
WalletExport(context.Context, address.Address) (*types.KeyInfo, error)
|
|
|
|
WalletImport(context.Context, *types.KeyInfo) (address.Address, error)
|
2019-07-17 03:05:55 +00:00
|
|
|
|
2019-06-25 11:42:17 +00:00
|
|
|
// Other
|
|
|
|
|
2019-07-12 09:59:18 +00:00
|
|
|
// ClientImport imports file under the specified path into filestore
|
|
|
|
ClientImport(ctx context.Context, path string) (cid.Cid, error)
|
2019-08-07 20:06:10 +00:00
|
|
|
ClientStartDeal(ctx context.Context, data cid.Cid, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error)
|
2019-09-10 14:13:24 +00:00
|
|
|
ClientListDeals(ctx context.Context) ([]DealInfo, error)
|
2019-08-26 13:45:36 +00:00
|
|
|
ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error)
|
2019-08-26 18:23:11 +00:00
|
|
|
ClientFindData(ctx context.Context, root cid.Cid) ([]QueryOffer, error) // TODO: specify serialization mode we want (defaults to unixfs for now)
|
2019-08-27 22:10:23 +00:00
|
|
|
ClientRetrieve(ctx context.Context, order RetrievalOrder, path string) error
|
2019-09-13 21:00:36 +00:00
|
|
|
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error)
|
2019-08-01 17:12:41 +00:00
|
|
|
|
2019-07-12 09:59:18 +00:00
|
|
|
// ClientUnimport removes references to the specified file from filestore
|
|
|
|
//ClientUnimport(path string)
|
|
|
|
|
|
|
|
// ClientListImports lists imported files and their root CIDs
|
2019-07-12 10:44:01 +00:00
|
|
|
ClientListImports(ctx context.Context) ([]Import, error)
|
2019-07-12 09:59:18 +00:00
|
|
|
|
|
|
|
//ClientListAsks() []Ask
|
2019-08-07 06:35:57 +00:00
|
|
|
|
2019-09-18 00:08:49 +00:00
|
|
|
// if tipset is nil, we'll use heaviest
|
|
|
|
StateCall(context.Context, *types.Message, *types.TipSet) (*types.MessageReceipt, error)
|
2019-09-19 20:25:18 +00:00
|
|
|
StateReplay(context.Context, *types.TipSet, cid.Cid) (*ReplayResults, error)
|
2019-09-18 00:08:49 +00:00
|
|
|
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)
|
|
|
|
|
2019-08-07 06:35:57 +00:00
|
|
|
StateMinerSectors(context.Context, address.Address) ([]*SectorInfo, error)
|
2019-09-18 02:50:03 +00:00
|
|
|
StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*SectorInfo, error)
|
2019-08-21 16:31:14 +00:00
|
|
|
StateMinerPower(context.Context, address.Address, *types.TipSet) (MinerPower, error)
|
2019-09-03 04:36:07 +00:00
|
|
|
StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error)
|
2019-09-16 20:11:17 +00:00
|
|
|
StateMinerPeerID(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error)
|
2019-09-18 00:08:49 +00:00
|
|
|
StateMinerProvingPeriodEnd(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error)
|
2019-09-25 23:32:33 +00:00
|
|
|
StatePledgeCollateral(context.Context, *types.TipSet) (types.BigInt, error)
|
2019-10-08 05:51:34 +00:00
|
|
|
StateWaitMsg(context.Context, cid.Cid) (*MsgWait, error)
|
2019-10-12 06:45:48 +00:00
|
|
|
StateListMiners(context.Context, *types.TipSet) ([]address.Address, error)
|
|
|
|
StateListActors(context.Context, *types.TipSet) ([]address.Address, error)
|
2019-10-22 10:09:36 +00:00
|
|
|
StateMarketBalance(context.Context, address.Address, *types.TipSet) (actors.StorageParticipantBalance, error)
|
2019-10-22 19:29:05 +00:00
|
|
|
StateMarketParticipants(context.Context, *types.TipSet) (map[string]actors.StorageParticipantBalance, error)
|
|
|
|
StateMarketDeals(context.Context, *types.TipSet) (map[string]actors.OnChainDeal, error)
|
2019-08-09 21:41:50 +00:00
|
|
|
|
2019-09-16 13:46:05 +00:00
|
|
|
PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error)
|
2019-08-09 21:41:50 +00:00
|
|
|
PaychList(context.Context) ([]address.Address, error)
|
|
|
|
PaychStatus(context.Context, address.Address) (*PaychStatus, error)
|
2019-08-13 04:27:54 +00:00
|
|
|
PaychClose(context.Context, address.Address) (cid.Cid, error)
|
2019-09-16 13:46:05 +00:00
|
|
|
PaychAllocateLane(ctx context.Context, ch address.Address) (uint64, error)
|
2019-09-24 21:13:47 +00:00
|
|
|
PaychNewPayment(ctx context.Context, from, to address.Address, vouchers []VoucherSpec) (*PaymentInfo, error)
|
2019-08-12 17:09:56 +00:00
|
|
|
PaychVoucherCheckValid(context.Context, address.Address, *types.SignedVoucher) error
|
|
|
|
PaychVoucherCheckSpendable(context.Context, address.Address, *types.SignedVoucher, []byte, []byte) (bool, error)
|
2019-08-09 21:41:50 +00:00
|
|
|
PaychVoucherCreate(context.Context, address.Address, types.BigInt, uint64) (*types.SignedVoucher, error)
|
2019-09-16 21:25:23 +00:00
|
|
|
PaychVoucherAdd(context.Context, address.Address, *types.SignedVoucher, []byte, types.BigInt) (types.BigInt, error)
|
2019-08-09 21:41:50 +00:00
|
|
|
PaychVoucherList(context.Context, address.Address) ([]*types.SignedVoucher, error)
|
2019-08-13 04:27:54 +00:00
|
|
|
PaychVoucherSubmit(context.Context, address.Address, *types.SignedVoucher) (cid.Cid, error)
|
2019-07-24 00:09:34 +00:00
|
|
|
}
|
|
|
|
|
2019-10-18 03:01:55 +00:00
|
|
|
// StorageMiner is a low-level interface to the Filecoin network storage miner node
|
2019-07-24 00:09:34 +00:00
|
|
|
type StorageMiner interface {
|
|
|
|
Common
|
2019-07-27 01:54:03 +00:00
|
|
|
|
2019-10-14 02:32:32 +00:00
|
|
|
ActorAddress(context.Context) (address.Address, error)
|
2019-08-10 01:54:45 +00:00
|
|
|
|
2019-07-27 01:54:03 +00:00
|
|
|
// Temp api for testing
|
|
|
|
StoreGarbageData(context.Context) (uint64, error)
|
2019-07-27 21:08:10 +00:00
|
|
|
|
|
|
|
// Get the status of a given sector by ID
|
|
|
|
SectorsStatus(context.Context, uint64) (sectorbuilder.SectorSealingStatus, error)
|
|
|
|
|
|
|
|
// List all staged sectors
|
2019-10-14 02:32:32 +00:00
|
|
|
SectorsList(context.Context) ([]uint64, error)
|
2019-07-27 21:08:10 +00:00
|
|
|
|
|
|
|
// Seal all staged sectors
|
|
|
|
SectorsStagedSeal(context.Context) error
|
2019-08-26 10:04:57 +00:00
|
|
|
|
|
|
|
SectorsRefs(context.Context) (map[string][]SealedRef, error)
|
2019-06-25 11:42:17 +00:00
|
|
|
}
|
2019-08-09 21:41:50 +00:00
|
|
|
|
|
|
|
// Version provides various build-time information
|
|
|
|
type Version struct {
|
|
|
|
Version string
|
|
|
|
|
|
|
|
// APIVersion is a binary encoded semver version of the remote implementing
|
|
|
|
// this api
|
|
|
|
//
|
|
|
|
// See APIVersion in build/version.go
|
|
|
|
APIVersion uint32
|
|
|
|
|
|
|
|
// TODO: git commit / os / genesis cid?
|
2019-10-25 12:44:53 +00:00
|
|
|
|
|
|
|
// Seconds
|
|
|
|
BlockDelay uint64
|
2019-08-09 21:41:50 +00:00
|
|
|
}
|
|
|
|
|
2019-10-09 20:18:53 +00:00
|
|
|
func (v Version) String() string {
|
|
|
|
vM, vm, vp := build.VersionInts(v.APIVersion)
|
|
|
|
return fmt.Sprintf("%s+api%d.%d.%d", v.Version, vM, vm, vp)
|
|
|
|
}
|
|
|
|
|
2019-08-09 21:41:50 +00:00
|
|
|
type Import struct {
|
|
|
|
Status filestore.Status
|
|
|
|
Key cid.Cid
|
|
|
|
FilePath string
|
|
|
|
Size uint64
|
|
|
|
}
|
|
|
|
|
2019-09-10 14:13:24 +00:00
|
|
|
type DealInfo struct {
|
|
|
|
ProposalCid cid.Cid
|
|
|
|
State DealState
|
2019-10-22 10:09:36 +00:00
|
|
|
Provider address.Address
|
2019-09-10 14:48:54 +00:00
|
|
|
|
2019-10-22 10:09:36 +00:00
|
|
|
PieceRef []byte // cid bytes
|
2019-09-10 14:48:54 +00:00
|
|
|
Size uint64
|
|
|
|
|
|
|
|
TotalPrice types.BigInt
|
|
|
|
Duration uint64
|
2019-09-10 14:13:24 +00:00
|
|
|
}
|
|
|
|
|
2019-08-09 21:41:50 +00:00
|
|
|
type MsgWait struct {
|
|
|
|
Receipt types.MessageReceipt
|
2019-10-04 20:58:24 +00:00
|
|
|
TipSet *types.TipSet
|
2019-08-09 21:41:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type BlockMessages struct {
|
|
|
|
BlsMessages []*types.Message
|
|
|
|
SecpkMessages []*types.SignedMessage
|
2019-09-23 11:15:16 +00:00
|
|
|
|
|
|
|
Cids []cid.Cid
|
2019-08-09 21:41:50 +00:00
|
|
|
}
|
|
|
|
|
2019-10-06 00:37:28 +00:00
|
|
|
type Message struct {
|
|
|
|
Cid cid.Cid
|
|
|
|
Message *types.Message
|
|
|
|
}
|
|
|
|
|
2019-08-09 21:41:50 +00:00
|
|
|
type SectorInfo struct {
|
|
|
|
SectorID uint64
|
|
|
|
CommD []byte
|
|
|
|
CommR []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
type ActorState struct {
|
|
|
|
Balance types.BigInt
|
|
|
|
State interface{}
|
|
|
|
}
|
|
|
|
|
2019-09-06 22:39:47 +00:00
|
|
|
type PCHDir int
|
|
|
|
|
|
|
|
const (
|
|
|
|
PCHUndef PCHDir = iota
|
|
|
|
PCHInbound
|
|
|
|
PCHOutbound
|
|
|
|
)
|
|
|
|
|
2019-09-09 16:02:57 +00:00
|
|
|
type PaychStatus struct {
|
2019-09-06 22:39:47 +00:00
|
|
|
ControlAddr address.Address
|
|
|
|
Direction PCHDir
|
|
|
|
}
|
2019-08-21 16:31:14 +00:00
|
|
|
|
2019-09-13 14:11:40 +00:00
|
|
|
type ChannelInfo struct {
|
|
|
|
Channel address.Address
|
|
|
|
ChannelMessage cid.Cid
|
|
|
|
}
|
|
|
|
|
2019-09-10 13:43:01 +00:00
|
|
|
type PaymentInfo struct {
|
2019-09-13 14:11:40 +00:00
|
|
|
Channel address.Address
|
|
|
|
ChannelMessage *cid.Cid
|
2019-09-24 21:13:47 +00:00
|
|
|
Vouchers []*types.SignedVoucher
|
|
|
|
}
|
|
|
|
|
|
|
|
type VoucherSpec struct {
|
|
|
|
Amount types.BigInt
|
|
|
|
TimeLock uint64
|
|
|
|
MinClose uint64
|
|
|
|
|
|
|
|
Extra *types.ModVerifyParams
|
2019-09-10 13:43:01 +00:00
|
|
|
}
|
|
|
|
|
2019-08-21 16:31:14 +00:00
|
|
|
type MinerPower struct {
|
|
|
|
MinerPower types.BigInt
|
|
|
|
TotalPower types.BigInt
|
|
|
|
}
|
2019-08-26 10:04:57 +00:00
|
|
|
|
|
|
|
type SealedRef struct {
|
|
|
|
Piece string
|
|
|
|
Offset uint64
|
|
|
|
Size uint32
|
|
|
|
}
|
2019-08-26 13:45:36 +00:00
|
|
|
|
2019-08-26 18:23:11 +00:00
|
|
|
type QueryOffer struct {
|
2019-08-26 13:45:36 +00:00
|
|
|
Err string
|
|
|
|
|
2019-08-27 18:45:21 +00:00
|
|
|
Root cid.Cid
|
|
|
|
|
2019-08-26 13:45:36 +00:00
|
|
|
Size uint64
|
|
|
|
MinPrice types.BigInt
|
|
|
|
|
|
|
|
Miner address.Address
|
|
|
|
MinerPeerID peer.ID
|
|
|
|
}
|
2019-08-27 18:45:21 +00:00
|
|
|
|
|
|
|
func (o *QueryOffer) Order() RetrievalOrder {
|
|
|
|
return RetrievalOrder{
|
2019-09-16 13:46:05 +00:00
|
|
|
Root: o.Root,
|
|
|
|
Size: o.Size,
|
|
|
|
Total: o.MinPrice,
|
|
|
|
|
2019-08-27 18:45:21 +00:00
|
|
|
Miner: o.Miner,
|
|
|
|
MinerPeerID: o.MinerPeerID,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type RetrievalOrder struct {
|
2019-08-29 15:09:34 +00:00
|
|
|
// TODO: make this less unixfs specific
|
2019-08-27 18:45:21 +00:00
|
|
|
Root cid.Cid
|
|
|
|
Size uint64
|
|
|
|
// TODO: support offset
|
2019-09-16 13:46:05 +00:00
|
|
|
Total types.BigInt
|
2019-08-27 18:45:21 +00:00
|
|
|
|
2019-09-16 13:46:05 +00:00
|
|
|
Client address.Address
|
2019-08-27 18:45:21 +00:00
|
|
|
Miner address.Address
|
|
|
|
MinerPeerID peer.ID
|
|
|
|
}
|
2019-09-19 20:25:18 +00:00
|
|
|
|
|
|
|
type ReplayResults struct {
|
|
|
|
Msg *types.Message
|
|
|
|
Receipt *types.MessageReceipt
|
|
|
|
Error string
|
|
|
|
}
|
2019-09-30 21:06:47 +00:00
|
|
|
|
|
|
|
type SyncState struct {
|
|
|
|
Base *types.TipSet
|
|
|
|
Target *types.TipSet
|
|
|
|
|
2019-09-30 22:29:40 +00:00
|
|
|
Stage SyncStateStage
|
2019-09-30 21:06:47 +00:00
|
|
|
Height uint64
|
|
|
|
}
|
2019-09-30 22:29:40 +00:00
|
|
|
|
|
|
|
type SyncStateStage int
|
|
|
|
|
|
|
|
const (
|
|
|
|
StageIdle = SyncStateStage(iota)
|
|
|
|
StageHeaders
|
|
|
|
StagePersistHeaders
|
|
|
|
StageMessages
|
|
|
|
StageSyncComplete
|
|
|
|
)
|