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

Tracking metablocks' rounds in the Consensus contract. #103

Merged
merged 42 commits into from
Dec 19, 2019

Conversation

pgev
Copy link
Collaborator

@pgev pgev commented Dec 9, 2019

Fixes #92
Fixes #95

@pgev pgev requested a review from deepesh-kn December 9, 2019 11:06
@@ -91,29 +103,28 @@ contract Consensus is MasterCopyNonUpgradable, CoreStatusEnum, ConsensusI {
/** Coinbase split per mille */
uint256 public coinbaseSplitPerMille;

/** Block hash of heads of Metablockchains */
mapping(bytes20 /* chainId */ => bytes32 /* MetablockHash */) public metablockHeaderTips;
/** Mapping of a metablock number to a metablock (per chain). */
Copy link
Contributor

Choose a reason for hiding this comment

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

"(per metachain)"; also on L109

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.


/** Core statuses */
mapping(address /* core */ => CoreStatus /* coreStatus */) public coreStatuses;
/** Metablocks' heights per chain. */
Copy link
Contributor

@benjaminbollen benjaminbollen Dec 9, 2019

Choose a reason for hiding this comment

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

/** Metablockchains' current height of tip per metachain. */

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

mapping(address /* core */ => CoreStatus /* coreStatus */) public coreStatuses;

/** Linked-list of committees. */
mapping(address => address) public committees;
Copy link
Contributor

Choose a reason for hiding this comment

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

mapping(bytes32 /* metachainId */ => CommitteeI) public committees;

Copy link
Contributor

Choose a reason for hiding this comment

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

that way, there is less state build-up on Consensus; when a new metablock is precommitted; this mapping can be overwritten.

In return the pruning of Committees can be done from the committee itself; it can check whether it can be selfdestructed by checking open balances, and whether it has reported the decision / latest, if the metablockchain has moved on to another blockheight

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We can create a follow up ticket for this. What are your thoughts?

Copy link
Contributor

@benjaminbollen benjaminbollen left a comment

Choose a reason for hiding this comment

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

Hi ! last night i drafted the storage layout I had in mind for Consensus.sol after this ticket. you can find it here

https://github.com/mosaicdao/mosaic-pm/blob/master/specification-discussions/20191206-consensus.md#contract-summary

I can also give it a try to implement the functions according to this storage. Please evaluate from your side whether this is a sensible proposal cc @deepesh-kn @pgev

Copy link
Collaborator

@deepesh-kn deepesh-kn left a comment

Choose a reason for hiding this comment

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

👍
Lot of changes. Added a few comments.

contracts/consensus/Consensus.sol Outdated Show resolved Hide resolved
contracts/consensus/Consensus.sol Show resolved Hide resolved
contracts/consensus/Consensus.sol Show resolved Hide resolved
contracts/consensus/Consensus.sol Show resolved Hide resolved
@deepesh-kn deepesh-kn removed their assignment Dec 18, 2019
@pgev pgev requested a review from deepesh-kn December 18, 2019 08:02
deepesh-kn
deepesh-kn previously approved these changes Dec 18, 2019
Copy link
Collaborator

@deepesh-kn deepesh-kn left a comment

Choose a reason for hiding this comment

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

looks good. I added a comment and have created a followup ticket #147 to update enterCommittee

)
private
view
returns (bytes32 seed_)
{
assert(length > 0);

uint256 begin = end.add(uint256(1)).sub(length);
Copy link
Collaborator

Choose a reason for hiding this comment

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

  1. hashBlockSegment is used only at one place, so we need to pass the length, its already a constant.
  2. For me, It was difficult to understand this part of the code, just a suggestion.
    Instead of adding add(uint256(1)) here, can be do the following in the for loop:
for (uint256 i = 1; i <= length; i = i.add(1)) {
            seedGenerator[i] = blockhash(begin.add(i));
        }	        

Copy link
Contributor

Choose a reason for hiding this comment

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

  1. assuming you meant "we don't" need to pass the length? agreeing with this comment

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@deepesh-kn with regards to the 2. point I would rather keep existing implementation.
@deepesh-kn @benjaminbollen wrt 1. point, I am not sure why should not be function written as a standalone function. However, I will change it as you both have proposed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

Copy link
Collaborator

Choose a reason for hiding this comment

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

  1. assuming you meant "we don't" need to pass the length? agreeing with this comment

yes, I meant we don't.

contracts/consensus/Consensus.sol Show resolved Hide resolved
contracts/consensus/Consensus.sol Show resolved Hide resolved
@@ -272,7 +283,6 @@ contract Committee is MasterCopyNonUpgradable, ConsensusModule, CommitteeI {

proposal = _proposal;

// @qn (pro): In case of 7 quorum should be 4 or 5.
quorum = _committeeSize * COMMITTEE_SUPER_MAJORITY_NUMERATOR /
COMMITTEE_SUPER_MAJORITY_DENOMINATOR;
Copy link
Contributor

Choose a reason for hiding this comment

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

missing indentation

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

abi.encodePacked(seedGenerator)
bytes32 seed = hashBlockSegment(
committeeFormationBlockHeight,
COMMITTEE_FORMATION_LENGTH
Copy link
Contributor

@benjaminbollen benjaminbollen Dec 18, 2019

Choose a reason for hiding this comment

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

why are we passing the constant to an internal function?

consider instead passing the metablockHash, because otherwise if multiple precommits happen in the same Ethereum block, they will all have the same seed, and thus the same committee.

cc @deepesh-kn @jayeshbairagi can we make this a separate task?

        bytes32 seed = hashBlockSegments(
            currentMetablock.metablockHash,
            committeeFormationHeight);

(reference https://github.com/mosaicdao/mosaic-pm/blob/master/specification-discussions/20191206-consensus.md)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

"Further validator's address is 0."
);

require(
Copy link
Contributor

Choose a reason for hiding this comment

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

can we collapse these into a modifier

onlyAssignedCore(_metachainId)

in a new ticket?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In the current implementation of enterCommittee the core of the validator is specified by its address (not metablockchain id). In upcoming implementation of enterCommittee (according to the newest proposal) we can.

address core = assignments[_metachainId];
bytes32 metablockHash = goToCommittedRound(_metachainId);

CoreI core = assignments[_metachainId];
require(
Copy link
Contributor

Choose a reason for hiding this comment

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

ok for now, but it's more of an assert than anything; the assigned core should be active

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@benjaminbollen do you mean here, that cores in assignments storage mapping will not keep halted/corrupted cores?

"Core does not exist for given metachain."
);

// Specified core must have creation lifetime status.
require(
coreLifetimes[core] == CoreLifetime.creation,
coreLifetimes[address(core)] == CoreLifetime.creation,
Copy link
Contributor

Choose a reason for hiding this comment

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

the mapping should probably be from CoreI => CoreLifetime?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

To my knowledge, solidity mapping key can be only elementary type.

Copy link
Collaborator Author

@pgev pgev Dec 19, 2019

Choose a reason for hiding this comment

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

Mapping types use the syntax mapping(_KeyType => _ValueType) and variables of mapping type are declared using the syntax mapping(_KeyType => _ValueType) _VariableName. The _KeyType can be any built-in value type plus bytes and string. User-defined or complex types such as contract types, enums, mappings, structs or array types apart from bytes and string are not allowed. _ValueType can be any type, including mappings, arrays and structs.

https://solidity.readthedocs.io/en/v0.6.0/types.html#mapping-types

uint256 begin = end.add(uint256(1)).sub(length);

require(
block.number >= end && block.number < begin.add(uint256(256)),
Copy link
Contributor

Choose a reason for hiding this comment

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

block.number must be strictly greater than end, bc the blockhash of the current block is not yet known

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes. 🤦. Thanks!

Copy link
Contributor

@benjaminbollen benjaminbollen left a comment

Choose a reason for hiding this comment

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

Looks very good, great progress; thanks, and sorry for the long road to get here;

mostly requesting a small change, can you look and assert this point?
https://github.com/mosaicdao/mosaic-1/pull/103/files#r359458898

the other comments should largely be captured in new tickets; can you assist here @jayeshbairagi we can go over them tomorrow

Copy link
Contributor

@benjaminbollen benjaminbollen left a comment

Choose a reason for hiding this comment

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

LGTM!

@benjaminbollen benjaminbollen merged commit 86908bf into mosaicdao:feature/consensus Dec 19, 2019
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.

3 participants