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

node: implement ADR-52 Tendermint Mode (reopened) #6061

Closed

Conversation

dongsam
Copy link
Contributor

@dongsam dongsam commented Feb 6, 2021

Description

Implementation spec of Tendermint Mode ADR-52 by B-Harvest

Add Tendermint mode

  • Add --mode flag on tendermint node and mode on config.toml
  • [ fullnode, validator, seednode ]
  • default is fullnode, except testnet

Refs

  • Wrote tests
  • Updated CHANGELOG_PENDING.md
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
  • Updated relevant documentation (docs/) and code comments
  • Re-reviewed Files changed in the Github PR explorer
  • Applied Appropriate Labels

reopened the PR #5212
Since the last commit of the previous PR, added the following commits according to the review

@codecov
Copy link

codecov bot commented Feb 6, 2021

Codecov Report

Merging #6061 (e80715b) into master (26fd158) will increase coverage by 0.01%.
The diff coverage is 62.72%.

@@            Coverage Diff             @@
##           master    #6061      +/-   ##
==========================================
+ Coverage   60.76%   60.77%   +0.01%     
==========================================
  Files         275      275              
  Lines       25345    25455     +110     
==========================================
+ Hits        15401    15471      +70     
- Misses       8341     8371      +30     
- Partials     1603     1613      +10     
Impacted Files Coverage Δ
cmd/tendermint/commands/run_node.go 0.00% <0.00%> (ø)
cmd/tendermint/commands/testnet.go 23.44% <0.00%> (-0.17%) ⬇️
config/toml.go 60.86% <ø> (ø)
rpc/core/status.go 0.00% <0.00%> (ø)
config/config.go 75.93% <66.66%> (-0.18%) ⬇️
node/node.go 58.17% <69.65%> (+1.14%) ⬆️
consensus/wal_generator.go 70.47% <100.00%> (ø)
libs/clist/clist.go 63.74% <0.00%> (-3.51%) ⬇️
blockchain/v0/pool.go 74.90% <0.00%> (-1.53%) ⬇️
p2p/transport_memory.go 84.93% <0.00%> (-1.37%) ⬇️
... and 11 more

@dongsam dongsam marked this pull request as ready for review February 6, 2021 22:42
Copy link
Contributor

@melekes melekes left a comment

Choose a reason for hiding this comment

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

great work 👍 left a few comments

