Documentation ¶
Overview ¶
Package les implements the Light GoChain Subprotocol.
Package light implements on-demand retrieval capable state and chain objects for the Ethereum Light Client.
Package les implements the Light Ethereum Subprotocol.
Package les implements the Light Ethereum Subprotocol.
Package light implements on-demand retrieval capable state and chain objects for the Ethereum Light Client.
Package les implements the Light GoChain Subprotocol.
Package les implements the Light Ethereum Subprotocol.
Package les implements the Light Ethereum Subprotocol.
Package light implements on-demand retrieval capable state and chain objects for the Ethereum Light Client.
Package les implements the Light GoChain Subprotocol.
Package les implements the Light Ethereum Subprotocol.
Index ¶
- Constants
- Variables
- type BlockChain
- type BlockRequest
- type BloomReq
- type BloomRequest
- type ChtReq
- type ChtRequest
- type ChtResp
- type CodeData
- type CodeReq
- type CodeRequest
- type HelperTrieReq
- type HelperTrieResps
- type LesApiBackend
- func (b *LesApiBackend) AccountManager() *accounts.Manager
- func (b *LesApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error)
- func (b *LesApiBackend) BloomStatus() (uint64, uint64)
- func (b *LesApiBackend) ChainConfig() *params.ChainConfig
- func (b *LesApiBackend) ChainDb() common.Database
- func (b *LesApiBackend) CurrentBlock() *types.Block
- func (b *LesApiBackend) Downloader() *downloader.Downloader
- func (b *LesApiBackend) EventMux() *event.TypeMux
- func (b *LesApiBackend) GenesisAlloc() core.GenesisAlloc
- func (b *LesApiBackend) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error)
- func (b *LesApiBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, ...) (*vm.EVM, error)
- func (b *LesApiBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error)
- func (b *LesApiBackend) GetPoolTransaction(txHash common.Hash) *types.Transaction
- func (b *LesApiBackend) GetPoolTransactions() types.Transactions
- func (b *LesApiBackend) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)
- func (b *LesApiBackend) GetTd(blockHash common.Hash) *big.Int
- func (b *LesApiBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error)
- func (b *LesApiBackend) InitialSupply() *big.Int
- func (b *LesApiBackend) ProtocolVersion() int
- func (b *LesApiBackend) RemoveTx(txHash common.Hash)
- func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error
- func (b *LesApiBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession)
- func (b *LesApiBackend) SetHead(number uint64)
- func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error)
- func (b *LesApiBackend) StateQuery(ctx context.Context, blockNr rpc.BlockNumber, fn func(*state.StateDB) error) error
- func (b *LesApiBackend) Stats() (pending int, queued int)
- func (b *LesApiBackend) SubscribeChainEvent(ch chan<- core.ChainEvent)
- func (b *LesApiBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent)
- func (b *LesApiBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent)
- func (b *LesApiBackend) SubscribeLogsEvent(ch chan<- []*types.Log)
- func (b *LesApiBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent)
- func (b *LesApiBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent)
- func (b *LesApiBackend) SuggestPrice(ctx context.Context) (*big.Int, error)
- func (b *LesApiBackend) TxPoolContent(ctx context.Context) (map[common.Address]types.Transactions, map[common.Address]types.Transactions)
- func (b *LesApiBackend) UnsubscribeChainEvent(ch chan<- core.ChainEvent)
- func (b *LesApiBackend) UnsubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent)
- func (b *LesApiBackend) UnsubscribeChainSideEvent(ch chan<- core.ChainSideEvent)
- func (b *LesApiBackend) UnsubscribeLogsEvent(ch chan<- []*types.Log)
- func (b *LesApiBackend) UnsubscribeNewTxsEvent(ch chan<- core.NewTxsEvent)
- func (b *LesApiBackend) UnsubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent)
- type LesOdr
- func (odr *LesOdr) BloomIndexer() *core.ChainIndexer
- func (odr *LesOdr) BloomTrieIndexer() *core.ChainIndexer
- func (odr *LesOdr) ChtIndexer() *core.ChainIndexer
- func (odr *LesOdr) Database() common.Database
- func (odr *LesOdr) Retrieve(ctx context.Context, req light.OdrRequest) (err error)
- func (odr *LesOdr) Stop()
- type LesOdrRequest
- type LesServer
- type LesTxRelay
- type LightDummyAPI
- type LightGoChain
- func (s *LightGoChain) APIs() []rpc.API
- func (s *LightGoChain) BlockChain() *light.LightChain
- func (s *LightGoChain) Downloader() *downloader.Downloader
- func (s *LightGoChain) Engine() consensus.Engine
- func (s *LightGoChain) EventMux() *event.TypeMux
- func (s *LightGoChain) LesVersion() int
- func (s *LightGoChain) Protocols() []p2p.Protocol
- func (s *LightGoChain) ResetWithGenesisBlock(gb *types.Block)
- func (s *LightGoChain) Start(srvr *p2p.Server) error
- func (s *LightGoChain) Stop() error
- func (s *LightGoChain) TxPool() *light.TxPool
- type Msg
- type NodeInfo
- type ProofReq
- type ProtocolManager
- type ReceiptsRequest
- type RequestCostList
- type TrieRequest
Constants ¶
const ( MaxHeaderFetch = 192 // Amount of block headers to be fetched per retrieval request MaxBodyFetch = 32 // Amount of block bodies to be fetched per retrieval request MaxReceiptFetch = 128 // Amount of transaction receipts to allow fetching per request MaxCodeFetch = 64 // Amount of contract codes to allow fetching per request MaxProofsFetch = 64 // Amount of merkle proofs to be fetched per retrieval request MaxHelperTrieProofsFetch = 64 // Amount of merkle proofs to be fetched per retrieval request MaxTxSend = 64 // Amount of transactions to be send per request MaxTxStatus = 256 // Amount of transactions to queried per request )
const ( MsgBlockBodies = iota MsgCode MsgReceipts MsgProofsV1 MsgProofsV2 MsgHeaderProofs MsgHelperTrieProofs )
const ( NetworkId = 1 ProtocolMaxMsgSize = 10 * 1024 * 1024 // Maximum cap on the size of a protocol message )
const ( // Protocol messages belonging to LPV1 StatusMsg = 0x00 AnnounceMsg = 0x01 GetBlockHeadersMsg = 0x02 BlockHeadersMsg = 0x03 GetBlockBodiesMsg = 0x04 BlockBodiesMsg = 0x05 GetReceiptsMsg = 0x06 ReceiptsMsg = 0x07 GetProofsV1Msg = 0x08 ProofsV1Msg = 0x09 GetCodeMsg = 0x0a CodeMsg = 0x0b SendTxMsg = 0x0c GetHeaderProofsMsg = 0x0d HeaderProofsMsg = 0x0e // Protocol messages belonging to LPV2 GetProofsV2Msg = 0x0f ProofsV2Msg = 0x10 GetHelperTrieProofsMsg = 0x11 HelperTrieProofsMsg = 0x12 SendTxV2Msg = 0x13 GetTxStatusMsg = 0x14 TxStatusMsg = 0x15 )
les protocol message codes
const ( ErrMsgTooLarge = iota ErrDecode ErrInvalidMsgCode ErrProtocolVersionMismatch ErrNetworkIdMismatch ErrGenesisBlockMismatch ErrNoStatusMsg ErrExtraStatusMsg ErrSuspendedPeer ErrUselessPeer ErrRequestRejected ErrUnexpectedResponse ErrInvalidResponse ErrTooManyTimeouts ErrMissingKey )
Variables ¶
var ( ClientProtocolVersions = []uint{lpv2, lpv1} ServerProtocolVersions = []uint{lpv2, lpv1} AdvertiseProtocolVersions = []uint{lpv2} // clients are searching for the first advertised protocol in the list )
Supported versions of the les protocol (first is primary)
var ErrNoPeers = errors.New("no suitable peers available")
ErrNoPeers is returned if no peers capable of serving a queued request are available
var ProtocolLengths = map[uint]uint64{/* contains filtered or unexported fields */}
Number of implemented message corresponding to different protocol versions.
Functions ¶
This section is empty.
Types ¶
type BlockChain ¶
type BlockChain interface { Config() *params.ChainConfig HasHeader(hash common.Hash, number uint64) bool GetHeader(hash common.Hash, number uint64) *types.Header GetHeaderByHash(hash common.Hash) *types.Header CurrentHeader() *types.Header GetTd(hash common.Hash, number uint64) *big.Int State() (*state.StateDB, error) InsertHeaderChain(ctx context.Context, chain []*types.Header, checkFreq int) (int, error) Rollback(chain []common.Hash) GetHeaderByNumber(number uint64) *types.Header GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) Genesis() *types.Block SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) UnsubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) }
type BlockRequest ¶
type BlockRequest light.BlockRequest
BlockRequest is the ODR request type for block bodies
func (*BlockRequest) CanSend ¶
func (r *BlockRequest) CanSend(peer *peer) bool
CanSend tells if a certain peer is suitable for serving the given request
func (*BlockRequest) GetCost ¶
func (r *BlockRequest) GetCost(peer *peer) uint64
GetCost returns the cost of the given ODR request according to the serving peer's cost table (implementation of LesOdrRequest)
type BloomRequest ¶
type BloomRequest light.BloomRequest
ODR request type for requesting headers by Canonical Hash Trie, see LesOdrRequest interface
func (*BloomRequest) CanSend ¶
func (r *BloomRequest) CanSend(peer *peer) bool
CanSend tells if a certain peer is suitable for serving the given request
func (*BloomRequest) GetCost ¶
func (r *BloomRequest) GetCost(peer *peer) uint64
GetCost returns the cost of the given ODR request according to the serving peer's cost table (implementation of LesOdrRequest)
type ChtRequest ¶
type ChtRequest light.ChtRequest
ODR request type for requesting headers by Canonical Hash Trie, see LesOdrRequest interface
func (*ChtRequest) CanSend ¶
func (r *ChtRequest) CanSend(peer *peer) bool
CanSend tells if a certain peer is suitable for serving the given request
func (*ChtRequest) GetCost ¶
func (r *ChtRequest) GetCost(peer *peer) uint64
GetCost returns the cost of the given ODR request according to the serving peer's cost table (implementation of LesOdrRequest)
type CodeData ¶
type CodeData []struct { Value []byte }
CodeData is the network response packet for a node data retrieval.
type CodeRequest ¶
type CodeRequest light.CodeRequest
ODR request type for node data (used for retrieving contract code), see LesOdrRequest interface
func (*CodeRequest) CanSend ¶
func (r *CodeRequest) CanSend(peer *peer) bool
CanSend tells if a certain peer is suitable for serving the given request
func (*CodeRequest) GetCost ¶
func (r *CodeRequest) GetCost(peer *peer) uint64
GetCost returns the cost of the given ODR request according to the serving peer's cost table (implementation of LesOdrRequest)
type HelperTrieReq ¶
type HelperTrieResps ¶
type LesApiBackend ¶
type LesApiBackend struct {
// contains filtered or unexported fields
}
func (*LesApiBackend) AccountManager ¶
func (b *LesApiBackend) AccountManager() *accounts.Manager
func (*LesApiBackend) BlockByNumber ¶
func (b *LesApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error)
func (*LesApiBackend) BloomStatus ¶
func (b *LesApiBackend) BloomStatus() (uint64, uint64)
func (*LesApiBackend) ChainConfig ¶
func (b *LesApiBackend) ChainConfig() *params.ChainConfig
func (*LesApiBackend) ChainDb ¶
func (b *LesApiBackend) ChainDb() common.Database
func (*LesApiBackend) CurrentBlock ¶
func (b *LesApiBackend) CurrentBlock() *types.Block
func (*LesApiBackend) Downloader ¶
func (b *LesApiBackend) Downloader() *downloader.Downloader
func (*LesApiBackend) EventMux ¶
func (b *LesApiBackend) EventMux() *event.TypeMux
func (*LesApiBackend) GenesisAlloc ¶
func (b *LesApiBackend) GenesisAlloc() core.GenesisAlloc
func (*LesApiBackend) GetPoolNonce ¶
func (*LesApiBackend) GetPoolTransaction ¶
func (b *LesApiBackend) GetPoolTransaction(txHash common.Hash) *types.Transaction
func (*LesApiBackend) GetPoolTransactions ¶
func (b *LesApiBackend) GetPoolTransactions() types.Transactions
func (*LesApiBackend) GetReceipts ¶
func (*LesApiBackend) HeaderByNumber ¶
func (b *LesApiBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error)
func (*LesApiBackend) InitialSupply ¶
func (b *LesApiBackend) InitialSupply() *big.Int
func (*LesApiBackend) ProtocolVersion ¶
func (b *LesApiBackend) ProtocolVersion() int
func (*LesApiBackend) RemoveTx ¶
func (b *LesApiBackend) RemoveTx(txHash common.Hash)
func (*LesApiBackend) SendTx ¶
func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error
func (*LesApiBackend) ServiceFilter ¶
func (b *LesApiBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession)
func (*LesApiBackend) SetHead ¶
func (b *LesApiBackend) SetHead(number uint64)
func (*LesApiBackend) StateAndHeaderByNumber ¶
func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error)
func (*LesApiBackend) StateQuery ¶
func (b *LesApiBackend) StateQuery(ctx context.Context, blockNr rpc.BlockNumber, fn func(*state.StateDB) error) error
func (*LesApiBackend) Stats ¶
func (b *LesApiBackend) Stats() (pending int, queued int)
func (*LesApiBackend) SubscribeChainEvent ¶
func (b *LesApiBackend) SubscribeChainEvent(ch chan<- core.ChainEvent)
func (*LesApiBackend) SubscribeChainHeadEvent ¶
func (b *LesApiBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent)
func (*LesApiBackend) SubscribeChainSideEvent ¶
func (b *LesApiBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent)
func (*LesApiBackend) SubscribeLogsEvent ¶
func (b *LesApiBackend) SubscribeLogsEvent(ch chan<- []*types.Log)
func (*LesApiBackend) SubscribeNewTxsEvent ¶
func (b *LesApiBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent)
func (*LesApiBackend) SubscribeRemovedLogsEvent ¶
func (b *LesApiBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent)
func (*LesApiBackend) SuggestPrice ¶
func (*LesApiBackend) TxPoolContent ¶
func (b *LesApiBackend) TxPoolContent(ctx context.Context) (map[common.Address]types.Transactions, map[common.Address]types.Transactions)
func (*LesApiBackend) UnsubscribeChainEvent ¶
func (b *LesApiBackend) UnsubscribeChainEvent(ch chan<- core.ChainEvent)
func (*LesApiBackend) UnsubscribeChainHeadEvent ¶
func (b *LesApiBackend) UnsubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent)
func (*LesApiBackend) UnsubscribeChainSideEvent ¶
func (b *LesApiBackend) UnsubscribeChainSideEvent(ch chan<- core.ChainSideEvent)
func (*LesApiBackend) UnsubscribeLogsEvent ¶
func (b *LesApiBackend) UnsubscribeLogsEvent(ch chan<- []*types.Log)
func (*LesApiBackend) UnsubscribeNewTxsEvent ¶
func (b *LesApiBackend) UnsubscribeNewTxsEvent(ch chan<- core.NewTxsEvent)
func (*LesApiBackend) UnsubscribeRemovedLogsEvent ¶
func (b *LesApiBackend) UnsubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent)
type LesOdr ¶
type LesOdr struct {
// contains filtered or unexported fields
}
LesOdr implements light.OdrBackend
func NewLesOdr ¶
func NewLesOdr(db common.Database, chtIndexer, bloomTrieIndexer, bloomIndexer *core.ChainIndexer, retriever *retrieveManager) *LesOdr
func (*LesOdr) BloomIndexer ¶
func (odr *LesOdr) BloomIndexer() *core.ChainIndexer
BloomIndexer returns the bloombits chain indexer
func (*LesOdr) BloomTrieIndexer ¶
func (odr *LesOdr) BloomTrieIndexer() *core.ChainIndexer
BloomTrieIndexer returns the bloom trie chain indexer
func (*LesOdr) ChtIndexer ¶
func (odr *LesOdr) ChtIndexer() *core.ChainIndexer
ChtIndexer returns the CHT chain indexer
type LesOdrRequest ¶
type LesOdrRequest interface { GetCost(*peer) uint64 CanSend(*peer) bool Request(context.Context, uint64, *peer) error Validate(common.Database, *Msg) error }
func LesRequest ¶
func LesRequest(req light.OdrRequest) LesOdrRequest
type LesServer ¶
type LesServer struct {
// contains filtered or unexported fields
}
func NewLesServer ¶
func (*LesServer) SetBloomBitsIndexer ¶
func (s *LesServer) SetBloomBitsIndexer(bloomIndexer *core.ChainIndexer)
type LesTxRelay ¶
type LesTxRelay struct {
// contains filtered or unexported fields
}
func NewLesTxRelay ¶
func NewLesTxRelay(ps *peerSet, reqDist *requestDistributor) *LesTxRelay
func (*LesTxRelay) Discard ¶
func (self *LesTxRelay) Discard(hashes []common.Hash)
func (*LesTxRelay) Send ¶
func (self *LesTxRelay) Send(txs types.Transactions)
type LightDummyAPI ¶
type LightDummyAPI struct{}
func (*LightDummyAPI) Coinbase ¶
func (s *LightDummyAPI) Coinbase() (common.Address, error)
Coinbase is the address that mining rewards will be send to (alias for Etherbase)
func (*LightDummyAPI) Etherbase ¶
func (s *LightDummyAPI) Etherbase() (common.Address, error)
Etherbase is the address that mining rewards will be send to
func (*LightDummyAPI) Hashrate ¶
func (s *LightDummyAPI) Hashrate() hexutil.Uint
Hashrate returns the POW hashrate
func (*LightDummyAPI) Mining ¶
func (s *LightDummyAPI) Mining() bool
Mining returns an indication if this node is currently mining.
type LightGoChain ¶
type LightGoChain struct { ApiBackend *LesApiBackend // contains filtered or unexported fields }
func New ¶
func New(ctx context.Context, sctx *node.ServiceContext, config *eth.Config) (*LightGoChain, error)
func (*LightGoChain) APIs ¶
func (s *LightGoChain) APIs() []rpc.API
APIs returns the collection of RPC services the ethereum package offers. NOTE, some of these services probably need to be moved to somewhere else.
func (*LightGoChain) BlockChain ¶
func (s *LightGoChain) BlockChain() *light.LightChain
func (*LightGoChain) Downloader ¶
func (s *LightGoChain) Downloader() *downloader.Downloader
func (*LightGoChain) Engine ¶
func (s *LightGoChain) Engine() consensus.Engine
func (*LightGoChain) EventMux ¶
func (s *LightGoChain) EventMux() *event.TypeMux
func (*LightGoChain) LesVersion ¶
func (s *LightGoChain) LesVersion() int
func (*LightGoChain) Protocols ¶
func (s *LightGoChain) Protocols() []p2p.Protocol
Protocols implements node.Service, returning all the currently configured network protocols to start.
func (*LightGoChain) ResetWithGenesisBlock ¶
func (s *LightGoChain) ResetWithGenesisBlock(gb *types.Block)
func (*LightGoChain) Start ¶
func (s *LightGoChain) Start(srvr *p2p.Server) error
Start implements node.Service, starting all internal goroutines needed by the GoChain protocol implementation.
func (*LightGoChain) Stop ¶
func (s *LightGoChain) Stop() error
Stop implements node.Service, terminating all internal goroutines used by the GoChain protocol.
func (*LightGoChain) TxPool ¶
func (s *LightGoChain) TxPool() *light.TxPool
type NodeInfo ¶
type NodeInfo struct { Network uint64 `json:"network"` // Ethereum network ID (1=Frontier, 2=Morden, Ropsten=3, Rinkeby=4) Difficulty *big.Int `json:"difficulty"` // Total difficulty of the host's blockchain Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis block Config *params.ChainConfig `json:"config"` // Chain configuration for the fork rules Head common.Hash `json:"head"` // SHA3 hash of the host's best owned block }
NodeInfo represents a short summary of the Ethereum sub-protocol metadata known about the host peer.
type ProtocolManager ¶
type ProtocolManager struct { SubProtocols []p2p.Protocol // contains filtered or unexported fields }
func NewProtocolManager ¶
func NewProtocolManager(ctx context.Context, chainConfig *params.ChainConfig, lightSync bool, protocolVersions []uint, networkId uint64, mux *event.TypeMux, peers *peerSet, blockchain BlockChain, txpool txPool, chainDb common.Database, odr *LesOdr, txrelay *LesTxRelay, quitSync chan struct{}, wg *sync.WaitGroup) (*ProtocolManager, error)
NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable with the ethereum network.
func (*ProtocolManager) NodeInfo ¶
func (pm *ProtocolManager) NodeInfo() *NodeInfo
NodeInfo retrieves some protocol metadata about the running host node.
func (*ProtocolManager) Start ¶
func (pm *ProtocolManager) Start(maxPeers int)
func (*ProtocolManager) Stop ¶
func (pm *ProtocolManager) Stop()
type ReceiptsRequest ¶
type ReceiptsRequest light.ReceiptsRequest
ReceiptsRequest is the ODR request type for block receipts by block hash
func (*ReceiptsRequest) CanSend ¶
func (r *ReceiptsRequest) CanSend(peer *peer) bool
CanSend tells if a certain peer is suitable for serving the given request
func (*ReceiptsRequest) GetCost ¶
func (r *ReceiptsRequest) GetCost(peer *peer) uint64
GetCost returns the cost of the given ODR request according to the serving peer's cost table (implementation of LesOdrRequest)
type RequestCostList ¶
type RequestCostList []struct { MsgCode, BaseCost, ReqCost uint64 }
type TrieRequest ¶
type TrieRequest light.TrieRequest
ODR request type for state/storage trie entries, see LesOdrRequest interface
func (*TrieRequest) CanSend ¶
func (r *TrieRequest) CanSend(peer *peer) bool
CanSend tells if a certain peer is suitable for serving the given request
func (*TrieRequest) GetCost ¶
func (r *TrieRequest) GetCost(peer *peer) uint64
GetCost returns the cost of the given ODR request according to the serving peer's cost table (implementation of LesOdrRequest)
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package flowcontrol implements a client side flow control mechanism Package flowcontrol implements a client side flow control mechanism
|
Package flowcontrol implements a client side flow control mechanism Package flowcontrol implements a client side flow control mechanism |