From a86c0e620e2275562b67a7f0185fb31cf4a64901 Mon Sep 17 00:00:00 2001 From: Alessandro De Blasis Date: Mon, 9 Jan 2023 22:46:14 +0000 Subject: [PATCH] [TECHDEBT] Consolidate & encapsulate ValidatorMap logic - (Issue #203) (#402) ## Description ## Issue Fixes #203 ## Type of change Please mark the relevant option(s): - [x] New feature, functionality or library - [ ] Bug fix - [x] Code health or cleanup - [ ] Major breaking change - [ ] Documentation - [ ] Other ## List of changes - Refactored so that references to `modules.ValidatorMap` are removed/internalized within `Consensus` - [WIP] Make sure that the debug client can discover the validators in `LocalNet` ## Testing - [x] `make develop_test` - [ ] [LocalNet](https://github.com/pokt-network/pocket/blob/main/docs/development/README.md) w/ all of the steps outlined in the `README` ## 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 tested my changes using the available tooling - [x] 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) Signed-off-by: Alessandro De Blasis Co-authored-by: Daniel Olshansky --- Makefile | 8 +- app/client/cli/debug.go | 109 +++++++---------- app/client/cli/doc/CHANGELOG.md | 6 + build/config/config1.json | 4 +- build/config/config2.json | 3 +- build/config/config3.json | 3 +- build/config/config4.json | 3 +- build/docs/CHANGELOG.md | 7 +- consensus/doc/CHANGELOG.md | 3 +- consensus/module.go | 4 - consensus/types/types.go | 9 -- p2p/CHANGELOG.md | 12 ++ p2p/addrbook_provider/getter.go | 19 --- p2p/addrbook_provider/persistence.go | 114 ------------------ p2p/module.go | 100 ++++++++++++--- .../addrbook_provider/addrbook_provider.go | 62 ++++++++++ .../addrbook_provider/debug/provider.go | 74 ++++++++++++ .../addrbook_provider/persistence/provider.go | 66 ++++++++++ .../current_height_provider.go | 7 ++ .../current_height_provider/debug/provider.go | 21 ++++ p2p/providers/providers.go | 9 ++ p2p/raintree/network.go | 17 ++- p2p/raintree/network_test.go | 6 +- p2p/raintree/peers_manager.go | 3 +- p2p/raintree/peers_manager_test.go | 9 +- p2p/raintree/utils_test.go | 8 +- p2p/stdnetwork/network.go | 6 +- p2p/types/addr_book.go | 11 -- p2p/utils_test.go | 9 +- runtime/configs/proto/p2p_config.proto | 3 +- runtime/docs/CHANGELOG.md | 4 + shared/CHANGELOG.md | 5 + shared/modules/consensus_module.go | 5 - 33 files changed, 447 insertions(+), 282 deletions(-) delete mode 100644 p2p/addrbook_provider/getter.go delete mode 100644 p2p/addrbook_provider/persistence.go create mode 100644 p2p/providers/addrbook_provider/addrbook_provider.go create mode 100644 p2p/providers/addrbook_provider/debug/provider.go create mode 100644 p2p/providers/addrbook_provider/persistence/provider.go create mode 100644 p2p/providers/current_height_provider/current_height_provider.go create mode 100644 p2p/providers/current_height_provider/debug/provider.go create mode 100644 p2p/providers/providers.go diff --git a/Makefile b/Makefile index 1ac764baa..6b8c916b5 100644 --- a/Makefile +++ b/Makefile @@ -130,7 +130,7 @@ rebuild_client_start: docker_check ## Rebuild and run a client daemon which is o .PHONY: client_connect client_connect: docker_check ## Connect to the running client debugging daemon - docker exec -it client /bin/bash -c "go run -tags=debug app/client/*.go debug" + docker exec -it client /bin/bash -c "POCKET_P2P_IS_CLIENT_ONLY=true go run -tags=debug app/client/*.go debug" .PHONY: build_and_watch build_and_watch: ## Continous build Pocket's main entrypoint as files change @@ -224,11 +224,11 @@ mockgen: clean_mocks ## Use `mockgen` to generate mocks used for testing purpose go generate ./${modules_dir} echo "Mocks generated in ${modules_dir}/mocks" - $(eval p2p_types_dir = "p2p/types") + $(eval p2p_dir = "p2p") $(eval p2p_type_mocks_dir = "p2p/types/mocks") find ${p2p_type_mocks_dir} -type f ! -name "mocks.go" -exec rm {} \; - go generate ./${p2p_types_dir} - echo "P2P mocks generated in ${p2p_types_dir}/mocks" + go generate ./${p2p_dir}/... + echo "P2P mocks generated in ${p2p_type_mocks_dir}" # TODO(team): Tested locally with `protoc` version `libprotoc 3.19.4`. In the near future, only the Dockerfiles will be used to compile protos. diff --git a/app/client/cli/debug.go b/app/client/cli/debug.go index 2aeb64a2d..d3870a150 100644 --- a/app/client/cli/debug.go +++ b/app/client/cli/debug.go @@ -1,24 +1,18 @@ -//go:build debug -// +build debug - package cli import ( "log" "os" - "sync" "github.com/manifoldco/promptui" - "github.com/pokt-network/pocket/consensus" - "github.com/pokt-network/pocket/logger" "github.com/pokt-network/pocket/p2p" - "github.com/pokt-network/pocket/rpc" + debugABP "github.com/pokt-network/pocket/p2p/providers/addrbook_provider/debug" + debugCHP "github.com/pokt-network/pocket/p2p/providers/current_height_provider/debug" "github.com/pokt-network/pocket/runtime" - "github.com/pokt-network/pocket/shared" + coreTypes "github.com/pokt-network/pocket/shared/core/types" pocketCrypto "github.com/pokt-network/pocket/shared/crypto" "github.com/pokt-network/pocket/shared/messaging" "github.com/pokt-network/pocket/shared/modules" - "github.com/pokt-network/pocket/telemetry" "github.com/spf13/cobra" "google.golang.org/protobuf/types/known/anypb" ) @@ -39,10 +33,6 @@ var ( // A P2P module is initialized in order to broadcast a message to the local network p2pMod modules.P2PModule - // A consensus module is initialized in order to get a list of the validator network - consensusMod modules.ConsensusModule - modInitOnce sync.Once - items = []string{ PromptResetToGenesis, PromptPrintNodeState, @@ -50,6 +40,11 @@ var ( PromptTogglePacemakerMode, PromptShowLatestBlockInStore, } + + // validators holds the list of the validators at genesis time so that we can use it to create a debug address book provider. + // Its purpose is to allow the CLI to "discover" the nodes in the network. Since currently we don't have churn and we run nodes only in LocalNet, we can rely on the genesis state. + // HACK(#416): This is a temporary solution that guarantees backward compatibility while we implement peer discovery + validators []*coreTypes.Actor ) func init() { @@ -62,7 +57,30 @@ func NewDebugCommand() *cobra.Command { Short: "Debug utility for rapid development", Args: cobra.ExactArgs(0), PersistentPreRun: func(cmd *cobra.Command, args []string) { - initDebug(remoteCLIURL) + var err error + runtimeMgr := runtime.NewManagerFromFiles(defaultConfigPath, defaultGenesisPath, runtime.WithRandomPK()) + + // HACK(#416): this is a temporary solution that guarantees backward compatibility while we implement peer discovery. + validators = runtimeMgr.GetGenesis().Validators + + debugAddressBookProvider := debugABP.NewDebugAddrBookProvider( + runtimeMgr.GetConfig().P2P, + debugABP.WithActorsByHeight( + map[int64][]*coreTypes.Actor{ + debugABP.ANY_HEIGHT: validators, + }, + ), + ) + + debugCurrentHeightProvider := debugCHP.NewDebugCurrentHeightProvider(0) + + p2pM, err := p2p.CreateWithProviders(runtimeMgr, debugAddressBookProvider, debugCurrentHeightProvider) + if err != nil { + log.Fatalf("[ERROR] Failed to create p2p module: %v", err.Error()) + } + p2pMod = p2pM.(modules.P2PModule) + + p2pMod.Start() }, RunE: runDebug, } @@ -148,8 +166,8 @@ func broadcastDebugMessage(debugMsg *messaging.DebugMessage) { // address book of the actual validator nodes, so `node1.consensus` never receives the message. // p2pMod.Broadcast(anyProto, messaging.PocketTopic_DEBUG_TOPIC) - for _, val := range consensusMod.ValidatorMap() { - addr, err := pocketCrypto.NewAddress(val.GetAddress()) + for _, valAddr := range validators { + addr, err := pocketCrypto.NewAddress(valAddr.GetAddress()) if err != nil { log.Fatalf("[ERROR] Failed to convert validator address into pocketCrypto.Address: %v", err) } @@ -165,58 +183,15 @@ func sendDebugMessage(debugMsg *messaging.DebugMessage) { } var validatorAddress []byte - for _, val := range consensusMod.ValidatorMap() { - validatorAddress, err = pocketCrypto.NewAddress(val.GetAddress()) - if err != nil { - log.Fatalf("[ERROR] Failed to convert validator address into pocketCrypto.Address: %v", err) - } - break + if len(validators) == 0 { + log.Fatalf("[ERROR] No validators found") } - p2pMod.Send(validatorAddress, anyProto) -} - -func initDebug(remoteCLIURL string) { - modInitOnce.Do(func() { - var err error - runtimeMgr := runtime.NewManagerFromFiles(defaultConfigPath, defaultGenesisPath, runtime.WithRandomPK()) - - consM, err := consensus.Create(runtimeMgr) - if err != nil { - logger.Global.Fatal().Err(err).Msg("Failed to create consensus module") - } - consensusMod = consM.(modules.ConsensusModule) - - p2pM, err := p2p.Create(runtimeMgr) - if err != nil { - log.Fatalf("[ERROR] Failed to create p2p module: %v", err.Error()) - } - p2pMod = p2pM.(modules.P2PModule) - - // This telemetry module instance is a NOOP because the 'enable_telemetry' flag in the `cfg` above is set to false. - // Since this client mimics partial - networking only - functionality of a full node, some of the telemetry-related - // code paths are executed. To avoid those messages interfering with the telemetry data collected, a non-nil telemetry - // module that NOOPs (per the configs above) is injected. - telemetryM, err := telemetry.Create(runtimeMgr) - if err != nil { - logger.Global.Fatal().Err(err).Msg("Failed to create telemetry module") - } - telemetryMod := telemetryM.(modules.TelemetryModule) - - loggerM, err := logger.Create(runtimeMgr) - if err != nil { - logger.Global.Fatal().Err(err).Msg("Failed to create logger module") - } - loggerMod := loggerM.(modules.LoggerModule) - - rpcM, err := rpc.Create(runtimeMgr) - if err != nil { - logger.Global.Fatal().Err(err).Msg("Failed to create rpc module") - } - rpcMod := rpcM.(modules.RPCModule) - - _ = shared.CreateBusWithOptionalModules(runtimeMgr, nil, p2pMod, nil, consensusMod, telemetryMod, loggerMod, rpcMod) // REFACTOR: use the `WithXXXModule()` pattern accepting a slice of IntegratableModule + // if the message needs to be broadcast, it'll be handled by the business logic of the message handler + validatorAddress, err = pocketCrypto.NewAddress(validators[0].GetAddress()) + if err != nil { + log.Fatalf("[ERROR] Failed to convert validator address into pocketCrypto.Address: %v", err) + } - p2pMod.Start() - }) + p2pMod.Send(validatorAddress, anyProto) } diff --git a/app/client/cli/doc/CHANGELOG.md b/app/client/cli/doc/CHANGELOG.md index 5cbd7faf9..3773711e4 100644 --- a/app/client/cli/doc/CHANGELOG.md +++ b/app/client/cli/doc/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.0.0.4] - 2023-01-09 + +- The `client` (i.e. CLI) no longer instantiates a `P2P` module along with a bus of optional modules. Instead, it instantiates a `client-only` `P2P` module that is disconnected from consensus and persistence. Interactions with the persistence & consensus layer happen via RPC. +- Replaced previous implementation, reliant on `ValidatorMap`, with a temporary fetch from genesis. This will be replaced with a lightweight peer discovery mechanism in #416 +- Simplified debug CLI initialization + ## [0.0.0.3] - 2023-01-03 - Updated to use `coreTypes` instead of utility types for `Actor` and `ActorType` diff --git a/build/config/config1.json b/build/config/config1.json index e296eb787..9eef908af 100644 --- a/build/config/config1.json +++ b/build/config/config1.json @@ -25,7 +25,9 @@ "consensus_port": 8080, "use_rain_tree": true, "is_empty_connection_type": false, - "private_key": "6fd0bc54cc2dd205eaf226eebdb0451629b321f11d279013ce6fdd5a33059256b2eda2232ffb2750bf761141f70f75a03a025f65b2b2b417c7f8b3c9ca91e8e4" + "private_key": "6fd0bc54cc2dd205eaf226eebdb0451629b321f11d279013ce6fdd5a33059256b2eda2232ffb2750bf761141f70f75a03a025f65b2b2b417c7f8b3c9ca91e8e4", + "max_mempool_count": 100000, + "is_client_only": false }, "telemetry": { "enabled": true, diff --git a/build/config/config2.json b/build/config/config2.json index afa43715e..ab67a2de5 100644 --- a/build/config/config2.json +++ b/build/config/config2.json @@ -25,7 +25,8 @@ "consensus_port": 8080, "use_rain_tree": true, "is_empty_connection_type": false, - "private_key": "5db3e9d97d04d6d70359de924bb02039c602080d6bf01a692bad31ad5ef93524c16043323c83ffd901a8bf7d73543814b8655aa4695f7bfb49d01926fc161cdb" + "private_key": "5db3e9d97d04d6d70359de924bb02039c602080d6bf01a692bad31ad5ef93524c16043323c83ffd901a8bf7d73543814b8655aa4695f7bfb49d01926fc161cdb", + "max_mempool_count": 100000 }, "telemetry": { "enabled": true, diff --git a/build/config/config3.json b/build/config/config3.json index 58cbe5248..ee6f63652 100644 --- a/build/config/config3.json +++ b/build/config/config3.json @@ -25,7 +25,8 @@ "consensus_port": 8080, "use_rain_tree": true, "is_empty_connection_type": false, - "private_key": "b37d3ba2f232060c41ba1177fea6008d885fcccad6826d64ee7d49f94d1dbc49a8b6be75d7551da093f788f7286c3a9cb885cfc8e52710eac5f1d5e5b4bf19b2" + "private_key": "b37d3ba2f232060c41ba1177fea6008d885fcccad6826d64ee7d49f94d1dbc49a8b6be75d7551da093f788f7286c3a9cb885cfc8e52710eac5f1d5e5b4bf19b2", + "max_mempool_count": 100000 }, "telemetry": { "enabled": true, diff --git a/build/config/config4.json b/build/config/config4.json index 74f76035b..36fb8f7ff 100644 --- a/build/config/config4.json +++ b/build/config/config4.json @@ -25,7 +25,8 @@ "consensus_port": 8080, "use_rain_tree": true, "is_empty_connection_type": false, - "private_key": "c6c136d010d07d7f5e9944aa3594a10f9210dd3e26ebc1bc1516a6d957fd0df353ee26c82826694ffe1773d7b60d5f20dd9e91bdf8745544711bec5ff9c6fb4a" + "private_key": "c6c136d010d07d7f5e9944aa3594a10f9210dd3e26ebc1bc1516a6d957fd0df353ee26c82826694ffe1773d7b60d5f20dd9e91bdf8745544711bec5ff9c6fb4a", + "max_mempool_count": 100000 }, "telemetry": { "enabled": true, diff --git a/build/docs/CHANGELOG.md b/build/docs/CHANGELOG.md index aa092940b..7c553c1f6 100644 --- a/build/docs/CHANGELOG.md +++ b/build/docs/CHANGELOG.md @@ -7,11 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [0.0.0.1] - 2023-01-03 +## [0.0.0.2] - 2023-01-09 - Removed `BaseConfig` from `configs` - Centralized `PersistenceGenesisState` and `ConsensusGenesisState` into `GenesisState` +## [0.0.0.1] - 2022-12-29 + +- Updated all `config*.json` files with the missing `max_mempool_count` value +- Added `is_client_only` to `config1.json` so Viper knows it can be overridden. The config override is done in the Makefile's `client_connect` target. Setting this can be avoided if we merge the changes in https://github.com/pokt-network/pocket/compare/main...issue/cli-viper-environment-vars-fix + ## [0.0.0.0] - 2022-12-22 - Introduced this `CHANGELOG.md` diff --git a/consensus/doc/CHANGELOG.md b/consensus/doc/CHANGELOG.md index c5c989c69..9426c1e1e 100644 --- a/consensus/doc/CHANGELOG.md +++ b/consensus/doc/CHANGELOG.md @@ -7,11 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [0.0.0.16] - 2023-01-03 +## [0.0.0.16] - 2023-01-09 - Added protobuf message definitions for requests related to sharing state sync metadata and blocks - Defined the interface for `StateSyncServerModule`, `StateSyncModule` (moving the old interface to `StateSyncModuleLEGACY` as a reference only) - Overhaul (updates, improvements, clarifications & additions) of the State Sync README +- Removed `ValidatorMap() ValidatorMap` ## [0.0.0.15] - 2023-01-03 diff --git a/consensus/module.go b/consensus/module.go index 5e15f30ce..bf1125e84 100644 --- a/consensus/module.go +++ b/consensus/module.go @@ -295,10 +295,6 @@ func (m *consensusModule) CurrentStep() uint64 { return uint64(m.step) } -func (m *consensusModule) ValidatorMap() modules.ValidatorMap { // TODO: This needs to be dynamically updated during various operations and network changes. - return typesCons.ValidatorMapToModulesValidatorMap(m.validatorMap) -} - // TODO: Populate the entire state from the persistence module: validator set, quorum cert, last block hash, etc... func (m *consensusModule) loadPersistedState() error { persistenceContext, err := m.GetBus().GetPersistenceModule().NewReadContext(-1) // Unknown height diff --git a/consensus/types/types.go b/consensus/types/types.go index 263ea8862..94e67281f 100644 --- a/consensus/types/types.go +++ b/consensus/types/types.go @@ -5,7 +5,6 @@ import ( "sort" coreTypes "github.com/pokt-network/pocket/shared/core/types" - "github.com/pokt-network/pocket/shared/modules" ) type NodeId uint64 @@ -42,14 +41,6 @@ func GetValAddrToIdMap(validatorMap ValidatorMap) (ValAddrToIdMap, IdToValAddrMa return valToIdMap, idToValMap } -func ValidatorMapToModulesValidatorMap(validatorMap ValidatorMap) (vm modules.ValidatorMap) { - vm = make(modules.ValidatorMap) - for _, v := range validatorMap { - vm[v.GetAddress()] = *v - } - return -} - func ActorListToValidatorMap(actors []*coreTypes.Actor) (m ValidatorMap) { m = make(ValidatorMap, len(actors)) for _, a := range actors { diff --git a/p2p/CHANGELOG.md b/p2p/CHANGELOG.md index 000e2772e..18e07cbf1 100644 --- a/p2p/CHANGELOG.md +++ b/p2p/CHANGELOG.md @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.0.0.16] - 2023-01-09 + +- Added missing `Close()` call to `persistenceReadContext` + +## [0.0.0.15] - 2023-01-03 + +- Refactored `AddrBookProvider` to support multiple implementations +- Added `CurrentHeightProvider` +- Dependency injection of the aforementioned provider into the module creation (used by the debug-client) +- Updated implementation to use the providers +- Updated tests and mocks + ## [0.0.0.14] - 2023-01-03 - `ActorsToAddrBook` now skips actors that are not validators since they don't have a serviceUrl generic parameter diff --git a/p2p/addrbook_provider/getter.go b/p2p/addrbook_provider/getter.go deleted file mode 100644 index ed9304221..000000000 --- a/p2p/addrbook_provider/getter.go +++ /dev/null @@ -1,19 +0,0 @@ -package addrbook_provider - -import ( - typesP2P "github.com/pokt-network/pocket/p2p/types" - "github.com/pokt-network/pocket/shared/modules" -) - -// GetAddrBook is a helper function that returns the addrBook depending on the availability of the persistence module -// -// HACK: This is a temporary solution simply used to centralize the logic that is going to be refactored in #331 and #203 -func GetAddrBook(bus modules.Bus, addrBookProvider typesP2P.AddrBookProvider) (addrBook typesP2P.AddrBook, err error) { - if bus.GetPersistenceModule() == nil { - // TODO(#203): refactor or remove this once `ValidatorMap` logic is encapsulated. - addrBook, err = addrBookProvider.ActorsToAddrBook(bus.GetConsensusModule().ValidatorMap()) - } else { - addrBook, err = addrBookProvider.GetStakedAddrBookAtHeight(bus.GetConsensusModule().CurrentHeight()) - } - return addrBook, err -} diff --git a/p2p/addrbook_provider/persistence.go b/p2p/addrbook_provider/persistence.go deleted file mode 100644 index 81db1d718..000000000 --- a/p2p/addrbook_provider/persistence.go +++ /dev/null @@ -1,114 +0,0 @@ -package addrbook_provider - -import ( - "fmt" - "log" - - "github.com/pokt-network/pocket/p2p/transport" - typesP2P "github.com/pokt-network/pocket/p2p/types" - "github.com/pokt-network/pocket/runtime/configs" - coreTypes "github.com/pokt-network/pocket/shared/core/types" - cryptoPocket "github.com/pokt-network/pocket/shared/crypto" - "github.com/pokt-network/pocket/shared/modules" -) - -var _ modules.IntegratableModule = &persistenceAddrBookProvider{} -var _ typesP2P.AddrBookProvider = &persistenceAddrBookProvider{} - -type persistenceAddrBookProvider struct { - bus modules.Bus - p2pCfg *configs.P2PConfig - connFactory typesP2P.ConnectionFactory -} - -func NewPersistenceAddrBookProvider(bus modules.Bus, p2pCfg *configs.P2PConfig, options ...func(*persistenceAddrBookProvider)) *persistenceAddrBookProvider { - pabp := &persistenceAddrBookProvider{ - bus: bus, - p2pCfg: p2pCfg, - connFactory: transport.CreateDialer, // default connection factory, overridable with WithConnectionFactory() - } - - for _, o := range options { - o(pabp) - } - - return pabp -} - -// WithConnectionFactory allows the user to specify a custom connection factory -func WithConnectionFactory(connFactory typesP2P.ConnectionFactory) func(*persistenceAddrBookProvider) { - return func(pabp *persistenceAddrBookProvider) { - pabp.connFactory = connFactory - } -} - -func (pabp *persistenceAddrBookProvider) GetBus() modules.Bus { - return pabp.bus -} - -func (pabp *persistenceAddrBookProvider) SetBus(bus modules.Bus) { - pabp.bus = bus -} - -func (pabp *persistenceAddrBookProvider) GetStakedAddrBookAtHeight(height uint64) (typesP2P.AddrBook, error) { - persistenceReadContext, err := pabp.GetBus().GetPersistenceModule().NewReadContext(int64(height)) - if err != nil { - return nil, err - } - stakedActors, err := persistenceReadContext.GetAllStakedActors(int64(height)) - if err != nil { - return nil, err - } - // TODO(#203): refactor `ValidatorMap` - validatorMap := make(modules.ValidatorMap, len(stakedActors)) - for _, v := range stakedActors { - validatorMap[v.GetAddress()] = *v - } - addrBook, err := pabp.ActorsToAddrBook(validatorMap) - if err != nil { - return nil, err - } - return addrBook, nil -} - -// TODO (#426): refactor so that it's possible to connect to peers without using the GenericParam and having to filter out non-validator actors. -// AddrBook and similar concepts shouldn't leak outside the P2P module. It should be possible to broadcast messages to all peers or only to a specific actor type -// without having to know the underlying implementation in the P2P module. -func (pabp *persistenceAddrBookProvider) ActorsToAddrBook(actors map[string]coreTypes.Actor) (typesP2P.AddrBook, error) { - book := make(typesP2P.AddrBook, 0) - for _, v := range actors { - // only add validator actors since they are the only ones having a service url in their generic param at the moment - if v.ActorType != coreTypes.ActorType_ACTOR_TYPE_VAL { - continue - } - networkPeer, err := pabp.ActorToNetworkPeer(v) - if err != nil { - log.Println("[WARN] Error connecting to validator: ", err) - continue - } - book = append(book, networkPeer) - } - return book, nil -} - -// TODO (#426): refactor so that it doesn't use the GenericParam anymore to connect to the peer -func (pabp *persistenceAddrBookProvider) ActorToNetworkPeer(v coreTypes.Actor) (*typesP2P.NetworkPeer, error) { - conn, err := pabp.connFactory(pabp.p2pCfg, v.GetGenericParam()) // service url - if err != nil { - return nil, fmt.Errorf("error resolving addr: %v", err) - } - - pubKey, err := cryptoPocket.NewPublicKey(v.GetPublicKey()) - if err != nil { - return nil, err - } - - peer := &typesP2P.NetworkPeer{ - Dialer: conn, - PublicKey: pubKey, - Address: pubKey.Address(), - ServiceUrl: v.GetGenericParam(), // service url - } - - return peer, nil -} diff --git a/p2p/module.go b/p2p/module.go index 177aeecd7..97bd3c1d0 100644 --- a/p2p/module.go +++ b/p2p/module.go @@ -3,7 +3,8 @@ package p2p import ( "log" - "github.com/pokt-network/pocket/p2p/addrbook_provider" + "github.com/pokt-network/pocket/p2p/providers" + persABP "github.com/pokt-network/pocket/p2p/providers/addrbook_provider/persistence" "github.com/pokt-network/pocket/p2p/raintree" "github.com/pokt-network/pocket/p2p/stdnetwork" "github.com/pokt-network/pocket/p2p/transport" @@ -31,38 +32,69 @@ type p2pModule struct { address cryptoPocket.Address network typesP2P.Network -} -// TECHDEBT(drewsky): Discuss how to best expose/access `Address` throughout the codebase. -func (m *p2pModule) GetAddress() (cryptoPocket.Address, error) { - return m.address, nil + injectedAddrBookProvider providers.AddrBookProvider + injectedCurrentHeightProvider providers.CurrentHeightProvider } func Create(runtimeMgr modules.RuntimeMgr) (modules.Module, error) { return new(p2pModule).Create(runtimeMgr) } -func (*p2pModule) Create(runtimeMgr modules.RuntimeMgr) (modules.Module, error) { +// TODO(#429): need to define a better pattern for dependency injection. Currently we are probably limiting ourselves by having a common constructor `Create(bus modules.Bus) (modules.Module, error)` for all modules. +func CreateWithProviders(runtimeMgr modules.RuntimeMgr, addrBookProvider providers.AddrBookProvider, currentHeightProvider providers.CurrentHeightProvider) (modules.Module, error) { log.Println("Creating network module") var m *p2pModule cfg := runtimeMgr.GetConfig() p2pCfg := cfg.P2P - l, err := transport.CreateListener(p2pCfg) + privateKey, err := cryptoPocket.NewPrivateKey(p2pCfg.GetPrivateKey()) if err != nil { return nil, err } + m = &p2pModule{ + p2pCfg: p2pCfg, + address: privateKey.Address(), + injectedAddrBookProvider: addrBookProvider, + injectedCurrentHeightProvider: currentHeightProvider, + } + + if !p2pCfg.GetIsClientOnly() { + l, err := transport.CreateListener(p2pCfg) + if err != nil { + return nil, err + } + m.listener = l + } + + return m, nil +} + +func (*p2pModule) Create(runtimeMgr modules.RuntimeMgr) (modules.Module, error) { + log.Println("Creating network module") + var m *p2pModule + + cfg := runtimeMgr.GetConfig() + p2pCfg := cfg.P2P + privateKey, err := cryptoPocket.NewPrivateKey(p2pCfg.PrivateKey) if err != nil { return nil, err } m = &p2pModule{ - p2pCfg: p2pCfg, + p2pCfg: p2pCfg, + address: privateKey.Address(), + } - listener: l, - address: privateKey.Address(), + if !p2pCfg.GetIsClientOnly() { + l, err := transport.CreateListener(p2pCfg) + if err != nil { + return nil, err + } + m.listener = l } + return m, nil } @@ -87,6 +119,19 @@ func (m *p2pModule) GetModuleName() string { func (m *p2pModule) Start() error { log.Println("Starting network module") + addrbookProvider := getAddrBookProvider(m) + currentHeightProvider := getCurrentHeightProvider(m) + + if m.p2pCfg.GetUseRainTree() { + m.network = raintree.NewRainTreeNetwork(m.address, m.GetBus(), m.p2pCfg, addrbookProvider, currentHeightProvider) + } else { + m.network = stdnetwork.NewNetwork(m.GetBus(), m.p2pCfg, addrbookProvider, currentHeightProvider) + } + + if m.p2pCfg.GetIsClientOnly() { + return nil + } + m.GetBus(). GetTelemetryModule(). GetTimeSeriesAgent(). @@ -95,14 +140,6 @@ func (m *p2pModule) Start() error { telemetry.P2P_NODE_STARTED_TIMESERIES_METRIC_DESCRIPTION, ) - addrbookProvider := addrbook_provider.NewPersistenceAddrBookProvider(m.GetBus(), m.p2pCfg) - - if m.p2pCfg.UseRainTree { - m.network = raintree.NewRainTreeNetwork(m.address, m.GetBus(), m.p2pCfg, addrbookProvider) - } else { - m.network = stdnetwork.NewNetwork(m.GetBus(), m.p2pCfg, addrbookProvider) - } - go func() { for { data, err := m.listener.Read() @@ -122,6 +159,28 @@ func (m *p2pModule) Start() error { return nil } +// CLEANUP(#429): marked for removal since we'll implement a better pattern for dependency injection +func getAddrBookProvider(m *p2pModule) providers.AddrBookProvider { + var addrbookProvider providers.AddrBookProvider + if m.injectedAddrBookProvider == nil { + addrbookProvider = persABP.NewPersistenceAddrBookProvider(m.GetBus(), m.p2pCfg) + } else { + addrbookProvider = m.injectedAddrBookProvider + } + return addrbookProvider +} + +// CLEANUP(#429): marked for removal since we'll implement a better pattern for dependency injection +func getCurrentHeightProvider(m *p2pModule) providers.CurrentHeightProvider { + var currentHeightProvider providers.CurrentHeightProvider + if m.injectedCurrentHeightProvider == nil { + currentHeightProvider = m.GetBus().GetConsensusModule() + } else { + currentHeightProvider = m.injectedCurrentHeightProvider + } + return currentHeightProvider +} + func (m *p2pModule) Stop() error { log.Println("Stopping network module") if err := m.listener.Close(); err != nil { @@ -155,6 +214,11 @@ func (m *p2pModule) Send(addr cryptoPocket.Address, msg *anypb.Any) error { return m.network.NetworkSend(data, addr) } +// TECHDEBT(drewsky): Discuss how to best expose/access `Address` throughout the codebase. +func (m *p2pModule) GetAddress() (cryptoPocket.Address, error) { + return m.address, nil +} + func (m *p2pModule) handleNetworkMessage(networkMsgData []byte) { appMsgData, err := m.network.HandleNetworkData(networkMsgData) if err != nil { diff --git a/p2p/providers/addrbook_provider/addrbook_provider.go b/p2p/providers/addrbook_provider/addrbook_provider.go new file mode 100644 index 000000000..1820259cd --- /dev/null +++ b/p2p/providers/addrbook_provider/addrbook_provider.go @@ -0,0 +1,62 @@ +package addrbook_provider + +//go:generate mockgen -source=$GOFILE -destination=../../types/mocks/addrbook_provider_mock.go -package=mock_types github.com/pokt-network/pocket/p2p/types AddrBookProvider + +import ( + "fmt" + "log" + + typesP2P "github.com/pokt-network/pocket/p2p/types" + "github.com/pokt-network/pocket/runtime/configs" + coreTypes "github.com/pokt-network/pocket/shared/core/types" + cryptoPocket "github.com/pokt-network/pocket/shared/crypto" +) + +// AddrBookProvider is an interface that provides AddrBook accessors +type AddrBookProvider interface { + GetStakedAddrBookAtHeight(height uint64) (typesP2P.AddrBook, error) + GetConnFactory() typesP2P.ConnectionFactory + GetP2PConfig() *configs.P2PConfig + SetConnectionFactory(typesP2P.ConnectionFactory) +} + +func ActorsToAddrBook(abp AddrBookProvider, actors []*coreTypes.Actor) (typesP2P.AddrBook, error) { + book := make(typesP2P.AddrBook, 0) + for _, a := range actors { + networkPeer, err := ActorToNetworkPeer(abp, a) + if err != nil { + log.Println("[WARN] Error connecting to validator: ", err) + continue + } + book = append(book, networkPeer) + } + return book, nil +} + +func ActorToNetworkPeer(abp AddrBookProvider, actor *coreTypes.Actor) (*typesP2P.NetworkPeer, error) { + conn, err := abp.GetConnFactory()(abp.GetP2PConfig(), actor.GetGenericParam()) // generic param is service url + if err != nil { + return nil, fmt.Errorf("error resolving addr: %v", err) + } + + pubKey, err := cryptoPocket.NewPublicKey(actor.GetPublicKey()) + if err != nil { + return nil, err + } + + peer := &typesP2P.NetworkPeer{ + Dialer: conn, + PublicKey: pubKey, + Address: pubKey.Address(), + ServiceUrl: actor.GetGenericParam(), // service url + } + + return peer, nil +} + +// WithConnectionFactory allows the user to specify a custom connection factory +func WithConnectionFactory(connFactory typesP2P.ConnectionFactory) func(AddrBookProvider) { + return func(ap AddrBookProvider) { + ap.SetConnectionFactory(connFactory) + } +} diff --git a/p2p/providers/addrbook_provider/debug/provider.go b/p2p/providers/addrbook_provider/debug/provider.go new file mode 100644 index 000000000..a5afa14f0 --- /dev/null +++ b/p2p/providers/addrbook_provider/debug/provider.go @@ -0,0 +1,74 @@ +package debug + +import ( + "log" + + "github.com/pokt-network/pocket/p2p/providers/addrbook_provider" + "github.com/pokt-network/pocket/p2p/transport" + typesP2P "github.com/pokt-network/pocket/p2p/types" + "github.com/pokt-network/pocket/runtime/configs" + coreTypes "github.com/pokt-network/pocket/shared/core/types" +) + +const ( + // ANY_HEIGHT is a special height that will be used to indicate that the actors are valid for all heights (including future heights) + ANY_HEIGHT = -1 +) + +var _ addrbook_provider.AddrBookProvider = &debugAddrBookProvider{} + +type debugAddrBookProvider struct { + p2pCfg *configs.P2PConfig + actorsByHeight map[int64][]*coreTypes.Actor + connFactory typesP2P.ConnectionFactory +} + +func NewDebugAddrBookProvider(p2pCfg *configs.P2PConfig, options ...func(*debugAddrBookProvider)) *debugAddrBookProvider { + dabp := &debugAddrBookProvider{ + p2pCfg: p2pCfg, + connFactory: transport.CreateDialer, // default connection factory, overridable with WithConnectionFactory() + } + + for _, o := range options { + o(dabp) + } + + return dabp +} + +func WithActorsByHeight(actorsByHeight map[int64][]*coreTypes.Actor) func(*debugAddrBookProvider) { + return func(pabp *debugAddrBookProvider) { + pabp.actorsByHeight = actorsByHeight + } +} + +func (dabp *debugAddrBookProvider) getActorsByHeight(height uint64) []*coreTypes.Actor { + if stakedActors, ok := dabp.actorsByHeight[ANY_HEIGHT]; ok { + log.Println("[DEBUG] Ignoring height param in debugAddrBookProvider") + return stakedActors + } + + if stakedActors, ok := dabp.actorsByHeight[int64(height)]; ok { + return stakedActors + } + + log.Fatalf("No actors found for height %d. Please make sure you configured the provider via WithActorsByHeight", height) + return nil +} + +func (dabp *debugAddrBookProvider) GetStakedAddrBookAtHeight(height uint64) (typesP2P.AddrBook, error) { + stakedActors := dabp.getActorsByHeight(height) + return addrbook_provider.ActorsToAddrBook(dabp, stakedActors) +} + +func (dabp *debugAddrBookProvider) GetConnFactory() typesP2P.ConnectionFactory { + return dabp.connFactory +} + +func (dabp *debugAddrBookProvider) GetP2PConfig() *configs.P2PConfig { + return dabp.p2pCfg +} + +func (dabp *debugAddrBookProvider) SetConnectionFactory(connFactory typesP2P.ConnectionFactory) { + dabp.connFactory = connFactory +} diff --git a/p2p/providers/addrbook_provider/persistence/provider.go b/p2p/providers/addrbook_provider/persistence/provider.go new file mode 100644 index 000000000..7f12a5671 --- /dev/null +++ b/p2p/providers/addrbook_provider/persistence/provider.go @@ -0,0 +1,66 @@ +package persistence + +import ( + "github.com/pokt-network/pocket/p2p/providers/addrbook_provider" + "github.com/pokt-network/pocket/p2p/transport" + typesP2P "github.com/pokt-network/pocket/p2p/types" + "github.com/pokt-network/pocket/runtime/configs" + "github.com/pokt-network/pocket/shared/modules" +) + +var _ modules.IntegratableModule = &persistenceAddrBookProvider{} +var _ addrbook_provider.AddrBookProvider = &persistenceAddrBookProvider{} + +type persistenceAddrBookProvider struct { + bus modules.Bus + p2pCfg *configs.P2PConfig + connFactory typesP2P.ConnectionFactory +} + +func NewPersistenceAddrBookProvider(bus modules.Bus, p2pCfg *configs.P2PConfig, options ...func(*persistenceAddrBookProvider)) *persistenceAddrBookProvider { + pabp := &persistenceAddrBookProvider{ + bus: bus, + p2pCfg: p2pCfg, + connFactory: transport.CreateDialer, // default connection factory, overridable with WithConnectionFactory() + } + + for _, o := range options { + o(pabp) + } + + return pabp +} + +func (pabp *persistenceAddrBookProvider) GetBus() modules.Bus { + return pabp.bus +} + +func (pabp *persistenceAddrBookProvider) SetBus(bus modules.Bus) { + pabp.bus = bus +} + +func (pabp *persistenceAddrBookProvider) GetStakedAddrBookAtHeight(height uint64) (typesP2P.AddrBook, error) { + persistenceReadContext, err := pabp.GetBus().GetPersistenceModule().NewReadContext(int64(height)) + if err != nil { + return nil, err + } + defer persistenceReadContext.Close() + + stakedActors, err := persistenceReadContext.GetAllStakedActors(int64(height)) + if err != nil { + return nil, err + } + return addrbook_provider.ActorsToAddrBook(pabp, stakedActors) +} + +func (pabp *persistenceAddrBookProvider) GetConnFactory() typesP2P.ConnectionFactory { + return pabp.connFactory +} + +func (pabp *persistenceAddrBookProvider) GetP2PConfig() *configs.P2PConfig { + return pabp.p2pCfg +} + +func (pabp *persistenceAddrBookProvider) SetConnectionFactory(connFactory typesP2P.ConnectionFactory) { + pabp.connFactory = connFactory +} diff --git a/p2p/providers/current_height_provider/current_height_provider.go b/p2p/providers/current_height_provider/current_height_provider.go new file mode 100644 index 000000000..feb858bc2 --- /dev/null +++ b/p2p/providers/current_height_provider/current_height_provider.go @@ -0,0 +1,7 @@ +package current_height_provider + +//go:generate mockgen -source=$GOFILE -destination=../../types/mocks/current_height_provider_mock.go -package=mock_types github.com/pokt-network/pocket/p2p/types CurrentHeightProvider + +type CurrentHeightProvider interface { + CurrentHeight() uint64 +} diff --git a/p2p/providers/current_height_provider/debug/provider.go b/p2p/providers/current_height_provider/debug/provider.go new file mode 100644 index 000000000..7575cdd9e --- /dev/null +++ b/p2p/providers/current_height_provider/debug/provider.go @@ -0,0 +1,21 @@ +package debug + +import "github.com/pokt-network/pocket/p2p/providers/current_height_provider" + +var _ current_height_provider.CurrentHeightProvider = &debugCurrentHeightProvider{} + +type debugCurrentHeightProvider struct { + currentHeight uint64 +} + +func (dchp *debugCurrentHeightProvider) CurrentHeight() uint64 { + return dchp.currentHeight +} + +func NewDebugCurrentHeightProvider(height uint64) *debugCurrentHeightProvider { + dchp := &debugCurrentHeightProvider{ + currentHeight: height, + } + + return dchp +} diff --git a/p2p/providers/providers.go b/p2p/providers/providers.go new file mode 100644 index 000000000..05dfdfe62 --- /dev/null +++ b/p2p/providers/providers.go @@ -0,0 +1,9 @@ +package providers + +import ( + "github.com/pokt-network/pocket/p2p/providers/addrbook_provider" + "github.com/pokt-network/pocket/p2p/providers/current_height_provider" +) + +type AddrBookProvider = addrbook_provider.AddrBookProvider +type CurrentHeightProvider = current_height_provider.CurrentHeightProvider diff --git a/p2p/raintree/network.go b/p2p/raintree/network.go index 6cee74b0b..065e663be 100644 --- a/p2p/raintree/network.go +++ b/p2p/raintree/network.go @@ -6,7 +6,8 @@ import ( "math/rand" "time" - "github.com/pokt-network/pocket/p2p/addrbook_provider" + "github.com/pokt-network/pocket/p2p/providers" + "github.com/pokt-network/pocket/p2p/providers/addrbook_provider" typesP2P "github.com/pokt-network/pocket/p2p/types" "github.com/pokt-network/pocket/runtime/configs" "github.com/pokt-network/pocket/shared/codec" @@ -24,7 +25,7 @@ type rainTreeNetwork struct { bus modules.Bus selfAddr cryptoPocket.Address - addrBookProvider typesP2P.AddrBookProvider + addrBookProvider addrbook_provider.AddrBookProvider peersManager *peersManager @@ -53,8 +54,8 @@ func NewRainTreeNetworkWithAddrBook(addr cryptoPocket.Address, addrBook typesP2P return typesP2P.Network(n) } -func NewRainTreeNetwork(addr cryptoPocket.Address, bus modules.Bus, p2pCfg *configs.P2PConfig, addrBookProvider typesP2P.AddrBookProvider) typesP2P.Network { - addrBook, err := addrbook_provider.GetAddrBook(bus, addrBookProvider) +func NewRainTreeNetwork(addr cryptoPocket.Address, bus modules.Bus, p2pCfg *configs.P2PConfig, addrBookProvider providers.AddrBookProvider, currentHeightProvider providers.CurrentHeightProvider) typesP2P.Network { + addrBook, err := addrBookProvider.GetStakedAddrBookAtHeight(currentHeightProvider.CurrentHeight()) if err != nil { log.Fatalf("[ERROR] Error getting addrBook: %v", err) } @@ -149,7 +150,13 @@ func (n *rainTreeNetwork) networkSendInternal(data []byte, address cryptoPocket. return err } - n.GetBus(). + // A bus is not available In client debug mode + bus := n.GetBus() + if bus == nil { + return nil + } + + bus. GetTelemetryModule(). GetEventMetricsAgent(). EmitEvent( diff --git a/p2p/raintree/network_test.go b/p2p/raintree/network_test.go index 10c9f35a6..ba305b298 100644 --- a/p2p/raintree/network_test.go +++ b/p2p/raintree/network_test.go @@ -27,8 +27,9 @@ func TestRainTreeNetwork_AddPeerToAddrBook(t *testing.T) { busMock := mockBus(ctrl) addrBookProviderMock := mockAddrBookProvider(ctrl, addrBook) + currentHeightProviderMock := mockCurrentHeightProvider(ctrl, 0) - network := NewRainTreeNetwork(selfAddr, busMock, p2pCfg, addrBookProviderMock).(*rainTreeNetwork) + network := NewRainTreeNetwork(selfAddr, busMock, p2pCfg, addrBookProviderMock, currentHeightProviderMock).(*rainTreeNetwork) peerAddr, err := cryptoPocket.GenerateAddress() require.NoError(t, err) @@ -67,8 +68,9 @@ func TestRainTreeNetwork_RemovePeerToAddrBook(t *testing.T) { busMock := mockBus(ctrl) addrBookProviderMock := mockAddrBookProvider(ctrl, addrBook) + currentHeightProviderMock := mockCurrentHeightProvider(ctrl, 0) - network := NewRainTreeNetwork(selfAddr, busMock, p2pCfg, addrBookProviderMock).(*rainTreeNetwork) + network := NewRainTreeNetwork(selfAddr, busMock, p2pCfg, addrBookProviderMock, currentHeightProviderMock).(*rainTreeNetwork) stateView := network.peersManager.getNetworkView() require.Equal(t, numAddressesInAddressBook+1, len(stateView.addrList)) // +1 to account for self in the addrBook as well diff --git a/p2p/raintree/peers_manager.go b/p2p/raintree/peers_manager.go index 6bbba74a2..67c07a1e4 100644 --- a/p2p/raintree/peers_manager.go +++ b/p2p/raintree/peers_manager.go @@ -6,6 +6,7 @@ import ( "sort" "sync" + "github.com/pokt-network/pocket/p2p/providers/addrbook_provider" "github.com/pokt-network/pocket/p2p/types" typesP2P "github.com/pokt-network/pocket/p2p/types" cryptoPocket "github.com/pokt-network/pocket/shared/crypto" @@ -30,7 +31,7 @@ type peersManager struct { maxNumLevels uint32 } -func newPeersManagerWithAddrBookProvider(selfAddr cryptoPocket.Address, addrBookProvider typesP2P.AddrBookProvider, height uint64) (*peersManager, error) { +func newPeersManagerWithAddrBookProvider(selfAddr cryptoPocket.Address, addrBookProvider addrbook_provider.AddrBookProvider, height uint64) (*peersManager, error) { addrBook, err := addrBookProvider.GetStakedAddrBookAtHeight(height) if err != nil { return nil, err diff --git a/p2p/raintree/peers_manager_test.go b/p2p/raintree/peers_manager_test.go index eb7cbe3ce..b9fa74b7b 100644 --- a/p2p/raintree/peers_manager_test.go +++ b/p2p/raintree/peers_manager_test.go @@ -81,8 +81,9 @@ func TestRainTreeAddrBookUtilsHandleUpdate(t *testing.T) { mockBus := mockBus(ctrl) mockAddrBookProvider := mockAddrBookProvider(ctrl, addrBook) + currentHeightProviderMock := mockCurrentHeightProvider(ctrl, 0) - network := NewRainTreeNetwork(addr, mockBus, p2pCfg, mockAddrBookProvider).(*rainTreeNetwork) + network := NewRainTreeNetwork(addr, mockBus, p2pCfg, mockAddrBookProvider, currentHeightProviderMock).(*rainTreeNetwork) peersManagerStateView := network.peersManager.getNetworkView() @@ -123,8 +124,9 @@ func BenchmarkAddrBookUpdates(b *testing.B) { mockBus := mockBus(ctrl) mockAddrBookProvider := mockAddrBookProvider(ctrl, addrBook) + currentHeightProviderMock := mockCurrentHeightProvider(ctrl, 0) - network := NewRainTreeNetwork(addr, mockBus, p2pCfg, mockAddrBookProvider).(*rainTreeNetwork) + network := NewRainTreeNetwork(addr, mockBus, p2pCfg, mockAddrBookProvider, currentHeightProviderMock).(*rainTreeNetwork) peersManagerStateView := network.peersManager.getNetworkView() @@ -214,8 +216,9 @@ func testRainTreeMessageTargets(t *testing.T, expectedMsgProp *ExpectedRainTreeM } addrBook := getAlphabetAddrBook(expectedMsgProp.numNodes) mockAddrBookProvider := mockAddrBookProvider(ctrl, addrBook) + currentHeightProviderMock := mockCurrentHeightProvider(ctrl, 1) - network := NewRainTreeNetwork([]byte{expectedMsgProp.orig}, busMock, p2pCfg, mockAddrBookProvider).(*rainTreeNetwork) + network := NewRainTreeNetwork([]byte{expectedMsgProp.orig}, busMock, p2pCfg, mockAddrBookProvider, currentHeightProviderMock).(*rainTreeNetwork) network.SetBus(busMock) diff --git a/p2p/raintree/utils_test.go b/p2p/raintree/utils_test.go index e584c83bf..342905cf0 100644 --- a/p2p/raintree/utils_test.go +++ b/p2p/raintree/utils_test.go @@ -12,14 +12,18 @@ func mockBus(ctrl *gomock.Controller) *mockModules.MockBus { busMock.EXPECT().GetPersistenceModule().Return(nil).AnyTimes() consensusMock := mockModules.NewMockConsensusModule(ctrl) consensusMock.EXPECT().CurrentHeight().Return(uint64(0)).AnyTimes() - consensusMock.EXPECT().ValidatorMap().Return(nil).AnyTimes() busMock.EXPECT().GetConsensusModule().Return(consensusMock).AnyTimes() return busMock } func mockAddrBookProvider(ctrl *gomock.Controller, addrBook typesP2P.AddrBook) *mocksP2P.MockAddrBookProvider { addrBookProviderMock := mocksP2P.NewMockAddrBookProvider(ctrl) - addrBookProviderMock.EXPECT().ActorsToAddrBook(gomock.Any()).Return(addrBook, nil).AnyTimes() addrBookProviderMock.EXPECT().GetStakedAddrBookAtHeight(gomock.Any()).Return(addrBook, nil).AnyTimes() return addrBookProviderMock } + +func mockCurrentHeightProvider(ctrl *gomock.Controller, height uint64) *mocksP2P.MockCurrentHeightProvider { + currentHeightProviderMock := mocksP2P.NewMockCurrentHeightProvider(ctrl) + currentHeightProviderMock.EXPECT().CurrentHeight().Return(height).AnyTimes() + return currentHeightProviderMock +} diff --git a/p2p/stdnetwork/network.go b/p2p/stdnetwork/network.go index 4adb8550e..f79d83faa 100644 --- a/p2p/stdnetwork/network.go +++ b/p2p/stdnetwork/network.go @@ -6,7 +6,7 @@ import ( "fmt" "log" - "github.com/pokt-network/pocket/p2p/addrbook_provider" + "github.com/pokt-network/pocket/p2p/providers" typesP2P "github.com/pokt-network/pocket/p2p/types" "github.com/pokt-network/pocket/runtime/configs" cryptoPocket "github.com/pokt-network/pocket/shared/crypto" @@ -20,8 +20,8 @@ type network struct { addrBookMap typesP2P.AddrBookMap } -func NewNetwork(bus modules.Bus, p2pCfg *configs.P2PConfig, addrBookProvider typesP2P.AddrBookProvider) (n typesP2P.Network) { - addrBook, err := addrbook_provider.GetAddrBook(bus, addrBookProvider) +func NewNetwork(bus modules.Bus, p2pCfg *configs.P2PConfig, addrBookProvider providers.AddrBookProvider, currentHeightProvider providers.CurrentHeightProvider) (n typesP2P.Network) { + addrBook, err := addrBookProvider.GetStakedAddrBookAtHeight(currentHeightProvider.CurrentHeight()) if err != nil { log.Fatalf("[ERROR] Error getting addrBook: %v", err) } diff --git a/p2p/types/addr_book.go b/p2p/types/addr_book.go index d0594dc4a..3a317b18b 100644 --- a/p2p/types/addr_book.go +++ b/p2p/types/addr_book.go @@ -1,9 +1,5 @@ package types -//go:generate mockgen -source=$GOFILE -destination=./mocks/addrbook_provider_mock.go github.com/pokt-network/pocket/p2p/types AddrBookProvider - -import coreTypes "github.com/pokt-network/pocket/shared/core/types" - // AddrBook is a way of representing NetworkPeer sets type AddrBook []*NetworkPeer @@ -11,10 +7,3 @@ type AddrBook []*NetworkPeer // // Since maps cannot be sorted arbitrarily in Go, to achieve sorting, we need to rely on `addrList` which is a slice of addresses/strings and therefore we can sort it the way we want. type AddrBookMap map[string]*NetworkPeer - -// AddrBookProvider is an interface that provides AddrBook accessors -type AddrBookProvider interface { - GetStakedAddrBookAtHeight(height uint64) (AddrBook, error) - ActorsToAddrBook(actors map[string]coreTypes.Actor) (AddrBook, error) - ActorToNetworkPeer(actor coreTypes.Actor) (*NetworkPeer, error) -} diff --git a/p2p/utils_test.go b/p2p/utils_test.go index 3412cf4b3..05ece6c48 100644 --- a/p2p/utils_test.go +++ b/p2p/utils_test.go @@ -181,14 +181,6 @@ func prepareBusMock(t *testing.T, func prepareConsensusMock(t *testing.T, genesisState *genesis.GenesisState) *modulesMock.MockConsensusModule { ctrl := gomock.NewController(t) consensusMock := modulesMock.NewMockConsensusModule(ctrl) - - validators := genesisState.GetValidators() - m := make(modules.ValidatorMap, len(validators)) - for _, v := range validators { - m[v.GetAddress()] = *v - } - - consensusMock.EXPECT().ValidatorMap().Return(m).AnyTimes() consensusMock.EXPECT().CurrentHeight().Return(uint64(1)).AnyTimes() return consensusMock @@ -203,6 +195,7 @@ func preparePersistenceMock(t *testing.T, genesisState *genesis.GenesisState) *m readContextMock.EXPECT().GetAllStakedActors(gomock.Any()).Return(genesisState.GetValidators(), nil).AnyTimes() persistenceMock.EXPECT().NewReadContext(gomock.Any()).Return(readContextMock, nil).AnyTimes() + readContextMock.EXPECT().Close().Return(nil).AnyTimes() return persistenceMock } diff --git a/runtime/configs/proto/p2p_config.proto b/runtime/configs/proto/p2p_config.proto index 492a8664a..67c3ab30d 100644 --- a/runtime/configs/proto/p2p_config.proto +++ b/runtime/configs/proto/p2p_config.proto @@ -8,8 +8,9 @@ message P2PConfig { string private_key = 1; uint32 consensus_port = 2; bool use_rain_tree = 3; - bool is_empty_connection_type = 4; // TODO (Drewsky) switch back to enum + bool is_empty_connection_type = 4; // TODO: Switch back to enum uint64 max_mempool_count = 5; // this is used to limit the number of nonces that can be stored in the mempool, after which a FIFO mechanism is used to remove the oldest nonces and make space for the new ones + bool is_client_only = 6; } enum ConnectionType { diff --git a/runtime/docs/CHANGELOG.md b/runtime/docs/CHANGELOG.md index 945232db7..d8dde29d1 100644 --- a/runtime/docs/CHANGELOG.md +++ b/runtime/docs/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.0.0.4] - 2023-01-09 + +- Added 'is_client_only' to `P2PConfig` + ## [0.0.0.3] - 2023-01-03 - Split testing/development configs into separate files diff --git a/shared/CHANGELOG.md b/shared/CHANGELOG.md index e7dd1d6d5..a59a3ff01 100644 --- a/shared/CHANGELOG.md +++ b/shared/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.0.0.9] - 2023-01-09 + +- Removed `ValidatorMap() ValidatorMap` from `ConsensusModule` interface +- Added `GetIsClientOnly()` to `P2PConfig` + ## [0.0.0.8] - 2023-01-03 - Added `PoolNames.FriendlyName` method diff --git a/shared/modules/consensus_module.go b/shared/modules/consensus_module.go index b9a575561..6dc13e362 100644 --- a/shared/modules/consensus_module.go +++ b/shared/modules/consensus_module.go @@ -3,14 +3,10 @@ package modules //go:generate mockgen -source=$GOFILE -destination=./mocks/consensus_module_mock.go -aux_files=github.com/pokt-network/pocket/shared/modules=module.go import ( - coreTypes "github.com/pokt-network/pocket/shared/core/types" "github.com/pokt-network/pocket/shared/messaging" "google.golang.org/protobuf/types/known/anypb" ) -// TODO(olshansky): deprecate ValidatorMap or populate from persistence module -type ValidatorMap map[string]coreTypes.Actor - // NOTE: Consensus is the core of the replicated state machine and is driven by various asynchronous events. // Consider adding a mutex lock to your implementation that is acquired at the beginning of each entrypoint/function implemented in this interface. // Make sure that you are not locking again within the same call to avoid deadlocks (for example when the methods below call each other in your implementation). @@ -27,5 +23,4 @@ type ConsensusModule interface { CurrentHeight() uint64 CurrentRound() uint64 CurrentStep() uint64 - ValidatorMap() ValidatorMap }