config/config.go Outdated Show resolved Hide resolved
@@ -89,7 +89,7 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) {
consensusState := NewState(config.Consensus, state.Copy(), blockExec, blockStore, mempool, evpool)
consensusState.SetLogger(logger)
consensusState.SetEventBus(eventBus)
if privValidator != nil {
if privValidator != nil && privValidator != (*privval.FilePV)(nil) {
Copy link
Contributor

Choose a reason for hiding this comment

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

???

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 was trying just checking nil for "no validator", but there were cases privValidator != nil even though privValidator is empty with ModeFullNode, maybe interface typecasting issue

so originally I added the Empty() function to the interface PrivValidator for checking "no validator"

func (pv *FilePV) Empty() bool {
    return pv == (*FilePV)(nil)
}

but then changed it simply to using config because there were too many relevant correction codes.

#5212 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

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

What is the use case for having a FilePV as empty?

docs/nodes/validators.md Outdated Show resolved Hide resolved
docs/nodes/validators.md Outdated Show resolved Hide resolved
cmd/tendermint/commands/run_node.go Outdated Show resolved Hide resolved
privValAddress := env.PubKey.Address()
_, val := vals.GetByAddress(privValAddress)

// If we're still at height h, search in the current validator set.
Copy link
Contributor

Choose a reason for hiding this comment

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

why do we need to change this? is there a separate issue for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this logic is for return empty ValidatorInfo when fullnode mode call rpc /status

#5212 (comment)

@cmwaters
Copy link
Contributor

cmwaters commented Feb 8, 2021

I'm not implying that one or the other is necessary the right default but are we sure we want to default with fullnode rather than validator. If a user is to download the binary and run a single node test net it won't run because it will be a network of one full node. On the other hand, if the user accidentally runs as a validator when just being a full node, they will be treated the exact same as a full node until they join the validator set

@dongsam
Copy link
Contributor Author

dongsam commented Feb 10, 2021

I'm not implying that one or the other is necessary the right default but are we sure we want to default with fullnode rather than validator. If a user is to download the binary and run a single node test net it won't run because it will be a network of one full node. On the other hand, if the user accidentally runs as a validator when just being a full node, they will be treated the exact same as a full node until they join the validator set

That's right. So the default is fullnode mode, but TestConfig for local testnet is set as validator mode so that config.toml of validator mode is created

Copy link
Contributor

@alexanderbez alexanderbez left a comment

Choose a reason for hiding this comment

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

Am I missing something or are all the mode types already implemented? Or does this PR just handle the configuration aspect of it?

UPGRADING.md Outdated Show resolved Hide resolved
cmd/tendermint/commands/run_node.go Outdated Show resolved Hide resolved
@@ -102,6 +105,9 @@ func NewRunNodeCmd(nodeProvider nm.Provider) *cobra.Command {
Use: "start",
Aliases: []string{"node", "run"},
Short: "Run the tendermint node",
Long: `Run the tendermint node

need to set "--mode validator" to run the node as validator`,
Copy link
Contributor

Choose a reason for hiding this comment

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

I do no think this additional comment is necessary. If we want to describe mode we should have a more elaborate description of all the possible values.

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
@dongsam
Copy link
Contributor Author

dongsam commented Feb 16, 2021

Am I missing something or are all the mode types already implemented? Or does this PR just handle the configuration aspect of it?

Thanks for the review, @alexanderbez
the main logic of this PR is implemented in node/node.go

Copy link
Contributor

@cmwaters cmwaters left a comment

Choose a reason for hiding this comment

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

Hey, this is great work 🚀 . Looking forward to getting this over the line.

@@ -561,6 +586,7 @@ type P2PConfig struct { //nolint: maligned
// peers. If another node asks it for addresses, it responds and disconnects.
//
// Does not work if the peer-exchange reactor is disabled.
// automatically set true if Mode of the node is seednode
SeedMode bool `mapstructure:"seed-mode"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want to consider removing this variable. I feel with the introduction of mode, this has been made redundant. Of course you could have a validator with seed mode on but I'm leaning towards separating these i.e. either you're a validator or a seed node. What do people think?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this depends on the p2p refactor. Did we decide to pull out the seed mode in a different binary or?

Copy link
Contributor

Choose a reason for hiding this comment

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

I believe that is still up for discussion, but from the last conversations I heard, moving it to a separate binary is strong contender and there is a possibility that some part of this PR will have to adjusted for that.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hey @dongsam, we had a call yesterday and briefly discussed this, coming to the agreement that we would like to remove the SeedMode config parameter and rely only on the new mode parameter. This will help draw a clearer distinction between operating a seed node and a full node.

Copy link
Contributor

Choose a reason for hiding this comment

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

As to the decision about having it as a separate binary, I'm not too familiar with what the advantages and disadvantages would be. Is it just so that is of a smaller size?

If so, then I'm on board with this. However, I would also want to keep it as part of the main Tendermint binary as convenience to me when I am spinning up test nets and what not. Since we are down this road, is there any argument for the light client to also have its own binary?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the idea is that it's the same binary, but it runs in either a completely isolated mode -- full-node, validator, or seed-mode, but not any combo. i.e. if seed-mode is enabled, it will only run in seed-mode without full-node functionality.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks for the discussion and the feedback, I'll make an additional commit to remove the SeedMode config parameter and rely only on the new mode parameter

@@ -89,7 +89,7 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) {
consensusState := NewState(config.Consensus, state.Copy(), blockExec, blockStore, mempool, evpool)
consensusState.SetLogger(logger)
consensusState.SetEventBus(eventBus)
if privValidator != nil {
if privValidator != nil && privValidator != (*privval.FilePV)(nil) {
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the use case for having a FilePV as empty?

Comment on lines +693 to +701
_, stateDB, err := initDBs(config, dbProvider)
if err != nil {
return nil, err
}

state, genDoc, err := LoadStateFromDBOrGenesisDocProvider(stateDB, genesisDocProvider)
if err != nil {
return nil, err
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
_, stateDB, err := initDBs(config, dbProvider)
if err != nil {
return nil, err
}
state, genDoc, err := LoadStateFromDBOrGenesisDocProvider(stateDB, genesisDocProvider)
if err != nil {
return nil, err
}
genDoc, err := genesisDocProvider()
if err != nil {
return nil, err
}
state, err := sm.MakeGenesisState(genDoc)
if err != nil {
return nil, err
}

IMO, I don't think it makes sense to have a db that just takes the state derived from genesis and is never updated so I would remove dbProvider and just have it like this

Comment on lines +1537 to +1538
state.Version.Consensus.Block,
state.Version.Consensus.App,
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not too sure how full nodes handle this, but AFAICS, state is never updated. I can foresee then that there might be a problem if there is a change to the Block and/or App version where the seed node doesn't get updated and can thus no longer communicate with the block chain. I guess this would mean that the operator would also need to stop their seed node and update their genesis.

Copy link
Contributor

@tac0turtle tac0turtle left a comment

Choose a reason for hiding this comment

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

Is it possible to increase the total amount of peers a seed node can have? By default, we limit it to 50 because more would use high amounts of memory, but since the seed nodes are already running with reduced memory we could increase this amount.

@dongsam
Copy link
Contributor Author

dongsam commented Mar 3, 2021

Is it possible to increase the total amount of peers a seed node can have? By default, we limit it to 50 because more would use high amounts of memory, but since the seed nodes are already running with reduced memory we could increase this amount.

@marbar3778 Does the default limit value 50 mean MaxNumInboundPeers 40 + MaxNumOutboundPeers 10 ?
I think it's okay to increase the default for the lightened seed mode, but those config values are affected by the fullnode or validator, so I'm a little worried about increasing the default values, is that correct?

@cmwaters
Copy link
Contributor

but those config values are affected by the fullnode or validator, so I'm a little worried about increasing the default values, is that correct?

Yeah I would just leave the defaults as is. If we really wanted to, we could create a default seed node config with adjusted params that gets used when starting a seed node through the command line. But for now I would just leave it.

As a more general comment, I would like to get this PR in soon. @dongsam when do you think you will be able to work on this. Would be happy to help you with it if you wanted.

@dongsam
Copy link
Contributor Author

dongsam commented Mar 10, 2021

As a more general comment, I would like to get this PR in soon. @dongsam when do you think you will be able to work on this. Would be happy to help you with it if you wanted.

@cmwaters Thank you for your words and sorry for the delay. It is being delayed because it overlaps with the Liquidity module schedule. I think I can proceed next weekend, I'd appreciate your help.

@cmwaters cmwaters self-assigned this Mar 15, 2021
@cmwaters
Copy link
Contributor

I have created a new PR (#6241) to supersede this as I unfortunately am unable to push to the forked branch

@tac0turtle
Copy link
Contributor

tac0turtle commented Mar 17, 2021

closing in favor of #6241

Thank you for the work @dongsam

@tac0turtle tac0turtle closed this Mar 17, 2021
@cmwaters cmwaters mentioned this pull request Mar 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants