Skip to content
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

[P2P] Integrate background router #732

Merged
merged 70 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
fe24824
refactor: unicast router
bryanchriswhite Jun 19, 2023
1277859
chore: cleanup TODOs
bryanchriswhite Jun 22, 2023
871af48
chore: add background message
bryanchriswhite Jun 16, 2023
013c433
chore: add `Router#Close()`
bryanchriswhite Jun 22, 2023
4f998ee
chore: separate raintree & bg protocol IDs
bryanchriswhite Jun 22, 2023
1c9c18c
chore: generate `PocketEnvelope` nonce in `PackMessage()`
bryanchriswhite Jun 22, 2023
f9a0c10
refactor: add `Handler` to router config validation
bryanchriswhite Jun 22, 2023
0bdffbd
refactor: raintree router
bryanchriswhite Jun 22, 2023
2b40776
refactor: background router
bryanchriswhite Jun 22, 2023
213f294
refactor: integrate bg router
bryanchriswhite Jun 22, 2023
437afc8
refactor: staked actor router peer discovery
bryanchriswhite Jun 22, 2023
43cf671
test: post-refactor updates
bryanchriswhite Jun 22, 2023
4b19d8f
Merge remote-tracking branch 'pokt/main' into refactor/unicast-router
bryanchriswhite Jun 22, 2023
cf886a7
Merge branch 'refactor/unicast-router' into feat/integrate-bg-router
bryanchriswhite Jun 22, 2023
048e306
fix: gofmt
bryanchriswhite Jun 23, 2023
d7278b8
Merge remote-tracking branch 'pokt/main' into refactor/unicast-router
bryanchriswhite Jun 23, 2023
acc1d59
Merge branch 'refactor/unicast-router' into feat/integrate-bg-router
bryanchriswhite Jun 23, 2023
9ab2a5d
chore: fix typo in comment
bryanchriswhite Jun 26, 2023
dce1bac
chore: add debug log
bryanchriswhite Jun 26, 2023
8dc2852
chore: fix field comment out of place
bryanchriswhite Jun 26, 2023
a6d4b52
fix: imports
bryanchriswhite Jun 26, 2023
87d1fa9
Merge branch 'refactor/unicast-router' into feat/integrate-bg-router
bryanchriswhite Jun 26, 2023
d24407b
chore: bootstrap refactor / TECHDEBT
bryanchriswhite Jun 26, 2023
70ca573
fix: imports
bryanchriswhite Jun 26, 2023
8467f3a
chore: remove unused field
bryanchriswhite Jun 26, 2023
c3bc4c7
chore: cleanup unused test utils
bryanchriswhite Jun 27, 2023
3fdada6
chore: comment cleanup
bryanchriswhite Jun 28, 2023
39a7877
chore: add submodule TECHDEBT comments
bryanchriswhite Jun 28, 2023
049cbf5
chore: add missing godoc comments
bryanchriswhite Jun 28, 2023
79a1c6e
chore: cleanup unused garbage
bryanchriswhite Jun 28, 2023
a7c4bf6
fix: return error
bryanchriswhite Jun 28, 2023
904f17b
Merge remote-tracking branch 'pokt/main' into refactor/unicast-router
bryanchriswhite Jun 28, 2023
70b020b
Merge branch 'refactor/unicast-router' into feat/integrate-bg-router
bryanchriswhite Jun 28, 2023
8a54f1a
chore: router logging improvements
bryanchriswhite Jun 28, 2023
6795c96
fix: interim background router bootstrapping
bryanchriswhite Jun 28, 2023
0a3fac1
fix: `p2pModule#Send()` routing logic
bryanchriswhite Jun 28, 2023
b8f9a1a
chore: improve variable naming
bryanchriswhite Jun 28, 2023
de63d6d
chore: improve comments
bryanchriswhite Jun 28, 2023
1282e1a
chore: improve debug logging
bryanchriswhite Jun 28, 2023
5793b7f
chore: return early
bryanchriswhite Jun 28, 2023
95a3948
chore: add TECHDEBT comment
bryanchriswhite Jun 29, 2023
7cdc9e7
Merge remote-tracking branch 'pokt/main' into HEAD
bryanchriswhite Jun 29, 2023
fe42ab3
test: fix raintree message target test
bryanchriswhite Jun 29, 2023
60cd2bd
docs: update P2P readme
bryanchriswhite Jun 29, 2023
8354d79
docs: update table of contents
bryanchriswhite Jun 29, 2023
f7b0202
docs: tweak P2P readme
bryanchriswhite Jun 29, 2023
d2f33a4
chore: add godoc comment
bryanchriswhite Jun 29, 2023
b527d91
chore: remove warning log
bryanchriswhite Jun 29, 2023
73da86c
chore: convert `DISCUSS_THIS_COMMIT` to `TECHDEBT`
bryanchriswhite Jun 29, 2023
bf96542
Merge remote-tracking branch 'pokt/main' into feat/integrate-bg-router
bryanchriswhite Jun 30, 2023
4602283
fix: typo
bryanchriswhite Jul 3, 2023
65a8c94
chore: review suggestion improvements
bryanchriswhite Jul 4, 2023
519db25
fix: gofmt
bryanchriswhite Jul 4, 2023
7e7e6e7
docs: README improvements (review feedback)
bryanchriswhite Jul 4, 2023
f3437cb
docs: add architecture design language section
bryanchriswhite Jul 4, 2023
4f87921
chore: background router comment and var name cleanup
bryanchriswhite Jul 4, 2023
c113a36
chore: review feedback improvements
bryanchriswhite Jul 6, 2023
3356f63
chore: add issue # to TECHDEBT comment
bryanchriswhite Jul 6, 2023
157ecb6
docs: update TOC
bryanchriswhite Jul 6, 2023
30cf145
chore: add TODO README
bryanchriswhite Jul 6, 2023
40628c4
docs: improve legend definitions
bryanchriswhite Jul 6, 2023
8c0b8c3
docs: clarify broadcast table
bryanchriswhite Jul 6, 2023
5a4cc80
docs: fix mistake in peer discovery section
bryanchriswhite Jul 7, 2023
3e997f5
test: improve background router validation test
bryanchriswhite Jul 7, 2023
abd4789
chore: add error log
bryanchriswhite Jul 7, 2023
8c6ac68
fix: unstaked actor bootstrapping FSM transition
bryanchriswhite Jul 7, 2023
b76efdf
fix: goimports
bryanchriswhite Jul 7, 2023
66afa18
Merge remote-tracking branch 'pokt/main' into feat/integrate-bg-router
bryanchriswhite Jul 7, 2023
5aa0a5c
docs: update unicast/broadcast table
bryanchriswhite Jul 11, 2023
6fde86f
Merge branch 'main' into feat/integrate-bg-router
bryanchriswhite Jul 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 66 additions & 6 deletions p2p/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,22 @@ See [`raintree/router.go`](./raintree/router.go) for the specific implementation

