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] Background gossip using libp2p-pubsub #505

Closed
4 of 11 tasks
jessicadaugherty opened this issue Feb 13, 2023 · 1 comment · Fixed by #844 or #732 · May be fixed by #694
Closed
4 of 11 tasks

[P2P] Background gossip using libp2p-pubsub #505

jessicadaugherty opened this issue Feb 13, 2023 · 1 comment · Fixed by #844 or #732 · May be fixed by #694
Assignees
Labels
p2p P2P specific changes

Comments

@jessicadaugherty
Copy link
Contributor

jessicadaugherty commented Feb 13, 2023

Objective

Add "random gossip" broadcast layer (i.e. in addition to raintree) in P2P module using go-libp2p-pubsub to support full-node participation and provide basic raintree redundancy.

Origin Document

Opportunity identified while integrating Pocket with LibP2P in #347

P2P currently only supports network broadcasting via raintree which in insufficient for full-node participation. The raintree algorithm requires trust in (and/or an effective disincentive against) the entire set of recipients in order to guarantee complete message propagation. For this reason an alternative broadcast mechanism must be used to support full-node participation in P2P (and, by extension, higher-level things like consensus).

Goals

  • Determine a reliable, scalable, and customizable broadcasting protocol that has minimal network overhead
  • Install and configure a broadcast protocol in the libp2p integration for full node random gossip

Deliverable

  • Research the tradeoffs between gossipsub and randomsub (ADR)
  • Integrate the background router with the P2P module
    • handle incoming messages from background router sources
    • include background router in P2P module broadcast implementation
  • Wrap background router messages in new BackgroundMessage protobuf type

Integration / Architecture

Legends:

flowchart
subgraph Legend
    m[[`Method`]]
    c[Component]

    m -- "unconditional usage" --> c
    m -. "conditional usage" .-> c
end
Loading
classDiagram
class ConcreteType {
  +ExportedField
  -unexportedField
  +ExportedMethod(argType) returnType
  -unexportedMethod()
}

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

ConcreteType --|> InterfaceType : Interface realization

ConcreteType --> OtherType : Direct usage
ConcreteType --o OtherType : Composition
ConcreteType --* OtherType : Aggregatation
ConcreteType ..*  "(cardinality)" OtherType : Indirect (via interface)
Loading

Outgoing messages:

flowchart
    subgraph p2p[P2P Module]
        ps[[`Send`]]
        pb[[`Broadcast`]]

        subgraph rt[RainTree Router]
            rtu[UnicastRouter]
        end

        subgraph bg[Background Router]
            bgu[UnicastRouter]
            bgg[Gossipsub Topic]
        end
    end
 
ps -.-> rtu
ps -.-> bgu
pb --> rtu
pb --> bgg
Loading

Incoming messages:

flowchart TD
    subgraph p2p[P2P Module]
        subgraph rt[RainTree Router]
            rth[[`RainTreeMessage` Handler]]
            rtu[UnicastRouter]
        end

        subgraph bg[Background Router]
            bgh[[`BackgroundMessage` Handler]]
            bgu[UnicastRouter]
            bgg[Gossipsub Subscription]
        end

        nd[Nonce Deduper]
    
        p2ph[[`PocketEnvelope` Handler]]
        bus
    end

p2ph --> bus
    
bgu --> bgh
bgg --> bgh
rtu --> rth

p2ph --> nd
rth --> p2ph
bgh --> p2ph
Loading

Message handling and deduplication:

