-
Notifications
You must be signed in to change notification settings - Fork 0
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
PoET ticks #124
Comments
Just to clarify, I mentioned that it wasn't straightforward to implement, because of the Group and Merge features, which were added to support PoST. Since then PoST became tree-less, and thus no longer using this lib. If these features will be deprecated, it will probably be easy to implement the support for unbalanced trees. |
can we make ballot syntactically invalid in such case, so that it won't be accepted by the node?
this breaks verifying tortoise. currently it is faster because abstain votes are bounded by zdist, and all other votes can be counted in batches. but if we don't have such bound anymore then verifying tortoise will have the same worst case complexity as full tortoise, it will be less than quadratic but still more complex than linear. |
Have you considered what implications it will have for blocks pruning? Ballot should be able to count vote without checking tick height as it may not be available. It will also have an impact on base ballot selection. Historically we tried to minimize the difference between local opinion and base ballot opinion. Base ballot height needs to be added as a factor into this optimization. Not sure yet how complex is this task. |
@lrettig, I have a feeling that this one is done :) |
Thanks for bringing this up @dshulyak. We're starting to work on block pruning today, so we'll consider this. We need the block's layer if we prune it regardless, so this is just another field.
I'm not sure it should have an impact on that. Both the base ballot and the local ballot (the one we're building) should have an opinion about any block they are aware of (even if it's in "their future"), so they can pick any base ballot and express the diff and votes for "future" blocks will be ignored when counting. I think this is what we decided with Tal, isn't it? |
I only now realized that I responded to a very old comment. I think all these questions have already been discussed and agreed upon. @dshulyak are there still any open questions or something that's unclear in this context? |
Extended spec for the Tortoise voting part of the problem: |
@selfdual-brain implementation part, which was added as #143 was closed, therefore it's not so wise to keep this one open. Please create a new one for the problem mentioned above. |
Missing PoET-related functionality
merkle-tree
Support unbalanced trees
Here's the issue in the
merkle-tree
repo. @moshababo pointed out here that it might not be trivial to implement:Avoid redundant allocation
While someone's in the context of this library, we should probably consider this pull request from someone in the community. @dshulyak pointed out here that since the lib is single-threaded, a simpler solution can be utilized (statically allocate a variable and re-use it). OTOH, it's a generic library that anyone can use, and I'm not sure, but it could possibly work in a multithreaded context, so we can consider not breaking that.
poet
Better configuration / alignment with epochs
The PoET is currently very hard to align with Spacemesh epochs. Currently the core PoET service is configured with 3 parameters:
initialduration
duration
n
If
n
is set low enough, theduration
param dominates and the length is determined by that. This means that PoET completes the proof and then idles until the next round is supposed to begin.In mainnet we'll want to control PoET more tightly. We'll want to set a precise completion time, in such a way that when it's reached execution stops. The flip side is also desirable: there's no reason to stop extending the PoET tree before the completion time is reached. This is especially important in case the PoET server crashes and is restored.
To make alignment even easier and less error prone, I think that configuration should be controlled using only these two parameters:
genesis_time
epoch_duration
tick_size
phase_shift
cycle_gap
Based on these params, PoET will calculate the next round start time. Start times are:
Each round ends
cycle_gap
seconds before the next one begins (this is to allow smeshers to create a PoST proof and publish their ATX without missing registration for the next round).Every time a round ends, any remaining iterations that don't fit in a round number of
tick_size
s will be discarded and a proof will be generated and published.go-spacemesh
Introduce Ticks
The number of ticks in a PoET proof is the
LeafCount
divided byTickSize
, ignoring any remainder.TickSize
should be added to the node configuration. We'll want to set it to a value that will allow PoETs to run ~10,000 ticks in an epoch, based on PoET benchmarks before genesis.A PoET proof's
TickCount
should be available to fetch from thePoetDb
. This will be fetched, at the same time we validate that an ATX that references a PoET proof is really a member. The existing implementation of verifying membership is not currently efficiently implemented (the entire proof message is loaded from disk and deserialized, while only the list of members is needed - and it can probably be even more efficient than that).I leave it up to the developer implementing this to find an efficient way to perform this entire operation of validating membership in a PoET round and fetching this round's
TickCount
. We can store theTickCount
in the DB directly, or calculate it on the fly from theLeafCount
(just an integer division - super cheap).Changes to ATXs
Today, the
NIPostChallenge
(which is eventually embedded inActivationTxHeader
) includesStartTick
andEndTick
fields. There's no reason to explicitly include (or commit to) these values, so they should be removed.These fields are used:
GetWeight()
in order to calculate the total tick count.EndTick
is used inGetPositioningAtxInfo()
, to set theStartTick
of the ATX.We should add the following to
ActivationTxHeader
:baseTickHeight uint64
andtickCount uint64
fields, with matching exported getters (BaseTickHeight() uint64
andTickCount() uint64
).TickHeight() uint64
method, which returns the sum of the two new fields.When a new ATX is validated,
baseTickHeight
is set to the value of the positioning ATX'sTickHeight()
. Also,tickCount
should be extracted from the PoET proof and cached.GetWeight()
should useTickCount()
to multiply with the number of PoST units.In
GetPositioningAtxInfo()
, in the caseif id == b.goldenATXID
we should return0
as theTickHeight
.We should update
UpdateTopIfNeeded()
to replace the top ATX if the new ATX is either in a higher epoch, or in the same epoch and has a higherTickHeight
.Add
TickHeight
to BlocksWhen constructing a block, its height is explicitly included. It's determined by iterating over the ATXs of the proposals used to construct the block, and picking the highest
BaseTickHeight
of all of them.Because the Golden ATX has a
TickHeight
of0
by definition, all ATXs in epoch 1 will have aBaseTickHeight
of0
, so all blocks in epoch 2 (the first epoch with blocks) will have aTickHeight
of0
as well.Tortoise
Limit Ballots Voting for Blocks in Future
Ballots cannot vote for or against blocks with a higher
TickCount
than their ATX, they can only abstain. We need to take this into account and ignore any non-abstain votes in that case.It's assumed that all ATXs in epoch
n
have a higherTickHeight
than any ATX in epochn-1
. This is not guaranteed, but it's a reasonable assumption, at least for a while. This will become a less reasonable assumption when we incentivize smeshers to de-concentrate ATXs (publish them in different layers during the epoch).Break Ties in Layers with Multiple Valid Blocks
There is a possibility that layers end up having more than one valid block. This can happen in extreme cases, when we resort to Weak Coin for voting.
The current mechanism, in this case, executes the block with the lexicographically lowest ID (see
mesh.go → getBlockToApply()
). Instead, we should pick the block with the lowestTickHeight
(the one that the most ballots could vote for and against). Only if this is also a tie, we resort to lexicographic order of IDs.The text was updated successfully, but these errors were encountered: