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 tendermint modes #6241

Merged
merged 22 commits into from Mar 18, 2021
Merged

Conversation

cmwaters
Copy link
Contributor

Reference PR: #6061

@codecov
Copy link

codecov bot commented Mar 16, 2021

Codecov Report

Merging #6241 (8432063) into master (c52de48) will decrease coverage by 0.10%.
The diff coverage is 56.02%.

@@            Coverage Diff             @@
##           master    #6241      +/-   ##
==========================================
- Coverage   60.84%   60.74%   -0.11%     
==========================================
  Files         277      277              
  Lines       25943    26060     +117     
==========================================
+ Hits        15785    15830      +45     
- Misses       8530     8590      +60     
- Partials     1628     1640      +12     
Impacted Files Coverage Δ
cmd/tendermint/commands/run_node.go 0.00% <0.00%> (ø)
cmd/tendermint/commands/testnet.go 22.22% <0.00%> (-0.15%) ⬇️
config/toml.go 60.86% <ø> (ø)
rpc/core/status.go 0.00% <0.00%> (ø)
node/node.go 58.35% <60.36%> (+0.79%) ⬆️
config/config.go 75.86% <77.77%> (-0.26%) ⬇️
consensus/wal_generator.go 70.47% <100.00%> (ø)
privval/signer_server.go 89.47% <0.00%> (-5.27%) ⬇️
types/tx.go 82.97% <0.00%> (-4.26%) ⬇️
blockchain/v0/pool.go 73.00% <0.00%> (-3.43%) ⬇️
... and 10 more

@cmwaters cmwaters marked this pull request as ready for review March 16, 2021 18:48
CHANGELOG_PENDING.md Outdated Show resolved Hide resolved
node/node.go Outdated Show resolved Hide resolved
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.

Thanks for pushing this over the finish line!!

@cmwaters
Copy link
Contributor Author

cmwaters commented Mar 17, 2021

There are a few points / ideas that came to mind whilst working on this that I would like to document (I may do also in a separate issue). This PR (and the prior work and ADR) ultimately move us in the direction of making clearer separations in the types of nodes and the roles they play in the network. Specifically:

  • Validator Node -> proposes and votes on blocks
  • Full Node -> gossips txs, participates in consensus, validates and stores blocks, provides endpoints for data availability
  • Seed Node -> keeps an address book of a large part / the entire network, providing peers that nodes can connect with.

I find it compelling to add a fourth type of node:

  • Light Node -> runs a light client and an RPC client.

This is something that of course already exists but I believe needs to be explicitly named in a way that groups it with the rest of the nodes and is more intuitive for people familiarising themselves with Tendermint / Cosmos SDK. To make the distinction clear:

  • IBC uses a light client
  • A wallet runs a light node

The next point I would like to address is the Config file. Given this growing separation between the different nodes in a network, I see two paths we can go down: 1) A "one config to rule them all" approach where one large config file can be used for every node. 2) A config file specific to the node. Currently we side with the former. What this means is that an operator could stop a full node and run a seed node from the exact config. It also means that If I'm running a seed node, my config.toml file is filled with variables that have no relation to a seed node i.e. MempoolConfig or ConsensusConfig. I think this is just bad UX and may confuse end users. I would also argue that it would be more beneficial to this separation if an operator couldn't simply switch modes but would have to start a new process.

I would propose that all node types share a BaseConfig(this already exists). The BaseConfig would indicate the mode and thus how the rest of the toml file should be read. Seed nodes would have a SeedConfig and light nodes would have a LightConfig

@cmwaters cmwaters closed this Mar 17, 2021
@cmwaters cmwaters reopened this Mar 17, 2021
@tac0turtle
Copy link
Contributor

I find it compelling to add a fourth type of node:

* Light Node -> runs a light client and an RPC client.