classDiagram
    class RainTreeMessage {
        <<protobuf>>
        +Level uint32
        +Data []byte
    }

    class BackgroundMessage {
        <<protobuf>>
        +Data []byte
    }
    
    class PocketEnvelope {
        <<protobuf>>
        +Content *anypb.Any
        +Nonce uint64
    }

    RainTreeMessage --* PocketEnvelope : serialized as `Data`
    BackgroundMessage --* PocketEnvelope : serialized as `Data`
    
    
    class p2pModule {
        -handlePocketEnvelope([]byte) error
    }

    class P2PModule {
        <<interface>>
        GetAddress() (Address, error)
        HandleEvent(*anypb.Any) error
        Send([]byte, address Address) error
        Broadcast([]byte) error
    }
    p2pModule --|> P2PModule

    class RainTreeRouter {
        UnicastRouter
        -handler MessageHandler
        +Broadcast([]byte) error
        -handleRainTreeMsg([]byte) error
    }

    class NonceDeduper {
        
    }

    class BackgroundRouter {
        UnicastRouter
        -handler MessageHandler
        +Broadcast([]byte) error
        -handleBackgroundMsg([]byte) error
        -readSubscription(subscription *pubsub.Subscription)
    }

    class UnicastRouter {
        -messageHandler MessageHandler
        -peerHandler PeerHandler
        +Send([]byte, address Address) error
        -handleStream(stream libp2pNetwork.Stream)
        -readStream(stream libp2pNetwork.Stream)
    }
    RainTreeRouter --* UnicastRouter : (embedded)
    BackgroundRouter --* UnicastRouter : (embedded)
    %% UnicastRouter --> RainTreeRouter : via `messageHandler`
    %% UnicastRouter --> BackgroundRouter  : via `messageHandler`

    p2pModule ..* RainTreeRouter
    %% RainTreeRouter --> p2pModule : `handler` == `handlePocketEnvelope`
    RainTreeRouter --o RainTreeMessage
    
    p2pModule ..* BackgroundRouter
    %% BackgroundRouter --> p2pModule : `handler` == `handlePocketEnvelope`
    BackgroundRouter --o BackgroundMessage

    p2pModule --o PocketEnvelope
    p2pModule --* NonceDeduper

    %% class Router {
    %%     <<interface>>
    %%     +Send([]byte, address Address) error
    %%     +Broadcast([]byte) error
    %% }
    %% BackgroundRouter --|> Router
    %% RainTreeRouter --|> Router
Loading

P2P module / router decoupling:

classDiagram
    class p2pModule {
        -stakedActorRouter Router
        -unstakedActorRouter Router
        -handlePocketEnvelope([]byte) error
    }

    class P2PModule {
        <<interface>>
        GetAddress() (Address, error)
        HandleEvent(*anypb.Any) error
        Send([]byte, Address) error
        Broadcast([]byte) error
    }
    p2pModule --|> P2PModule

    class RainTreeRouter {
        UnicastRouter
        -handler MessageHandler
        +Broadcast([]byte) error
        -handleRainTreeMsg([]byte) error
    }

    class BackgroundRouter {
        UnicastRouter
        -handler MessageHandler
        +Broadcast([]byte) error
        -handleBackgroundMsg([]byte) error
        -readSubscription(subscription *pubsub.Subscription)
    }

    class UnicastRouter {
        -messageHandler MessageHandler
        -peerHandler PeerHandler
        +Send([]byte, Address) error
        -handleStream(libp2pNetwork.Stream)
        -readStream(libp2pNetwork.Stream)
    }
    RainTreeRouter --* UnicastRouter : (embedded)
    BackgroundRouter --* UnicastRouter : (embedded)

    p2pModule --o "2" Router
    p2pModule ..* RainTreeRouter : (`stakedActorRouter`)
    p2pModule ..* BackgroundRouter : (`unstakedActorRouter`)
    
    class Router {
        <<interface>>
        +Send([]byte, Address) error
        +Broadcast([]byte) error
    }
    BackgroundRouter --|> Router
    RainTreeRouter --|> Router
Loading

Non-goals / Non-deliverables

General issue deliverables

  • Update the appropriate CHANGELOG(s)
  • Update any relevant local/global README(s)
  • Update relevant source code tree explanations
  • Add or update any relevant or supporting mermaid diagrams

Testing Methodology

  • All tests: make test_all
  • LocalNet: verify a LocalNet is still functioning correctly by following the instructions at docs/development/README.md

Creator: @jessicadaugherty
Co-creator: @bryanchriswhite

@jessicadaugherty jessicadaugherty converted this from a draft issue Feb 13, 2023
@jessicadaugherty jessicadaugherty added the p2p P2P specific changes label Feb 13, 2023
@jessicadaugherty jessicadaugherty changed the title [P2P] Peer Discovery - Replace floodsub for broadcast [P2P] Replace floodsub for broadcast Feb 13, 2023
@jessicadaugherty jessicadaugherty changed the title [P2P] Replace floodsub for broadcast [P2P] Random gossip using LibP2P Apr 10, 2023
@jessicadaugherty
Copy link
Contributor Author

