-
Notifications
You must be signed in to change notification settings - Fork 44
Restructure Codebase #175
Comments
How are you currently stepping through time? If there's a well-defined grid step, you could give each validator a Sample validator delays from some arbitrary distribution (uniform) over the |
You also (maybe?) could add the |
I think this is a good approach and agree that it will clean up the codebase and testing. Bigger design notes/questions:
Minor notes:
|
@naterush also correct me if I'm wrong but it looks like there is a single protocol view that all validators keep track of. This means that all validators always have the same exact view. Do you have plans to let each validator have a potentially unique view of the chain state? |
@drewstone This is already implemented.
Sometimes the output/viewgraphs is just showing us info from the global view so we can get a global perspective on the network. |
Thanks for the great feedback. I've updated the post above to consider most of these comments. I think that a lot of the complexity described above was a result of not having rounds (which it turns out - though they seem unnecessary, are fairly necessary). As such, I've changed the above description to have rounds again; the key here is that we only really need them when a) creating the execution string, and b) calculating when to display (if we are displaying something). Reintroducing them seems to solve all the problems, but let me know if you see any other issues. Also, most of the minor notes seem reasonable to me. I've justified some decisions (like the separate |
There's one more thing I want to make sure we can handle, but I'm not exactly sure how to do it. Essentially: we need to control how initial messages are propagated. For example: currently, we send all initial messages to everyone at the start of a binary protocol, but this leads to all messages have the same estimate for the rest of time (b/c everyone has seen everything), which isn't very interesting. So we need more control over the execution over how these initial messages are propagated. There are a couple solutions here:
Personally, I think 1 is the cleanest solution. Any other thoughts/suggestions are greatly appreciated. |
So I figured out a way to actually handle the special case in a general manner, without doing much extra work. Essentially: the first time a validator 0 sends a message to validator 1, they send it in a justified manner (by including all the other blocks they sent as well). |
Rounds in string generators with passing some info along with the execution string (length of round) is a good trade off :) Notes:
|
As for your fix on the sending of initial messages.. Are you proposing that when Val-0 (whose initial message was A) sends its first message (B) to Val-1, that both A and B are attempted to be propagated to Val-1?
|
@djrtwo I am suggesting the first. Essentially, we insist that the first time Val-0 sends to Val-1 (say they are sending message B), we use |
I think that sending in the length of the round is a nice solution - as well as leaving display and save out. I'll update the spec with this now. Agree on defaulting to one - especially in the case of more complex strategies. |
One final change: I'm proposing some changes to the testing language so it's more extensible for any possible future protocol executions we might want. There are two base commands:
Other validity conditions:
Furthermore, we also add the following . The base make command is For example, we could have The regex for matching these commands is: |
Does that mean make block F forgetting that I made block E? Or is it making
block F explicitly with E as estimate?
…On Tuesday, March 20, 2018, Nate Rush ***@***.***> wrote:
Last thing I'd like to add to the specification before we move forward:
keeping the language as general as possible... will post on this in a day.
Side note: just figured out how to do an equivocation: M0-F(E-{A, B, C,
D}), where the second part essentially says that it's an equiocation, and
gives a set of messages are are included in the justification of the new
message.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#175 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABXf-0GWrrjx-OMQzkN3wS29pdEfd1foks5tgH2TgaJpZM4Smr4x>
.
|
@djrtwo updated with explanation of new commands. |
Merged! |
Issue
The codebase is not currently optimized for readability and extensibility. There are currently multiple classes that do the exact same work (or no work at all) like test langs, simulation runner, and protocol. In general, would be nice if we could crunch all of these into one - which would make the codebase much more understandable and comprehensible. Yay!
Proposed Implementation
Overview
For each protocol, create a
XProtocol
class (for example,BlockchainProtocol
). Note that this is different than the currentBlockchainProtocol
class that exists today.The protocol class is instantiated with a JSON object that specifies the execution of the entire protocol. Here's an example JSON object for a concurrent schedule replication:
Obviously, each protocol would have a required set of fields, as well as validity conditions about the JSON object (reasonable things like
len(initial_estimates) = len(validators)
). See at end of post for spec of each JSON object. The goal is that the entire execution is totally deterministic from the JSON object.This can then be run with
protocol.execute()
, which essentially consumes theexecution_string
, printing/making GIFs where appropriate.Displayz
Each
XProtocol
class take three (optional) other than the setup string:interval, display, save
.interval
defaults to if not specified, anddisplay
andsave
both default toFalse
.The interval is measured in rounds where one round is
msg_per_round
number of messages being created. Ifdisplay == True
,interval == 3
, andmsg_per_round = 1
, then a viewgraph will appear after every 3 messages are created. This makes it simple to display viewgraphs in cases like full message propagation:msg_per_round = len(validators)
.Thus, depending on the message default being used,
msg_per_round
changes: (random, 1) (rrob, 1) (full, len(val_set)), etc.Initial messages
Currently, there is some weirdness is how initial messages are created and dealt with. The new proposed method is essentially adding a method
add_initial_messages
to each view (or validator), and removing the instantiation of view with messages.The reasoning for this is that a validator's view is created when the validator is, but some initial message schemes require all of the validators to be created before creating the initial messages, so we must treat these as two separate steps.
It looks like this:
It might make sense to push the
set_initial_messages
functions down to the view only, and not have the validator have access to this. Not sure what is best here.The benefits to this are simple: each protocol can now do initial messages in its own way. Sharding has multiple genesis messages (one for each shard), and deals with this in a strange manner currently. This new approach would resolve this.
execution_string
Now, we must specify how to generate execution strings. This is a bit more complicated than it initially looks; consider how to handle different networks as we currently have.
However, I think we can essentially 'rip out' our existing message generation and networking stuff, to create some interesting
ExecutionGenerator
classes. Some of these could beRandomExecutionGenerator
,RrobExecutionGenerator
, etc (these are essentially the message generator classes that exist today.Note: each of these classes has knowledge of how long a "round" is for itself. This is how we get the round number described above that is used when displaying (it can return this along w/ the execution string).
Furthermore, we must be able to specify networks that these classes can use to figure out when messages actually get delivered. However, this is fairly easy; because we can have the protocol string be generated round by round (some type of loop makes the most sense anyways), we can have messages, upon creation, check a delay function for how many rounds later they should be delivered.
For example (this is an example of full message propagation, but you get the idea)
Thus, we can carry over the same delay functions that we have currently to get the effect of the network!
Note that we can also store a
max_round
variable, and require that all messages are delivered before this max round.Misc.
protocol.execute()
takes an optional string. If you callprotocol.execute(s)
thenprotocol.execute(t)
then you would be left at the state gotten to via json_string + s + t.Conclusion
The benefits of this approach:
venv/bin/python casper.py --execution network_split
or other setups that have interesting situations...JSON objects for different protocols
Note that throughout each of these protocols, reasonable rules apply to the execution strings: you can’t send messages before they exist, and the creator of a message must be a real validator.
Binary
len(validators) == len(initial_estimates)
initial_estimates
must be 0 or 1Integer
len(validators) == len(initial_estimates)
initial_estimates
must be an integerOrder
len(validators) == len(initial_estimates)
initial_estimates
must be a permutation of some list (when converting them to a set, must be equal - assuming no duplicates).Blockchain
Concurrent Schedule
len(validators) == len(initial_estimates)
initial_estimates
must be a subset of the starting outputs.Sharded blockchain
num_shards
>= 2num_shards <= len(validators)
In the future, we can add:
which a) must have shard ids for the number of shards, and b) has validators go through very specific state transitions. This can be used with some
val_select_shards
rules.The text was updated successfully, but these errors were encountered: