-
Notifications
You must be signed in to change notification settings - Fork 166
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
Running an unstaked Access Node #911
Conversation
@@ -124,6 +128,15 @@ func main() { | |||
panic(err) | |||
} | |||
|
|||
fmt.Println("Node bootstrapping data generated...") |
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.
to help distinguish between the staked versus the unstaked AN.
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.
e.g. output
Node bootstrapping data generated...
1: execution-9897aa81bbf63ff72dab471ae7f025af81c8227704a7287ce04f6411663bf36b@execution_1:2137=1000
2: collection-71b7873bc7421c7e6c5c269768c49f07e1de7e1e7a886b20f678625c7b04b29a@collection_1:2137=1000
3: consensus-d039bfff32380e4482a5272c35a822d303ac2cd97fc1b5ca2242bff72039c81d@consensus_1:2137=1000
4: verification-e07013fb410df9f9d3a19566d6341bf7a77dd6eeefc3cb1a9412969fdca6cead@verification_1:2137=1000
5: access-4b4381b604a5fcb60e98a485c29adef262e5ab1617b43a1ec3137a2b8563e8b4@access_1:2137=1000
6: access-4f86c7a6a33ff21d4cf3e4612840a8fb5f90788fb2c7ef0c71a4f7d524ddac8b@access_2:2137=1000 (unstaked)
@@ -583,19 +584,43 @@ func BootstrapNetwork(networkConf NetworkConfig, bootstrapDir string) (*flow.Blo | |||
return nil, nil, nil, nil, fmt.Errorf("failed to setup keys: %w", err) | |||
} | |||
|
|||
// write private key files for each node |
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.
moved up to separate out staked vs non-staked nodes before calling runDKG
for only the staked nodes.
Codecov Report
@@ Coverage Diff @@
## master #911 +/- ##
==========================================
- Coverage 54.85% 54.79% -0.06%
==========================================
Files 284 285 +1
Lines 18872 18876 +4
==========================================
- Hits 10352 10343 -9
- Misses 7123 7138 +15
+ Partials 1397 1395 -2
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
@@ -114,7 +114,7 @@ func NewMiddleware(log zerolog.Logger, | |||
} | |||
} | |||
|
|||
func defaultValidators(log zerolog.Logger, flowID flow.Identifier) []network.MessageValidator { | |||
func DefaultValidators(log zerolog.Logger, flowID flow.Identifier) []network.MessageValidator { |
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.
Making public so that it can be used in scaffold.
cmd/scaffold.go
Outdated
@@ -135,6 +136,7 @@ type FlowNodeBuilder struct { | |||
postInitFns []func(*FlowNodeBuilder) | |||
stakingKey crypto.PrivateKey | |||
networkKey crypto.PrivateKey | |||
Unstaked bool |
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.
This is the flag used to determine if the node should run as staked (Unstaked=false
) or unstaked (Unstaked=true
). Although it is only used for an access node, it is define here in scaffold because it needs to influence how the node is initialized by the flow node builder.
cmd/scaffold.go
Outdated
// filter out messages sent by this node itself | ||
validator.NewSenderValidator(fnb.Me.NodeID()), | ||
// but retain all the 1-k messages even if they are not intended for this node |
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.
Can you explain this part a little more? Why do we filter out messages sent by this node itself, and what is the significance of 1-k?
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.
sure..currently, when you send a 1-k message (in other words, publish a message on a topic), the network layers seems to also loopback the message to the sender if the sender has also subscribed to the topic. This is not desired and hence a validator was added to filter out such messages which have the Origin field in the message equal to the node ID of the node (loop back messages).
Also, when you send a 1-k message, the sender has to specify a list of TargetIDs which indicate the nodes for which the message is intended. This is generally a subset of nodes subscribed on the topic. e.g. If a collection node sends a tx to collection node 1, 2 and 3, it will be received by ALL collection nodes in the system since they are all subscribed to the send-transaction channel. The target validator makes sure that only the intended targets receive the message and the other nodes just drop it.
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 guess my question is, why does the behavior of the staked vs unstaked node need to be different?
Can you explain how exactly the behavior will be different here between the staked and unstaked version?
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.
@smnzhu I think what @vishalchangrani is saying is that the normal pattern is to address messages to a TargetID which requires to have the AN maintain current a set of unstaked ANs. By not doing that, we remove the duty to care about that set, but we also make validators that look for a node's own targetID pointless at the unstaked receiver AN.
cmd/access/main.go
Outdated
if staked { | ||
return | ||
} | ||
if strings.TrimSpace(stakedAccessNodeIDHex) == "" { |
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.
yet to add code to actually use the staked access node id
…zation; changing scafold to to seperate out initialition from construction
I think that will be possible. Lemme work on that. I didn't realize I would need so many changes on the base class until after I finished it. |
Refactored the code to address this comment. Now, the structure is as follows:
|
@huitseeker - To address the issue of not letting the unstaked AN know about the identities of the staked node at all, I have created this new issue The unstaked Access Node should bootstrap without the identity list of the staked network |
4a06354
to
269981a
Compare
@jordanschalm @huitseeker @smnzhu - To help make the code review a little easier, I moved all the bootstrap changes to scaffold into its own separate PR here - #983. This new PR is based off of this branch ( |
cmd/access/access_node_builder.go
Outdated
unstakedMiddleware *p2p.Middleware | ||
} | ||
|
||
func FlowAccessNode() *AccessNodeBuilder { |
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.
We could move this and the existing FlowNodeBuilder
to a scaffold
package together to avoid all the newly public methods in FlowNodeBuilder
and keep the scaffolding logic together.
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.
Lemme do this in the other PR since that one is primarily for such scaffold related changes.
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.
Actually, lemme do that as different PR all together once I have 983 merged into this one otherwise it will just become even more difficult to review.
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.
created this issue to address this comment
// It is composed of the FlowNodeBuilder | ||
type AccessNodeBuilder struct { | ||
*cmd.FlowNodeBuilder | ||
staked bool |
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 wonder if there is a different term than "unstaked" that we can use for this new mode of operation for the Access Node. Being unstaked doesn't really describe the new mode of operation very well IMO, and the notions of stake and weight are already a bit overloaded and frankly confusing in parts in the protocol code (see here for an example).
For example, in the NodeConfig
we have a field called Stake
, which really means Weight
and we have a field called Unstaked
which only applies to access nodes, doesn't have much to do with the field called Stake
, and determines whether an AN runs in this new external network or as part of the core Flow network.
Some ideas: External AN / network, Proxy AN / network, Adjunct AN / network
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.
Public network? (versus our current private network)
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.
tbh - i like the word unstaked network
it succinctly describes this network as a network of unstaked actors. Any other name seems to be requiring more explanation since our flow network is public and external.
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.
Maybe in places where the new field / name is near an existing stake/weight reference we can expand the name to differentiate or add some comments to differentiate
Co-authored-by: Jordan Schalm <jordan@dapperlabs.com>
|
||
// SupportUnstakedNodes returns True if this a staked Access Node which also participates in the unstaked network, | ||
// False otherwise | ||
func (builder *StakedAccessNodeBuilder) supportUnstakedNodes() bool { |
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 think we should put this function on the parent interface AccessNodeBuilder
, and rename to something like ParticipatesInUnstakedNetwork
.
This is because the main.go
will need to use this function to determine whether to create a splitter engine and relay engine for a staked access node.
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.
done
@jordanschalm @huitseeker @smnzhu - thanks for the diligent review on this PR so far! ❤️ |
cmd/access/access_node_builder.go
Outdated
func (anb *FlowAccessNodeBuilder) parseFlags() { | ||
// supportUnstakedNodes returns True if this a staked Access Node which also participates in the unstaked network, | ||
// False otherwise | ||
func (builder *FlowAccessNodeBuilder) supportUnstakedNodes() bool { |
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.
What I meant was to add it to the AccessNodeBuilder
interface, not only the FlowAccessNodeBuilder
implementation. See this for example.
We would rename the method as ParticipatesInUnstakedNetwork
(or some other name which does not imply whether the node is staked or not), and it would always return true for unstaked nodes.
Of course, instead of doing this I could just do a type assertion here, but I think this way is a little bit cleaner.
But if we don't want to add the method to the interface, then IMO we should probably just leave it on the StakedAccessNodeBuilder
and do the type assertion.
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.
oh shoot! I forgot to push the commit with that change. Yes, 100% agree that method should be on the interface.
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.
Superb work!
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.
Nice work 🎸
thanks for all the amazing feedback..really appreciate it! |
This is the first set of changes needed to run an Unstaked Access node (an access node whose identity is not part of the identity table). This brings up the AN as a stand alone program or as part of the localnet.
There are two different networks - unstaked network and staked network. An unstaked access node only joins the unstaked network. A staked access node joins both the unstaked and the staked network.
This PR introduces the following changes:
scaffold.go
to allow initializing an unstaked access node a little differently than a regular node via newPreInit
functions and exported public functions.AccessNodeBuilder
to initialize and run a staked or an unstaked access node.Currently, the unstaked Access node does expect the genesis data (root snapshot) AND the
node-info.json
. It reads thenodeid
and the networking key from it (not the staking key).I could generate the networking key and the node id on the fly as the node starts but I am wondering if there is value in asking the node operator to provide a node id (maybe for auditing traffic coming into a staked access node).
the unstaked access node can be run using the args:
the staked access node can be run using the args:
To run in IDE specify params here -