Iteration 15 Planning: Revisit AC in case anything is stale or can be more relevant to latest info @bryanchriswhite

@bryanchriswhite bryanchriswhite moved this from Backlog to In Progress in V1 Dashboard Apr 19, 2023
bryanchriswhite added a commit that referenced this issue May 8, 2023
## @Reviewer
This PR may be more digestible / reviewable on a commit-by-commit basis.
Commits are organized logically and any given line is only modified in a
single commit, with few exceptions*.

*(In the interest of preserving the git-time-continuum
:police_officer::rotating_light:, this applies in batches of commits
between comments or reviews *by humans*)

---

## Description

Implements a "background router" to work alongside raintree (to be
integrated in a future PR) which uses a kademlia DHT for peer discovery
and a gossipsub pubsub router for broadcasting and listening.

## Issue

Part 1 of #505 
Part 1 of #712 

## Type of change

Please mark the relevant option(s):

- [x] New feature, functionality or library
- [ ] Bug fix
- [ ] Code health or cleanup
- [ ] Major breaking change
- [ ] Documentation
- [ ] Other <!-- add details here if it a different type of change -->

## List of changes

- Removed unused `Transport` interface
- Moved and renamed `raintree.RainTreeConfig` to `util.RouterConfig`
- Renamed `protocol.DefaultTopicStr` to `protocol.BackgroundTopicStr`
- Added `protocol.PeerDiscoveryNamespace`
- Added kademlia peer discovery baseline test
- Added background router (kad + gossipsub)
- Renamed `P2PConfig#MaxMempoolCount` to `P2PConfig#MaxNonces`
- Renamed `DefaultP2PMaxMempoolCount` to `DefaultP2PMaxNonces`
- Updated Dockerfiles using outdated go version to 1.19
- Updated P2P README

## Testing