I would say this is more up to the application (cosmos/cosmos-sdk#6563). Reason we can not offer this type of node is because we don't know the apps proof design making queries through the light client not usable. IMO we shouldn't have a cmd for it either, it should be app specific.

I agree with your second point. Having two configs will cause less confusion and better the UX for outr users.

@cmwaters cmwaters force-pushed the ADR-52-Tendermint-Mode-reopen-PR branch from dab9b90 to 457cd5a Compare March 17, 2021 14:52
@cmwaters
Copy link
Contributor Author

I would say this is more up to the application (cosmos/cosmos-sdk#6563). Reason we can not offer this type of node is because we don't know the apps proof design making queries through the light client not usable. IMO we shouldn't have a cmd for it either, it should be app specific.

Right, the verification of ABCI queries is a difficult one although I believe any app through the cosmos sdk has the same proof design which is the default of the TM light node. Also, aren't the other uses of a light node, verification of headers and txs also valuable?

@tac0turtle
Copy link
Contributor

Right, the verification of ABCI queries is a difficult one although I believe any app through the cosmos sdk has the same proof design which is the default of the TM light node. Also, aren't the other uses of a light node, verification of headers and txs also valuable?

Does it work? Last I checked it was still broken. What is the use case for verifying headers via cli? Verifying txs is possible, but it's more valuable to have a single light client defined by the app to do both queries and tx verification. We can add it, but I would guess it would cause confusion with so many options.

@cmwaters cmwaters force-pushed the ADR-52-Tendermint-Mode-reopen-PR branch from 6a29bed to 9e4cc4b Compare March 17, 2021 15:54
@cmwaters
Copy link
Contributor Author

Last I checked it was still broken.

Maybe, I thought we fixed it. At least there is a test for it. 😬

What is the use case for verifying headers via cli?

Well technically it's done via the RPC

more valuable to have a single light client defined by the app to do both queries and tx verification

Totally agree. I think I need to do some more thinking about it because I would like to make light clients/nodes something that provides greater utility to applications. Currently, the model is to have light clients quite separate from application. The light client doesn't store any app state or have any connection with the app. Perhaps we could have an ABCI Light (😅 ) that gives the application the app hash and a proof for verification.

I think a valuable use case for a light node would be to track partial state. I.e. perhaps I just want to know all the transactions that occur with a specific type or attribute (a logical example would be tracking transactions to and from an account). A light node could listen for events on a full node and when the tx was made, verify it and update that specific part of state. I don't know, I'm just thinking aloud.

@tac0turtle
Copy link
Contributor

Totally agree. I think I need to do some more thinking about it because I would like to make light clients/nodes something that provides greater utility to applications. Currently, the model is to have light clients quite separate from application. The light client doesn't store any app state or have any connection with the app. Perhaps we could have an ABCI Light (😅 ) that gives the application the app hash and a proof for verification.

I think a valuable use case for a light node would be to track partial state. I.e. perhaps I just want to know all the transactions that occur with a specific type or attribute (a logical example would be tracking transactions to and from an account). A light node could listen for events on a full node and when the tx was made, verify it and update that specific part of state. I don't know, I'm just thinking aloud.

I like some of these ideas. We should do a brainstorm session on these and other ideas, the scope can easily get large, but it would be fun to see what we come up with.

node/node.go Outdated

err = sw.AddPersistentPeers(splitAndTrimEmpty(config.P2P.PersistentPeers, ",", " "))
if err != nil {

Copy link
Contributor

Choose a reason for hiding this comment

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

nit, blank line

node/node.go Outdated
if err := n.bcReactor.Start(); err != nil {
return err
if n.config.Mode != cfg.ModeSeed {

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: line

node/node.go Outdated
return err
if n.config.Mode != cfg.ModeSeed {

if n.config.FastSync.Version == "v0" {
Copy link
Contributor

Choose a reason for hiding this comment

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

is "v0" a constant somewhere that we could use?

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, I don't think so. We could add one

if n.config.Mode == cfg.ModeValidator {
pubKey, err := n.privValidator.GetPubKey(context.TODO())
if pubKey == nil || err != nil {
return fmt.Errorf("can't get pubkey: %w", err)
Copy link
Contributor

Choose a reason for hiding this comment

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

is this error salient when pubkey is nil and error is nil?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yup. I'm not sure if there is a case where it happens, but if it does we should still error

nodeInfo.ListenAddr = lAddr

err := nodeInfo.Validate()
return nodeInfo, err
Copy link
Contributor

Choose a reason for hiding this comment

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

should we return a non-nil node info when err is non nil?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The assumption is generally to read the error first, so I think it should be fine

func TestNodeNewSeedNode(t *testing.T) {
config := cfg.ResetTestRoot("node_new_node_custom_reactors_test")
config.Mode = cfg.ModeSeed
defer os.RemoveAll(config.RootDir)
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 sure, but it seems like t.Cleanup() might be better at cleanup but I'm not sure.

@cmwaters cmwaters merged commit 9f7051d into master Mar 18, 2021
@cmwaters cmwaters deleted the ADR-52-Tendermint-Mode-reopen-PR branch March 18, 2021 10:17
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

4 participants