-
Notifications
You must be signed in to change notification settings - Fork 778
Add p2p.Network
component
#2283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
39 commits
Select commit
Hold shift + click to select a range
c073533
p2p network
joshua-kim ec6b9f9
add test
joshua-kim b84be08
nit
joshua-kim 74765cb
nit
joshua-kim c54c7d5
go mod
joshua-kim f61113e
refactor validators
joshua-kim f377a8b
nit
joshua-kim 2995647
nit
joshua-kim accd487
nit
joshua-kim be9e25a
nit
joshua-kim e1b726d
Merge branch 'dev' into network
joshua-kim f35fc75
nit
joshua-kim bc0c84a
Merge branch 'dev' into network
joshua-kim 15a7af6
Merge branch 'dev' into network
joshua-kim 2627182
Update network/p2p/validators.go
joshua-kim 5b1d64a
Update network/p2p/network.go
joshua-kim f62f91a
Update network/p2p/network_test.go
joshua-kim 4854748
Update network/p2p/network_test.go
joshua-kim d0440e8
Update network/p2p/validators_test.go
joshua-kim 35ef6fe
unexport clientOptions
joshua-kim 97bf26f
fix
joshua-kim e741d12
fix bug
joshua-kim 1568dc7
nit
joshua-kim b6565dd
nit
joshua-kim 438a0ab
nit
joshua-kim 7c4a2af
Merge branch 'dev' into network
joshua-kim 3cc6218
fix
joshua-kim af2740d
nit
joshua-kim e2781cf
nit
joshua-kim f512ead
nit
joshua-kim 741f612
nti
joshua-kim bfa0638
Update network/p2p/validators.go
joshua-kim 4701b31
nit
joshua-kim 3a8cca5
Merge branch 'dev' into network
joshua-kim ee0eb08
nit
joshua-kim 5fde830
tidy
joshua-kim 6870966
Merge branch 'dev' into network
StephenButtolph 7295103
Update coreth
StephenButtolph 521f8c8
Merge branch 'dev' into network
StephenButtolph File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. | ||
// See the file LICENSE for licensing terms. | ||
|
||
package p2p | ||
|
||
import ( | ||
"context" | ||
"encoding/binary" | ||
"sync" | ||
"time" | ||
|
||
"github.com/prometheus/client_golang/prometheus" | ||
|
||
"github.com/ava-labs/avalanchego/ids" | ||
"github.com/ava-labs/avalanchego/snow/engine/common" | ||
"github.com/ava-labs/avalanchego/snow/validators" | ||
"github.com/ava-labs/avalanchego/utils/logging" | ||
"github.com/ava-labs/avalanchego/utils/set" | ||
"github.com/ava-labs/avalanchego/version" | ||
) | ||
|
||
var ( | ||
_ validators.Connector = (*Network)(nil) | ||
_ common.AppHandler = (*Network)(nil) | ||
_ NodeSampler = (*peerSampler)(nil) | ||
) | ||
|
||
// ClientOption configures Client | ||
type ClientOption interface { | ||
apply(options *clientOptions) | ||
} | ||
|
||
type clientOptionFunc func(options *clientOptions) | ||
|
||
func (o clientOptionFunc) apply(options *clientOptions) { | ||
o(options) | ||
} | ||
|
||
// WithValidatorSampling configures Client.AppRequestAny to sample validators | ||
func WithValidatorSampling(validators *Validators) ClientOption { | ||
return clientOptionFunc(func(options *clientOptions) { | ||
options.nodeSampler = validators | ||
}) | ||
} | ||
|
||
// clientOptions holds client-configurable values | ||
type clientOptions struct { | ||
// nodeSampler is used to select nodes to route Client.AppRequestAny to | ||
nodeSampler NodeSampler | ||
} | ||
|
||
// NewNetwork returns an instance of Network | ||
func NewNetwork( | ||
log logging.Logger, | ||
sender common.AppSender, | ||
metrics prometheus.Registerer, | ||
namespace string, | ||
) *Network { | ||
return &Network{ | ||
Peers: &Peers{}, | ||
log: log, | ||
sender: sender, | ||
metrics: metrics, | ||
namespace: namespace, | ||
router: newRouter(log, sender, metrics, namespace), | ||
} | ||
} | ||
|
||
// Network exposes networking state and supports building p2p application | ||
// protocols | ||
type Network struct { | ||
Peers *Peers | ||
|
||
log logging.Logger | ||
sender common.AppSender | ||
metrics prometheus.Registerer | ||
namespace string | ||
|
||
router *router | ||
} | ||
|
||
func (n *Network) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, request []byte) error { | ||
return n.router.AppRequest(ctx, nodeID, requestID, deadline, request) | ||
} | ||
|
||
func (n *Network) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error { | ||
return n.router.AppResponse(ctx, nodeID, requestID, response) | ||
} | ||
|
||
func (n *Network) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { | ||
return n.router.AppRequestFailed(ctx, nodeID, requestID) | ||
} | ||
|
||
func (n *Network) AppGossip(ctx context.Context, nodeID ids.NodeID, msg []byte) error { | ||
return n.router.AppGossip(ctx, nodeID, msg) | ||
} | ||
|
||
func (n *Network) CrossChainAppRequest(ctx context.Context, chainID ids.ID, requestID uint32, deadline time.Time, request []byte) error { | ||
return n.router.CrossChainAppRequest(ctx, chainID, requestID, deadline, request) | ||
} | ||
|
||
func (n *Network) CrossChainAppResponse(ctx context.Context, chainID ids.ID, requestID uint32, response []byte) error { | ||
return n.router.CrossChainAppResponse(ctx, chainID, requestID, response) | ||
} | ||
|
||
func (n *Network) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32) error { | ||
return n.router.CrossChainAppRequestFailed(ctx, chainID, requestID) | ||
} | ||
|
||
func (n *Network) Connected(_ context.Context, nodeID ids.NodeID, _ *version.Application) error { | ||
n.Peers.add(nodeID) | ||
return nil | ||
} | ||
|
||
func (n *Network) Disconnected(_ context.Context, nodeID ids.NodeID) error { | ||
n.Peers.remove(nodeID) | ||
return nil | ||
} | ||
|
||
// NewAppProtocol reserves an identifier for an application protocol handler and | ||
// returns a Client that can be used to send messages for the corresponding | ||
// protocol. | ||
func (n *Network) NewAppProtocol(handlerID uint64, handler Handler, options ...ClientOption) (*Client, error) { | ||
if err := n.router.addHandler(handlerID, handler); err != nil { | ||
return nil, err | ||
} | ||
|
||
client := &Client{ | ||
handlerID: handlerID, | ||
handlerPrefix: binary.AppendUvarint(nil, handlerID), | ||
sender: n.sender, | ||
router: n.router, | ||
options: &clientOptions{ | ||
nodeSampler: &peerSampler{ | ||
peers: n.Peers, | ||
}, | ||
}, | ||
} | ||
|
||
for _, option := range options { | ||
option.apply(client.options) | ||
} | ||
|
||
return client, nil | ||
} | ||
|
||
// Peers contains metadata about the current set of connected peers | ||
type Peers struct { | ||
lock sync.RWMutex | ||
set set.SampleableSet[ids.NodeID] | ||
} | ||
|
||
func (p *Peers) add(nodeID ids.NodeID) { | ||
p.lock.Lock() | ||
defer p.lock.Unlock() | ||
|
||
p.set.Add(nodeID) | ||
} | ||
|
||
func (p *Peers) remove(nodeID ids.NodeID) { | ||
p.lock.Lock() | ||
defer p.lock.Unlock() | ||
|
||
p.set.Remove(nodeID) | ||
} | ||
|
||
func (p *Peers) has(nodeID ids.NodeID) bool { | ||
p.lock.RLock() | ||
defer p.lock.RUnlock() | ||
|
||
return p.set.Contains(nodeID) | ||
} | ||
|
||
// Sample returns a pseudo-random sample of up to limit Peers | ||
func (p *Peers) Sample(limit int) []ids.NodeID { | ||
p.lock.RLock() | ||
defer p.lock.RUnlock() | ||
|
||
return p.set.Sample(limit) | ||
} | ||
|
||
type peerSampler struct { | ||
peers *Peers | ||
} | ||
|
||
func (p peerSampler) Sample(_ context.Context, limit int) []ids.NodeID { | ||
return p.peers.Sample(limit) | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.