- [ ] `make develop_test`; if any code changes were made
- [x] [Docker Compose
LocalNet](https://github.com/pokt-network/pocket/blob/main/docs/development/README.md);
if any major functionality was changed or introduced
- [x] [k8s
LocalNet](https://github.com/pokt-network/pocket/blob/main/build/localnet/README.md);
if any infrastructure or configuration changes were made


## Required Checklist

- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have added, or updated, [`godoc` format
comments](https://go.dev/blog/godoc) on touched members (see:
[tip.golang.org/doc/comment](https://tip.golang.org/doc/comment))
- [x] I have tested my changes using the available tooling
- [x] I have updated the corresponding CHANGELOG

### If Applicable Checklist

- [x] I have updated the corresponding README(s); local and/or global
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] I have added, or updated,
[mermaid.js](https://mermaid-js.github.io) diagrams in the corresponding
README(s)
- [ ] I have added, or updated, documentation and
[mermaid.js](https://mermaid-js.github.io) diagrams in `shared/docs/*`
if I updated `shared/*`README(s)

---------

Co-authored-by: Daniel Olshansky <[email protected]>
@bryanchriswhite bryanchriswhite linked a pull request May 31, 2023 that will close this issue
18 tasks
@bryanchriswhite bryanchriswhite changed the title [P2P] Random gossip using LibP2P [P2P] Background gossip using libp2p-pubsub May 31, 2023
bryanchriswhite added a commit that referenced this issue Jun 13, 2023
## Description

1. Simplify `PeerstoreProvider` interface
2. Extend it to support retrieval of the unstaked actor peerstore
3. Implement the extended interface in `persistencePeerstoreProvider`

### Before

```mermaid
classDiagram 

class InterruptableModule {
    <<interface>>
    Start() error
    Stop() error
}
class IntegratableModule {
    <<interface>>
    +SetBus(bus Bus)
    +GetBus() Bus
}
class InitializableModule {
    <<interface>>
    +GetModuleName() string
    +Create(bus Bus, opts ...Option) (Module, error)
}
class Module {
    <<interface>>
}

Module --|> InitializableModule
Module --|> IntegratableModule
Module --|> InterruptableModule


class PeerstoreProvider {
    <<interface>>
    +GetStakedPeerstoreAtHeight(height int) (Peerstore, error)
    +GetP2PConfig() *P2PConfig
}

class persistencePeerstoreProvider

class rpcPeerstoreProvider

persistencePeerstoreProvider --|> PeerstoreProvider

rpcPeerstoreProvider --|> PeerstoreProvider
PeerstoreProvider --|> Module
```

### After

```mermaid
classDiagram 

class IntegratableModule {
    <<interface>>
    +GetBus() Bus
    +SetBus(bus Bus)
}

class PeerstoreProvider {
    <<interface>>
    +GetStakedPeerstoreAtHeight(height int) (Peerstore, error)
    +GetUnstakedPeerstore() (Peerstore, error)
}

class persistencePeerstoreProvider
class rpcPeerstoreProvider
class p2pModule

class unstakedPeerstoreProvider {
    <<interface>>
    +GetUnstakedPeerstore() (Peerstore, error)
}

persistencePeerstoreProvider --|> PeerstoreProvider
persistencePeerstoreProvider --> p2pModule : from Bus
rpcPeerstoreProvider --> p2pModule : from Bus
p2pModule --|> unstakedPeerstoreProvider

rpcPeerstoreProvider --|> PeerstoreProvider
rpcPeerstoreProvider --|> Module
PeerstoreProvider --|> IntegratableModule

class Module {
    <<interface>>
}

Module --|> InitializableModule
Module --|> IntegratableModule
Module --|> InterruptableModule
```

## Issue

Realted:
- #810

Dependants:
- #505 
- #806

## Type of change

Please mark the relevant option(s):

- [ ] New feature, functionality or library
- [ ] Bug fix
- [ ] Code health or cleanup
- [ ] Major breaking change
- [ ] Documentation
- [ ] Other <!-- add details here if it a different type of change -->

## List of changes

- Replaced embedded `modules.Module` with simpler
`modules.IntegratableModule` in `PeerstoreProvider` interface
- Removed unused `PeerstoreProvider#GetP2PConfig()` method
- Added `PeerstoreProvider#GetUnstakedPeerstore()` method
- Added `p2pPeerstoreProvider` implementation of `PeerstoreProvider`
interface
- Added `Factory` generic type 

## Testing

- [ ] `make develop_test`; if any code changes were made
- [x] `make test_e2e` on [k8s
LocalNet](https://github.com/pokt-network/pocket/blob/main/build/localnet/README.md);
if any code changes were made
- [ ] `e2e-devnet-test` passes tests on
[DevNet](https://pocketnetwork.notion.site/How-to-DevNet-ff1598f27efe44c09f34e2aa0051f0dd);
if any code was changed
- [x] [Docker Compose
LocalNet](https://github.com/pokt-network/pocket/blob/main/docs/development/README.md);
if any major functionality was changed or introduced
- [x] [k8s
LocalNet](https://github.com/pokt-network/pocket/blob/main/build/localnet/README.md);
if any infrastructure or configuration changes were made

<!-- REMOVE this comment block after following the instructions
 If you added additional tests or infrastructure, describe it here.
 Bonus points for images and videos or gifs.
-->

## Required Checklist

- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have added, or updated, [`godoc` format
comments](https://go.dev/blog/godoc) on touched members (see:
[tip.golang.org/doc/comment](https://tip.golang.org/doc/comment))
- [ ] I have tested my changes using the available tooling
- [ ] I have updated the corresponding CHANGELOG

### If Applicable Checklist

- [ ] I have updated the corresponding README(s); local and/or global
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] I have added, or updated,
[mermaid.js](https://mermaid-js.github.io) diagrams in the corresponding
README(s)
- [ ] I have added, or updated, documentation and
[mermaid.js](https://mermaid-js.github.io) diagrams in `shared/docs/*`
if I updated `shared/*`README(s)
bryanchriswhite added a commit that referenced this issue Jun 29, 2023
## Description

Factor out "unicast routing" concerns which will be common to both
RainTree and background routers. To implement the `Router` interface
(which I believe is applied appropriately), **each** must be able to
both send and receive messages directly to/from individual peers. In
libp2p this is done via streams.

### Before

```mermaid
classDiagram
    class RainTreeMessage {
        <<protobuf>>
        +Level uint32
        +Data []byte
    }

    class PocketEnvelope {
        <<protobuf>>
        +Content *anypb.Any
        +Nonce uint64
    }

    RainTreeMessage --* PocketEnvelope : serialized as `Data`
    
    %% class p2pModule {
    %%     -handlePocketEnvelope([]byte) error
    %% }

    %% class P2PModule {
    %%     <<interface>>
    %%     GetAddress() (Address, error)
    %%     HandleEvent(*anypb.Any) error
    %%     Send([]byte, address Address) error
    %%     Broadcast([]byte) error
    %%     BroadcastStaked([]byte) error
    %% }
    %% p2pModule --|> P2PModule

    class RainTreeRouter {
        -handler RouterHandler
        +Broadcast([]byte) error
        +Send([]byte, address Address) error
        -handleStream(stream libp2pNetwork.Stream)
        -readStream(stream libp2pNetwork.Stream)
        -handleRainTreeMsg([]byte) ([]byte, error)
    }

    %% p2pModule --* RainTreeRouter
    %% RainTreeRouter --> p2pModule : `handler` == `handlePocketEnvelope`
    RainTreeRouter --o RainTreeMessage


    %% p2pModule --o PocketEnvelope
    %% p2pModule --* NonceDeduper

    class Router {
        <<interface>>
        +Send([]byte, address Address) error
        +Broadcast([]byte) error
    }
    RainTreeRouter --|> Router
```

### After

```mermaid
classDiagram
    class RainTreeMessage {
        <<protobuf>>
        +Level uint32
        +Data []byte
    }

    class PocketEnvelope {
        <<protobuf>>
        +Content *anypb.Any
        +Nonce uint64
    }

    RainTreeMessage --* PocketEnvelope : serialized as `Data`
    
    %% class p2pModule {
    %%     -handlePocketEnvelope([]byte) error
    %% }

    %% class P2PModule {
    %%     <<interface>>
    %%     GetAddress() (Address, error)
    %%     HandleEvent(*anypb.Any) error
    %%     Send([]byte, address Address) error
    %%     Broadcast([]byte) error
    %%     BroadcastStaked([]byte) error
    %% }
    %% p2pModule --|> P2PModule

    class RainTreeRouter {
        UnicastRouter
        -handler MessageHandler
        +Broadcast([]byte) error
        -handleRainTreeMsg([]byte) error
    }

    class UnicastRouter {
        -messageHandler MessageHandler
        -peerHandler PeerHandler
        +Send([]byte, address Address) error
        -handleStream(stream libp2pNetwork.Stream)
        -readStream(stream libp2pNetwork.Stream)
    }
    RainTreeRouter --* UnicastRouter : (embedded)
    %% UnicastRouter --> RainTreeRouter : via `messageHandler`


    %% p2pModule --* RainTreeRouter
    %% RainTreeRouter --> p2pModule : `handler` == `handlePocketEnvelope`
    RainTreeRouter --o RainTreeMessage


    %% p2pModule --o PocketEnvelope
    %% p2pModule --* NonceDeduper

    class Router {
        <<interface>>
        +Send([]byte, address Address) error
        +Broadcast([]byte) error
    }
    RainTreeRouter --|> Router
```

See #505 "Integration / Architecture" class diagrams for more context.

<!-- reviewpad:summarize:start -->
### Summary generated by Reviewpad on 29 Jun 23 06:52 UTC
This pull request includes several changes related to improving
testability, reducing technical debt, and implementing unicast
functionality.

The overall changes aim to improve the code structure, make it more
maintainable and testable, and add support for handling unicast messages
in a peer-to-peer network.

Here is a summary of the changes per file:

1. In the file `setup.go`, changes were made to register providers and
routers to the module registry and improve testability.
2. In the file `router.go`, changes were made to improve peer discovery,
introduce encapsulated approaches, and share interfaces among modules.
Additionally, type and function names were updated.
3. The file `logging.go` underwent a rename and changes were made to the
package name, logging functionality, and function names.
4. In the file `network.go`, changes were made to imports, type names,
function names, and the implementation of the `handleRainTreeMsg`
function to support the unicast functionality.
5. The file `testutil.go` was added as a new file to provide testing
utilities for the unicast functionality.
6. In the file `p2p/raintree/testutil.go`, changes were made to imports
and a function to call the `HandleStream` method from the
`UnicastRouter` struct.

These changes collectively improve the testability, code structure, and
unicast functionality in the project.
<!-- reviewpad:summarize:end -->

## Issue

- #505 

## Dependants

- #732 

## Type of change

Please mark the relevant option(s):

- [ ] New feature, functionality or library
- [ ] Bug fix
- [x] Code health or cleanup
- [ ] Major breaking change
- [ ] Documentation
- [ ] Other <!-- add details here if it a different type of change -->

## List of changes

- Refactored stream handling logic (i.e. unicast routing) out of
`rainTreeRouter` and into new `UnicastRouter` type

## Testing

- [x] `make develop_test`; if any code changes were made
- [x] `make test_e2e` on [k8s
LocalNet](https://github.com/pokt-network/pocket/blob/main/build/localnet/README.md);
if any code changes were made
- [x] `e2e-devnet-test` passes tests on
[DevNet](https://pocketnetwork.notion.site/How-to-DevNet-ff1598f27efe44c09f34e2aa0051f0dd);
if any code was changed
- [ ] [Docker Compose
LocalNet](https://github.com/pokt-network/pocket/blob/main/docs/development/README.md);
if any major functionality was changed or introduced
- [x] [k8s
LocalNet](https://github.com/pokt-network/pocket/blob/main/build/localnet/README.md);
if any infrastructure or configuration changes were made

<!-- REMOVE this comment block after following the instructions
 If you added additional tests or infrastructure, describe it here.
 Bonus points for images and videos or gifs.
-->

## Required Checklist

- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have added, or updated, [`godoc` format
comments](https://go.dev/blog/godoc) on touched members (see:
[tip.golang.org/doc/comment](https://tip.golang.org/doc/comment))
- [x] I have tested my changes using the available tooling
- [ ] I have updated the corresponding CHANGELOG

### If Applicable Checklist

- [ ] I have updated the corresponding README(s); local and/or global
- [x] I have added tests that prove my fix is effective or that my
feature works
- [ ] I have added, or updated,
[mermaid.js](https://mermaid-js.github.io) diagrams in the corresponding
README(s)
- [ ] I have added, or updated, documentation and
[mermaid.js](https://mermaid-js.github.io) diagrams in `shared/docs/*`
if I updated `shared/*`README(s)

---------

Co-authored-by: @Olshansk <[email protected]>
Co-authored-by: Daniel Olshansky <[email protected]>
This was linked to pull requests Jun 29, 2023
@bryanchriswhite bryanchriswhite moved this from In Progress to In Review in V1 Dashboard Jul 10, 2023
bryanchriswhite added a commit that referenced this issue Jul 11, 2023
## @Reviewer
This PR may be more digestible / reviewable on a commit-by-commit basis.
Commits are organized logically and any given line is only modified in a
single commit, with few exceptions*.

*(In the interest of preserving the git-time-continuum
:police_officer::rotating_light:, this applies in batches of commits
between comments or reviews *by humans*, only once "in review")

---

## Description

### Before

While `backgroundRouter` exists and implements the `Router` interface,
it had yet to be connected to anything. Additionally, it was not able to
handle incoming unicast messages.

```mermaid
classDiagram
    class p2pModule {
        -router Router
        -handlePocketEnvelope([]byte) error
    }

    class P2PModule {
        <<interface>>
        GetAddress() (Address, error)
        HandleEvent(*anypb.Any) error
        Send([]byte, Address) error
        Broadcast([]byte) error
    }
    p2pModule --|> P2PModule

    class RainTreeRouter {
        UnicastRouter
        -handler MessageHandler
        +Broadcast([]byte) error
        -handleRainTreeMsg([]byte) error
    }

    class BackgroundRouter {
        UnicastRouter
        -handler MessageHandler
        +Broadcast([]byte) error
        -handleBackgroundMsg([]byte) error
        -readSubscription(subscription *pubsub.Subscription)
    }

    class UnicastRouter {
        -messageHandler MessageHandler
        -peerHandler PeerHandler
        +Send([]byte, Address) error
        -handleStream(libp2pNetwork.Stream)
        -readStream(libp2pNetwork.Stream)
    }
    RainTreeRouter --* UnicastRouter : (embedded)

    p2pModule --o "1" Router
    p2pModule ..* RainTreeRouter : (`router`)
    
    class Router {
        <<interface>>
        +Send([]byte, Address) error
        +Broadcast([]byte) error
    }
    BackgroundRouter --|> Router
    RainTreeRouter --|> Router
```

### After

`backgroundRouter` embeds `UnicastRouter` and is integrated into
`p2pModule` such that it is considered when calling `P2PModule#Send()`
and `P2PModule#Broadcast()`.

```mermaid
classDiagram
    class p2pModule {
        -stakedActorRouter Router
        -unstakedActorRouter Router
        -handlePocketEnvelope([]byte) error
    }

    class P2PModule {
        <<interface>>
        GetAddress() (Address, error)
        HandleEvent(*anypb.Any) error
        Send([]byte, Address) error
        Broadcast([]byte) error
    }
    p2pModule --|> P2PModule

    class RainTreeRouter {
        UnicastRouter
        -handler MessageHandler
        +Broadcast([]byte) error
        -handleRainTreeMsg([]byte) error
    }

    class BackgroundRouter {
        UnicastRouter
        -handler MessageHandler
        +Broadcast([]byte) error
        -handleBackgroundMsg([]byte) error
        -readSubscription(subscription *pubsub.Subscription)
    }

    class UnicastRouter {
        -messageHandler MessageHandler
        -peerHandler PeerHandler
        +Send([]byte, Address) error
        -handleStream(libp2pNetwork.Stream)
        -readStream(libp2pNetwork.Stream)
    }
    RainTreeRouter --* UnicastRouter : (embedded)
    BackgroundRouter --* UnicastRouter : (embedded)

    p2pModule --o "2" Router
    p2pModule ..* RainTreeRouter : (`stakedActorRouter`)
    p2pModule ..* BackgroundRouter : (`unstakedActorRouter`)
    
    class Router {
        <<interface>>
        +Send([]byte, Address) error
        +Broadcast([]byte) error
    }
    BackgroundRouter --|> Router
    RainTreeRouter --|> Router
```

## Issue

- #505 

## Dependencies

- #844 

## Type of change

Please mark the relevant option(s):

- [x] New feature, functionality or library
- [ ] Bug fix
- [ ] Code health or cleanup
- [ ] Major breaking change
- [ ] Documentation
- [ ] Other <!-- add details here if it a different type of change -->

## List of changes

* added background message protobuf type
* added `Router#Close()` interface method
* separated raintree & bg protocol IDs
* move `PocketEnvelope` nonce generation to `PackMessage()`
* added `Handler` to router configs
* refactored raintree router to support P2P module & `Router` interface
changes
* refactored raintree router bootstrapping
* refactored background router to support P2P module integration &
`Router` interface changes
* integrated background router into P2P module
* refactored staked actor router (raintree) peer discovery
* updated tests, post-refactoring


## Testing

- [x] `make develop_test`; if any code changes were made
- [ ] [Docker Compose
LocalNet](https://github.com/pokt-network/pocket/blob/main/docs/development/README.md);
if any major functionality was changed or introduced
- [x] [k8s
LocalNet](https://github.com/pokt-network/pocket/blob/main/build/localnet/README.md);
if any infrastructure or configuration changes were made

<!-- REMOVE this comment block after following the instructions
 If you added additional tests or infrastructure, describe it here.
 Bonus points for images and videos or gifs.
-->

## Required Checklist

- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have added, or updated, [`godoc` format
comments](https://go.dev/blog/godoc) on touched members (see:
[tip.golang.org/doc/comment](https://tip.golang.org/doc/comment))
- [x] I have tested my changes using the available tooling
- [ ] I have updated the corresponding CHANGELOG

### If Applicable Checklist

- [x] I have updated the corresponding README(s); local and/or global
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] I have added, or updated,
[mermaid.js](https://mermaid-js.github.io) diagrams in the corresponding
README(s)
- [ ] I have added, or updated, documentation and
[mermaid.js](https://mermaid-js.github.io) diagrams in `shared/docs/*`
if I updated `shared/*`README(s)

---------

Co-authored-by: @Olshansk <[email protected]>
Co-authored-by: Daniel Olshansky <[email protected]>
Co-authored-by: d7t <[email protected]>
Co-authored-by: Daniel Olshansky <[email protected]>
@github-project-automation github-project-automation bot moved this from In Review to Done in V1 Dashboard Jul 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment