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

Validator epochs/ZIP25 #1298

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions z2/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use std::{
use alloy::primitives::{address, Address};
use anyhow::{anyhow, Context, Result};
use k256::ecdsa::SigningKey;
use libp2p::PeerId;
use serde::{Deserialize, Serialize};
use serde_yaml;
use tokio::fs;
Expand All @@ -22,8 +21,8 @@ use zilliqa::{
local_address_default, max_blocks_in_flight_default,
minimum_time_left_for_empty_block_default, scilla_address_default, scilla_lib_dir_default,
state_rpc_limit_default, total_native_token_supply_default, Amount, ConsensusConfig,
GenesisDeposit,
},
crypto::NodePublicKey,
transaction::EvmGas,
};

Expand Down Expand Up @@ -275,7 +274,7 @@ impl Setup {

pub async fn generate_config(&self) -> Result<()> {
// The genesis deposits.
let mut genesis_deposits: Vec<(NodePublicKey, PeerId, Amount, Address)> = Vec::new();
let mut genesis_deposits: Vec<GenesisDeposit> = Vec::new();
for (node, desc) in self.config.shape.nodes.iter() {
if desc.is_validator {
let data = self
Expand All @@ -285,12 +284,13 @@ impl Setup {
.ok_or(anyhow!("no node data for {node}"))?;
// Better have a genesis deposit.
let secret_key = SecretKey::from_hex(&data.secret_key)?;
genesis_deposits.push((
secret_key.node_public_key(),
secret_key.to_libp2p_keypair().public().to_peer_id(),
GENESIS_DEPOSIT.into(),
data.address,
))
genesis_deposits.push(GenesisDeposit {
public_key: secret_key.node_public_key(),
peer_id: secret_key.to_libp2p_keypair().public().to_peer_id(),
stake: GENESIS_DEPOSIT.into(),
reward_address: data.address,
control_address: data.address,
});
}
}

Expand Down
38 changes: 37 additions & 1 deletion zilliqa-macros/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use syn::{parse::Parser, ItemFn};
pub(crate) fn test_macro(args: TokenStream, item: TokenStream) -> TokenStream {
let mut restrict_concurrency = false;
let mut do_checkpoints = false;
let mut blocks_per_epoch = 10;

let parsed_args =
match syn::punctuated::Punctuated::<syn::Meta, syn::Token![,]>::parse_terminated
Expand Down Expand Up @@ -35,6 +36,41 @@ pub(crate) fn test_macro(args: TokenStream, item: TokenStream) -> TokenStream {
}
}
}
syn::Meta::NameValue(a) => {
let Some(name) = a.path.get_ident() else {
return token_stream_with_error(
args,
syn::Error::new_spanned(a.path, "Attribute parameter must be ident"),
);
};
match name.to_string().as_str() {
"blocks_per_epoch" => {
let syn::Expr::Lit(syn::ExprLit {
lit: syn::Lit::Int(val),
..
}) = a.value
else {
return token_stream_with_error(
args,
syn::Error::new_spanned(
a.value,
"Attribute parameter value must be an int",
),
);
};
match val.base10_parse::<u64>() {
Ok(val) => blocks_per_epoch = val,
Err(e) => return token_stream_with_error(args, e),
};
}
_ => {
return token_stream_with_error(
args,
syn::Error::new_spanned(a, "Unknown attribute"),
)
}
}
}
// Can match syn::Meta::Namevalue(a) here for args with params, e.g. to set node_count
// in the future
other => {
Expand Down Expand Up @@ -197,7 +233,7 @@ pub(crate) fn test_macro(args: TokenStream, item: TokenStream) -> TokenStream {
async move {
let mut rng = <rand_chacha::ChaCha8Rng as rand_core::SeedableRng>::seed_from_u64(seed);
let network = crate::Network::new(std::sync::Arc::new(std::sync::Mutex::new(rng)), 4, seed, format!("http://{addr}"),
scilla_lib_dir.to_string(), #do_checkpoints);
scilla_lib_dir.to_string(), #do_checkpoints, #blocks_per_epoch);

// Call the original test function, wrapped in `catch_unwind` so we can detect the panic.
let result = futures::FutureExt::catch_unwind(std::panic::AssertUnwindSafe(
Expand Down
12 changes: 11 additions & 1 deletion zilliqa/src/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ pub struct ConsensusConfig {
/// The initially staked deposits in the deposit contract at genesis, composed of
/// (public key, peerId, amount, reward address) tuples.
#[serde(default)]
pub genesis_deposits: Vec<(NodePublicKey, PeerId, Amount, Address)>,
pub genesis_deposits: Vec<GenesisDeposit>,
/// Accounts that will be pre-funded at genesis.
#[serde(default)]
pub genesis_accounts: Vec<(Address, Amount)>,
Expand Down Expand Up @@ -248,6 +248,16 @@ pub struct ConsensusConfig {
pub total_native_token_supply: Amount,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct GenesisDeposit {
pub public_key: NodePublicKey,
pub peer_id: PeerId,
pub stake: Amount,
pub reward_address: Address,
pub control_address: Address,
}

pub fn consensus_timeout_default() -> Duration {
Duration::from_secs(5)
}
Expand Down
71 changes: 35 additions & 36 deletions zilliqa/src/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -970,7 +970,8 @@ impl Consensus {
);
return Ok(None);
}
let committee = self.state.get_stakers_at_block(&block)?;

let committee = self.state.get_stakers()?;

// verify the sender's signature on block_hash
let Some((index, _)) = committee
Expand Down Expand Up @@ -2016,42 +2017,40 @@ impl Consensus {
}
}

if self.block_is_first_in_epoch(block.number()) && !block.is_genesis() {
// TODO: handle epochs (#1140)

if self.config.do_checkpoints
&& self.epoch_is_checkpoint(self.epoch_number(block.number()))
{
if let Some(checkpoint_path) = self.db.get_checkpoint_dir()? {
let parent = self
.db
.get_block_by_hash(block.parent_hash())?
.ok_or(anyhow!(
"Trying to checkpoint block, but we don't have its parent"
if self.block_is_first_in_epoch(block.number())
&& !block.is_genesis()
&& self.config.do_checkpoints
&& self.epoch_is_checkpoint(self.epoch_number(block.number()))
{
if let Some(checkpoint_path) = self.db.get_checkpoint_dir()? {
let parent = self
.db
.get_block_by_hash(block.parent_hash())?
.ok_or(anyhow!(
"Trying to checkpoint block, but we don't have its parent"
))?;
let transactions: Vec<SignedTransaction> = block
.transactions
.iter()
.map(|txn_hash| {
let tx = self.db.get_transaction(txn_hash)?.ok_or(anyhow!(
"failed to fetch transaction {} for checkpoint parent {}",
txn_hash,
parent.hash()
))?;
let transactions: Vec<SignedTransaction> = block
.transactions
.iter()
.map(|txn_hash| {
let tx = self.db.get_transaction(txn_hash)?.ok_or(anyhow!(
"failed to fetch transaction {} for checkpoint parent {}",
txn_hash,
parent.hash()
))?;
Ok::<_, anyhow::Error>(tx)
})
.collect::<Result<Vec<SignedTransaction>>>()?;

self.message_sender.send_message_to_coordinator(
InternalMessage::ExportBlockCheckpoint(
Box::new(block),
transactions,
Box::new(parent),
self.db.state_trie()?.clone(),
checkpoint_path,
),
)?;
}
Ok::<_, anyhow::Error>(tx)
})
.collect::<Result<Vec<SignedTransaction>>>()?;

self.message_sender.send_message_to_coordinator(
InternalMessage::ExportBlockCheckpoint(
Box::new(block),
transactions,
Box::new(parent),
self.db.state_trie()?.clone(),
checkpoint_path,
),
)?;
}
}

Expand Down
Loading
Loading