-
Notifications
You must be signed in to change notification settings - Fork 110
feat(ethexe-consensus
): implement changing validator set for the next era
#4847
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
base: master
Are you sure you want to change the base?
Changes from 9 commits
b73c2b9
5dacb53
edbb71f
e394146
d17ddcb
9b808e7
b3726f6
6d295fa
3e97eb0
335d274
155e794
96e2a3b
f6a8560
7f4d487
14e6724
9d0c4a3
b11d624
549c71d
329c156
1afd3da
32e7617
1f0f271
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -19,11 +19,12 @@ | |||||
//! Ethereum address. | ||||||
|
||||||
use super::keys::PublicKey; | ||||||
use alloc::string::String; | ||||||
use alloc::{string::String, vec::Vec}; | ||||||
use core::str::FromStr; | ||||||
use derive_more::{Debug, Display, Error}; | ||||||
use gprimitives::{ActorId, H160}; | ||||||
use hex::FromHexError; | ||||||
use nonempty::NonEmpty; | ||||||
use parity_scale_codec::{Decode, Encode}; | ||||||
use sha3::Digest as _; | ||||||
|
||||||
|
@@ -120,6 +121,73 @@ impl From<Address> for ActorId { | |||||
} | ||||||
} | ||||||
|
||||||
/// [`ValidatorsVec`] is a wrapper over non-empty vector of [`Address`]. | ||||||
/// It is needed because `NonEmpty` does not implement `Encode` and `Decode`. | ||||||
#[derive( | ||||||
Debug, | ||||||
Clone, | ||||||
Default, | ||||||
PartialEq, | ||||||
Eq, | ||||||
Hash, | ||||||
derive_more::Deref, | ||||||
derive_more::DerefMut, | ||||||
derive_more::IntoIterator, | ||||||
)] | ||||||
pub struct ValidatorsVec(NonEmpty<Address>); | ||||||
|
||||||
// Encode / Decode implementations | ||||||
impl Encode for ValidatorsVec { | ||||||
fn encode(&self) -> Vec<u8> { | ||||||
Into::<Vec<_>>::into(self.0.clone()).encode() | ||||||
} | ||||||
} | ||||||
|
||||||
impl Decode for ValidatorsVec { | ||||||
fn decode<I: parity_scale_codec::Input>( | ||||||
input: &mut I, | ||||||
) -> Result<Self, parity_scale_codec::Error> { | ||||||
let inner: Vec<Address> = Decode::decode(input)?; | ||||||
NonEmpty::from_vec(inner) | ||||||
.map(Self) | ||||||
.ok_or(parity_scale_codec::Error::from( | ||||||
"Failed to decode ValidatorsVec: empty vector", | ||||||
)) | ||||||
} | ||||||
} | ||||||
|
||||||
#[derive(Debug, Display, Error)] | ||||||
#[display("{:?}", self)] | ||||||
#[debug("ValidatorsVec must be non-empty")] | ||||||
|
#[debug("ValidatorsVec must be non-empty")] | |
#[debug("Vec must be non-empty")] |
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.
useful
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,8 +21,8 @@ | |
// TODO #4547: move types to another module(s) | ||
|
||
use crate::{ | ||
Address, BlockHeader, BlockMeta, CodeBlobInfo, ProgramStates, Schedule, events::BlockEvent, | ||
gear::StateTransition, | ||
BlockHeader, BlockMeta, CodeBlobInfo, GearExeTimelines, ProgramStates, Schedule, | ||
events::BlockEvent, gear::StateTransition, primitives::ValidatorsInfo, | ||
}; | ||
use alloc::{ | ||
collections::{BTreeSet, VecDeque}, | ||
|
@@ -33,7 +33,6 @@ use gear_core::{ | |
ids::{ActorId, CodeId}, | ||
}; | ||
use gprimitives::H256; | ||
use nonempty::NonEmpty; | ||
use parity_scale_codec::{Decode, Encode}; | ||
|
||
#[derive( | ||
|
@@ -61,6 +60,14 @@ impl BlockOutcome { | |
} | ||
} | ||
|
||
/// Static data stored in the database. | ||
/// Expected to be unmutable and set only once. | ||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Encode, Decode)] | ||
pub struct StaticData { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use LatestData |
||
pub gear_exe_timelines: Option<GearExeTimelines>, | ||
// Maybe add more static fields in the future. | ||
} | ||
|
||
#[auto_impl::auto_impl(&, Box)] | ||
pub trait BlockMetaStorageRead { | ||
/// NOTE: if `BlockMeta` doesn't exist in the database, it will return the default value. | ||
|
@@ -111,18 +118,22 @@ pub trait CodesStorageWrite { | |
|
||
#[auto_impl::auto_impl(&, Box)] | ||
pub trait OnChainStorageRead { | ||
fn gear_exe_timelines(&self) -> Option<GearExeTimelines>; | ||
|
||
fn block_header(&self, block_hash: H256) -> Option<BlockHeader>; | ||
fn block_events(&self, block_hash: H256) -> Option<Vec<BlockEvent>>; | ||
fn code_blob_info(&self, code_id: CodeId) -> Option<CodeBlobInfo>; | ||
fn latest_synced_block_height(&self) -> Option<u32>; | ||
fn validators(&self, block_hash: H256) -> Option<NonEmpty<Address>>; | ||
fn validators_info(&self, block_hash: H256) -> Option<ValidatorsInfo>; | ||
} | ||
|
||
#[auto_impl::auto_impl(&)] | ||
pub trait OnChainStorageWrite { | ||
fn set_gear_exe_timelines(&self, timelines: GearExeTimelines); | ||
|
||
fn set_block_header(&self, block_hash: H256, header: BlockHeader); | ||
fn set_block_events(&self, block_hash: H256, events: &[BlockEvent]); | ||
fn set_code_blob_info(&self, code_id: CodeId, code_info: CodeBlobInfo); | ||
fn set_latest_synced_block_height(&self, height: u32); | ||
fn set_validators(&self, block_hash: H256, validator_set: NonEmpty<Address>); | ||
fn set_validators_info(&self, block_hash: H256, validators_info: ValidatorsInfo); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,7 @@ | |
// You should have received a copy of the GNU General Public License | ||
// along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
|
||
use crate::{Digest, ToDigest, events::BlockEvent}; | ||
use crate::{Digest, ToDigest, ValidatorsVec, events::BlockEvent}; | ||
use alloc::{ | ||
collections::{btree_map::BTreeMap, btree_set::BTreeSet}, | ||
vec::Vec, | ||
|
@@ -167,6 +167,46 @@ impl CodeAndId { | |
} | ||
} | ||
|
||
/// [`NextEraValidators`] represents the all possible states of the next era validators. | ||
/// The majority of the era time, the next era validators are not known yet. | ||
/// The state switches to [`NextEraValidators::Elected`] at the election checkpoint by calling `makeElectionAt` in the middleware. | ||
/// After the commitment is included in a block, the state switches to [`NextEraValidators::Committed`]. | ||
#[derive(Debug, Clone, Default, PartialEq, Eq, Encode, Decode)] | ||
pub enum NextEraValidators { | ||
|
||
/// Validators are not known yet. | ||
#[default] | ||
Unknown, | ||
/// Validators are elected, but not yet committed. | ||
Elected(ValidatorsVec), | ||
// Committed in the Router. | ||
Committed(ValidatorsVec), | ||
} | ||
|
||
/// [`ValidatorsInfo`] stores the current and state of next set of validators. | ||
/// The next set of validators will be applied at the beginning of the next era. | ||
/// | ||
/// NOTE: [`Default`] implementation creates a non-empty set with a single zero address. | ||
/// DO NOT use default in production code, it is only for tests purposes. | ||
#[derive(Debug, Clone, Default, PartialEq, Eq, Encode, Decode)] | ||
pub struct ValidatorsInfo { | ||
pub current: ValidatorsVec, | ||
pub next: NextEraValidators, | ||
} | ||
|
||
/// GearExe network timelines configuration. Parameters fetched the Router contract. | ||
/// This struct stores in the database, because of using in the multiple places. | ||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Encode, Decode)] | ||
pub struct GearExeTimelines { | ||
// The genesis timestamp of the GearExe network. | ||
pub genesis_ts: u64, | ||
// The duration of an era in seconds. | ||
pub era: u64, | ||
// The election duration in seconds before the end of an era when the next set of validators elected. | ||
/// (start of era)[ - - - - - - - - - - - + - - - - ] (end of era) | ||
/// ^ election | ||
pub election: u64, | ||
} | ||
|
||
/// RemoveFromMailbox key; (msgs sources program (mailbox and queue provider), destination user id) | ||
pub type Rfm = (ActorId, ActorId); | ||
|
||
|
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.
\n