## Module Architecture

### Architecture Design Language
bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved

The architecture design language expressed in this documentation is based on [UML](https://www.uml-diagrams.org/).
Due to limitations in the current version of mermaid, class diagrams are much more adherant to the UML component specification.
Component diagrams however are much more loosely inspired by their UML counterparts.

Regardless, each architecture diagram should be accompanied by a legend which covers all the design language features used to provide disambiguation.

References:
- [Class Diagrams](https://www.uml-diagrams.org/class-diagrams-overview.html)
- [Component Diagrams](https://www.uml-diagrams.org/component-diagrams.html)

_NOTE: mermaid does not support ports, interfaces, ... in component diagrams ("flowcharts)._

### Legends
bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved

```mermaid
flowchart
subgraph Legend
Expand All @@ -89,13 +104,13 @@ classDiagram
class ConcreteType {
+ExportedField
-unexportedField
+ExportedMethod(argType) returnType
-unexportedMethod()
+ExportedMethod(...argTypes) (...returnTypes)
-unexportedMethod(...argTypes) (...returnTypes)
}

class InterfaceType {
<<interface>>
+Method(argType) (returnType1, returnType2)
+Method(...argTypes) (...returnTypes)
}

ConcreteType --|> InterfaceType : Interface realization
Expand All @@ -106,9 +121,48 @@ ConcreteType --* OtherType : Aggregatation
ConcreteType ..* "(cardinality)" OtherType : Indirect (via interface)
bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved
```

#### Interface Realization

bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved
> Realization is a specialized abstraction relationship between two sets of model elements, one representing a specification (the supplier) and the other represents an implementation of the latter (the client).

> Realization can be used to model stepwise refinement, optimizations, transformations, templates, model synthesis, framework composition, etc.

_(see: [UML Realization](https://www.uml-diagrams.org/realization.html))_

#### Direct Usage

bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved
> Dependency is a directed relationship which is used to show that some UML element or a set of elements requires, needs or depends on other model elements for specification or implementation. Because of this, dependency is called a supplier - client relationship, where supplier provides something to the client, and thus the client is in some sense incomplete while semantically or structurally dependent on the supplier element(s). Modification of the supplier may impact the client elements.

> Usage is a dependency in which one named element (client) requires another named element (supplier) for its full definition or implementation.

_(see: [UML Dependency](https://www.uml-diagrams.org/dependency.html))_

#### Composition

bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved
> A "strong" form of aggregation

> If a composite (whole) is deleted, all of its composite parts are "normally" deleted with it.

_(see: [UML Shared composition](https://www.uml-diagrams.org/composition.html))_

#### Aggregation

bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved
> A "weak" form of composition

> Shared part could be included in several composites, and if some or all of the composites are deleted, shared part may still exist.

_(see: [UML Shared aggregation](https://www.uml-diagrams.org/aggregation.html))_

#### Cardinality

bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved
Cardinality indicates the number or range of simultaneous instances of the classifier at the "cardinality-side" association end that are associated with the classifier at the other end of the given association type.

_(see: [UML Association](https://www.uml-diagrams.org/association.html#association-end))_


### P2P Module / Router Decoupling

The P2P module encapsulates the `RaiTreeRouter` and `BackgroundRouter` submodules.
The P2P module encapsulates the `RainTreeRouter` and `BackgroundRouter` submodules.
The P2P module internally refers to these as the `stakedActorRouter` and `unstakedActorRouter`, respectively.

Depending on the necessary routing scheme (unicast / broadcast) and whether the peers involved are staked actors, a node will use one or both of these routers.
Expand Down Expand Up @@ -337,6 +391,8 @@ Messages MUST be deduplicated before broadcasting their respective event over th

The responsibility of deduplication is encapsulated by the P2P module, As such duplicate messages may come from multiple routers in some of these scenarios.

The `NondeDeduper` state is not persisted outside of memory and therefore is cleared during node restarts.

```mermaid
classDiagram
class RainTreeMessage {
Expand Down Expand Up @@ -420,7 +476,12 @@ classDiagram
p2pModule --* NonceDeduper
```

#### Configuration

The size of the `NonceDeduper` queue is configurable via the `P2PConfig.MaxNonces` field.

### Peer Discovery

Peer discovery involves pairing peer IDs to their network addresses (multiaddr).
bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved
This pairing always has an associated TTL (time-to-live), near the end of which it must
be refreshed.
Expand Down Expand Up @@ -489,8 +550,7 @@ flowchart TD

### Raintree Router Architecture

_DISCUSS(team): If you feel this needs a diagram, please reach out to the team for additional details._
_TODO(olshansky, BenVan): Link to RainTree visualizations once it is complete._
_NOTE: If you (the reader) feel this needs a diagram, please reach out to the team for additional details._

### Code Organization

Expand Down
21 changes: 15 additions & 6 deletions p2p/background/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type backgroundRouter struct {
host libp2pHost.Host
// cancelReadSubscription is the cancel function for the context which is
// monitored in the `#readSubscription()` go routine. Call to terminate it.
// only one read subscription exists per router at any point in time
cancelReadSubscription context.CancelFunc
bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved

// Fields below are assigned during creation via `#setupDependencies()`.
Expand Down Expand Up @@ -215,6 +216,7 @@ func (rtr *backgroundRouter) setupUnicastRouter() error {
}

func (rtr *backgroundRouter) setupDependencies(ctx context.Context, cfg *config.BackgroundConfig) error {
Olshansk marked this conversation as resolved.
Show resolved Hide resolved
bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved
// NB: The order in which the internal components are setup below is important
if err := rtr.setupUnicastRouter(); err != nil {
return err
}
Expand All @@ -237,7 +239,9 @@ func (rtr *backgroundRouter) setupDependencies(ctx context.Context, cfg *config.

if err := rtr.setupPeerstore(
ctx,
cfg.PeerstoreProvider, cfg.CurrentHeightProvider); err != nil {
cfg.PeerstoreProvider,
cfg.CurrentHeightProvider,
); err != nil {
return fmt.Errorf("setting up peerstore: %w", err)
}
return nil
Expand All @@ -263,6 +267,7 @@ func (rtr *backgroundRouter) setupPeerstore(
return nil
}

// setupPeerDiscovery sets up the Kademlia Distributed Hash Table (DHT)
func (rtr *backgroundRouter) setupPeerDiscovery(ctx context.Context) (err error) {
bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved
dhtMode := dht.ModeAutoServer
// NB: don't act as a bootstrap node in peer discovery in client debug mode
Expand All @@ -274,6 +279,7 @@ func (rtr *backgroundRouter) setupPeerDiscovery(ctx context.Context) (err error)
return err
}

// setupPubsub sets up a new gossip sub topic using libp2p
func (rtr *backgroundRouter) setupPubsub(ctx context.Context) (err error) {
bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved
// TECHDEBT(#730): integrate libp2p tracing via `pubsub.WithEventTracer()`.

Expand Down Expand Up @@ -313,8 +319,8 @@ func (rtr *backgroundRouter) setupSubscription() (err error) {
}

func (rtr *backgroundRouter) bootstrap(ctx context.Context) error {
// CONSIDERATION: add `GetPeers` method to `PeerstoreProvider` interface
// to avoid this loop.
// CONSIDERATION: add `GetPeers` method, which returns a map,
// to the `PeerstoreProvider` interface to simplify this loop.
for _, peer := range rtr.pstore.GetPeerList() {
if err := utils.AddPeerToLibp2pHost(rtr.host, peer); err != nil {
return err
Expand Down Expand Up @@ -356,18 +362,21 @@ func (rtr *backgroundRouter) topicValidator(_ context.Context, _ libp2pPeer.ID,
}

if backgroundMsg.Data == nil {
rtr.logger.Debug().Msg("no data in Background message")
return false
bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved
}

networkMessage := messaging.PocketEnvelope{}
if err := proto.Unmarshal(backgroundMsg.Data, &networkMessage); err != nil {
rtr.logger.Error().Err(err).Msg("Error decoding network message")
poktEnvelope := messaging.PocketEnvelope{}
if err := proto.Unmarshal(backgroundMsg.Data, &poktEnvelope); err != nil {
rtr.logger.Error().Err(err).Msg("Error decoding Background message")
return false
}

return true
}

// readSubscription is a while loop for receiving and handling messages from the
// subscription. It is intended to be called as a goroutine.
func (rtr *backgroundRouter) readSubscription(ctx context.Context) {
bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved
for {
if err := ctx.Err(); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion p2p/event_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func (m *p2pModule) HandleEvent(event *anypb.Any) error {
if isStaked, err := m.isStakedActor(); err != nil {
return err
} else if !isStaked {
return nil
return nil // unstaked actors do not use RainTree and therefore do not need to update this router
}

oldPeerList := m.stakedActorRouter.GetPeerstore().GetPeerList()
Expand Down
4 changes: 2 additions & 2 deletions p2p/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func createP2PModules(t *testing.T, busMocks []*mockModules.MockBus, netMock moc
p2pMod, err := Create(
busMocks[i],
WithHost(host),
// mock background router to prevent background message propagation.
// mock background router to prevent & ignore background message propagation.
WithUnstakedActorRouter(noopBackgroundRouterMock),
)
require.NoError(t, err)
Expand Down Expand Up @@ -226,7 +226,7 @@ func createMockBus(
if readWriteWaitGroup != nil {
readWriteWaitGroup.Done()
}
}).AnyTimes() // TODO: specific times
}).AnyTimes() // TECHDEBT: assert number of times. Consider `waitForEventsInternal` or similar as in consensus.
mockBus.EXPECT().PublishEventToBus(gomock.Any()).AnyTimes()
return mockBus
}
Expand Down