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
Conversation
Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
Codecov Report
@@ 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
|
There was a problem hiding this 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!!
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:
I find it compelling to add a fourth type of node:
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:
The next point I would like to address is the I would propose that all node types share a |
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. |
dab9b90
to
457cd5a
Compare
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. |
6a29bed
to
9e4cc4b
Compare
Maybe, I thought we fixed it. At least there is a test for it. 😬
Well technically it's done via the RPC
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 { | ||
|
There was a problem hiding this comment.
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 { | ||
|
There was a problem hiding this comment.
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" { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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.
Reference PR: #6061