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

[Core] Consolidate all node configurations into a new configs package - (Issue #396) #403

Merged
merged 122 commits into from
Jan 3, 2023

Conversation

deblasis
Copy link
Contributor

@deblasis deblasis commented Dec 15, 2022

Description

The main goal of this PR is to centralize configurations into a single configs package.
The feedback received was that the previous implementation was probably overly abstracted. Mockability is still preserved thanks to the fact that we are ultimately just dealing with structs without any logic attached to them.

It also tends to address:

// IMPROVE(#361): Design a better way to generate deterministic keys for testing.

https://github.com/pokt-network/pocket/compare/issue/396-consolidate-config?expand=1#diff-ee06bf613911836fdf48424397b7ec556c2e1a8ddba5adecca4c1782aea24087L30

Issue

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

List of changes

  • Centralized configs into the configs package
  • Introduced a keygenerator that can work deterministically or randomly at will
  • Centralize genesis as well, from two structs with overlapping states into a single one
  • Simplified shared core types (Actor, Account, etc) under coreTypes
  • Added missing max_mempool_count in config (it was causing P2P instabilities in LocalNet)

Testing

  • make develop_test
  • LocalNet w/ all of the steps outlined in the README

Required Checklist

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • 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 diagrams in the corresponding README(s)
  • I have added, or updated, documentation and mermaid.js diagrams in shared/docs/* if I updated shared/*README(s)

@deblasis deblasis added the core Core infrastructure - protocol related label Dec 15, 2022
@deblasis deblasis self-assigned this Dec 15, 2022
@deblasis
Copy link
Contributor Author

deblasis commented Dec 15, 2022

@Olshansk I would appreciate a quick scan on this, just to make sure it's getting where it's supposed to be.

Please point out blatant gaps (apart from the fact that I need to centralize genesis as well but I am waiting for this initial feedback on the design before proceeding).
Close your eyes when you see leftover comments and other nits 🙂

🙏

Copy link
Member

@Olshansk Olshansk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tl;dr I ❤️ where this is going

@deblasis deblasis requested a review from Olshansk December 30, 2022 13:41
poolFriendlyNames = map[Pools]string{
Pools_POOLS_UNSPECIFIED: "Unspecified",
Pools_POOLS_DAO: "DAO",
Pools_POOLS_FEE_COLLECTOR: "FeeCollector",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Pools_POOLS_FEE_COLLECTOR: "FeeCollector",
Pools_POOLS_FEE_COLLECTOR: "FeeCollectorPool",

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure you want to change this? The current values reflect what's currently on main, also, I could argue that they are entities in the table pool so the suffix is redundant.

func init() {
poolFriendlyNames = map[Pools]string{
Pools_POOLS_UNSPECIFIED: "Unspecified",
Pools_POOLS_DAO: "DAO",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Pools_POOLS_DAO: "DAO",
Pools_POOLS_DAO: "DAOPool",

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stakedActorsInsertConfigs := []struct {
Name string
Getter func() []*coreTypes.Actor
InsertFn func(address []byte, publicKey []byte, output []byte, paused bool, status int32, serviceURL string, stakedTokens string, chains []string, pausedHeight int64, unstakingHeight int64) error
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say yes but if we want to enforce a style I would say let's be consistent and scout the whole codebase for similar instances and rectify accordingly otherwise it becomes a mix and match.

Agreed. I was trying to be consistent with line 83 of this file (just local consistency).

I believe we can enforce not specifying types (when they're the same) using the automatic linters @okdas set-up since these are standard golang suggestions. They're currently off because we need to do a one-time cleanup.

You are correct that #295 encompasses this.

Another thing we could do is adding newlines when the signatures are particularly long. I think you did that somewhere in the codebase and I like it since it allows the reader to avoid horizontal scrolling.

I do like it but think it's overkill here because the function is anonymous.

Let me know how you want to go about your suggestion and, more generally, about styling guidelines, perhaps this could be related to linting? (https://github.com/pokt-network/pocket/issues/295)

Let's just be consistent between this and line 83 and #295 will encompass the work of enforcing repo-wide guidelines.

@@ -92,7 +92,7 @@ func (p *PostgresContext) getActor(actorSchema types.ProtocolActorSchema, addres
if err != nil {
return
}

actor.ActorType = actorSchema.GetActorType()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getActor uses getActorFromRow under the hood

BUT

GetAllXXX uses getActorFromRow directly

So this won't actually fully work.

I'm okay with leaving it as is because we have a ton of scope creep, but could you add a TODO to fix it (in a follow up PR). I also think this is a really good opportunity to do some TDD to be future-proof.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I coudn't resist... fb42810 and 6ff3c3a

## [0.0.0.10] - 2022-12-21
## [0.0.0.17] - 2022-12-28

- Added missing `ActorType` in `GetAllXXXX()` functions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a comment in persistence/shared_sql.go

@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.0.0.14] - 2022-12-28

- `ActorsToAddrBook` now skips actors that are not validators since they don't have a serviceUrl generic parameter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding libp2p - makes sense when we get there.

Regarding the val filtering - see the comment I left in p2p/addrbook_provider/persistence.go


Also, what is this concept of generic parameter? Where can I learn more about it?

This is just a poor design decision that was the result of a compromise during the shared module refactor.

We (currently) have 4 protocol actor types:

  • Fisherman
  • Validator
  • Servicer
  • Application

There are things they all share (e.g. an address) and there are things that are specific:

  • Servicers need a "serviceURL" to service nodes
  • Fisherman need a "serviceURL" to enable QoS
  • Applications need a 'maxRelaysCount' which is only specific to them

The two potential future paths we take are:

  1. One Protobuf per actor
  2. One BaseActor protobuf that's embedded in each ProtocolActor type

See #313 for the origin document.

config modules.PersistenceConfig
genesisState modules.PersistenceGenesisState
config *configs.PersistenceConfig
genesisState *genesis.GenesisState
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto - fair point.

Given what you said, I don't love either approach but prefer what we have for now over the alternative.

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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to one of my other comments, fisherman and serviceNodes also have serviceURLs in their parameter, and can (and should) also participate in structured broadcast.

Should they not be included as well?

Screenshot 2023-01-03 at 11 49 05 AM

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TL;DR: The way I see it, NO...

Like you said, it looks like these serviceUrls have a different meaning depending on the actor type and therefore using them to connect to a node for consensus related messaging/structured broadcast is a... shortcut.

Nodes are listening on the ConsensuPort which by default is 8080 and it seems that serviceUrl has been used to have an easy way to address them.

I guess this is because we don't have -yet- a full-fledged P2P module that owns the addressbook and can be relied upon for routing and messaging (that will come with peer discovery and churn).

We won't address messages via serviceUrl but rather by address or nodeId, then P2P would figure out how to reach that peer.

In LocalNet we spin up 4 validator nodes and the debug commands are all related to consensus.
This explains why previously we had 👇👈 while now we have 👉👇
image

If we consider other actors I can only imagine that since we have overlaps (eg: node1.consensus:8080 in genesis.json is a Validator, a ServiceNode and also a Fisherman) we would have duplicate messages at a minimum.

I wish Brian was here to pick his brain on this :) the ways I see it, structured gossip happens under the hood in the P2P module, when you say "broadcast to all validators" you don't know/care if the message is also handled and retransmitted by a Fisherman in order to reach a "nearby" Validator. That's implementation detail of the P2P algorithm.

I would say that for now we have to filter. Happy to discuss further even offline.

Just let me know how to proceed here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid explanation. I'm convinced.

Excited to see what our next steps are going to be here :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added #426 PTAL 🙏

@deblasis deblasis requested a review from Olshansk January 3, 2023 21:18
Copy link
Member

@Olshansk Olshansk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One tiny comment about the addition of val1.json and val2.json to the root dir.

  1. Add it to .gitignore
  2. Update docs/demos/iteration_3_end_to_end_tx.md to move it into /tmp and reference that directly.

@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.0.0.14] - 2022-12-28

- `ActorsToAddrBook` now skips actors that are not validators since they don't have a serviceUrl generic parameter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏

val1.json Outdated
@@ -0,0 +1 @@
"6fd0bc54cc2dd205eaf226eebdb0451629b321f11d279013ce6fdd5a33059256b2eda2232ffb2750bf761141f70f75a03a025f65b2b2b417c7f8b3c9ca91e8e4"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope. Genuine mistake

"github.com/stretchr/testify/require"
)

func TestGetAllStakedActors(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙌

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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid explanation. I'm convinced.

Excited to see what our next steps are going to be here :)

Copy link
Member

@Olshansk Olshansk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LFG!

🚢 🚢🚢

@deblasis deblasis merged commit bbf8205 into main Jan 3, 2023
@Olshansk Olshansk deleted the issue/396-consolidate-config branch June 2, 2023 21:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Core infrastructure - protocol related
Projects
Status: Done
2 participants