Skip to content
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
63 changes: 63 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ members = [
"keyless/pepper/example-client-rust",
"keyless/pepper/service",
"mempool",
"movement-migration/validation-tool",
"network/benchmark",
"network/builder",
"network/discovery",
Expand Down Expand Up @@ -252,6 +253,7 @@ members = [
"third_party/move/tools/move-unit-test",
"tools/calc-dep-sizes",
"tools/compute-module-expansion-size",
"tools/l1-migration",
"types",
"vm-validator",
]
Expand Down Expand Up @@ -827,6 +829,7 @@ which = "4.2.5"
whoami = "1.5.0"
# This allows for zeroize 1.6 to be used. Version 1.2.0 of x25519-dalek locks zeroize to 1.3.
x25519-dalek = { git = "https://github.com/aptos-labs/x25519-dalek", rev = "b9cdbaf36bf2a83438d9f660e5a708c82ed60d8e" }
xz2 = "0.1"
z3tracer = "0.8.0"

# MOVE DEPENDENCIES
Expand Down
6 changes: 5 additions & 1 deletion consensus/consensus-types/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,11 @@ impl Block {
/// Construct new genesis block for next epoch deterministically from the end-epoch LedgerInfo
/// We carry over most fields except round and block id
pub fn make_genesis_block_from_ledger_info(ledger_info: &LedgerInfo) -> Self {
let block_data = BlockData::new_genesis_from_ledger_info(ledger_info);
let block_data = if ledger_info.ends_epoch() {
BlockData::new_genesis_from_ledger_info(ledger_info)
} else {
BlockData::make_genesis_block_from_any_ledger_info(ledger_info)
};
Block {
id: block_data.hash(),
block_data,
Expand Down
31 changes: 30 additions & 1 deletion consensus/consensus-types/src/block_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,22 @@ impl BlockData {
}
}

pub fn make_genesis_block_from_any_ledger_info(ledger_info: &LedgerInfo) -> Self {
let ancestor = ledger_info.commit_info().to_owned();

// Genesis carries a placeholder quorum certificate to its parent id with LedgerInfo
// carrying information about version from the last LedgerInfo of previous epoch.
let genesis_quorum_cert = QuorumCert::new(
VoteData::new(ancestor.clone(), ancestor.clone()),
LedgerInfoWithSignatures::new(
LedgerInfo::new(ancestor, HashValue::zero()),
AggregateSignature::empty(),
),
);

BlockData::new_starting_block(ledger_info.timestamp_usecs(), genesis_quorum_cert)
}

pub fn new_genesis_from_ledger_info(ledger_info: &LedgerInfo) -> Self {
assert!(ledger_info.ends_epoch());
let ancestor = BlockInfo::new(
Expand Down Expand Up @@ -246,9 +262,22 @@ impl BlockData {

#[allow(unexpected_cfgs)]
pub fn new_genesis(timestamp_usecs: u64, quorum_cert: QuorumCert) -> Self {
assume!(quorum_cert.certified_block().epoch() < u64::MAX); // unlikely to be false in this universe
let genesis_epoch = quorum_cert.certified_block().epoch() + 1;
Self {
epoch: genesis_epoch,
round: 0,
timestamp_usecs,
quorum_cert,
block_type: BlockType::Genesis,
}
}

#[allow(unexpected_cfgs)]
pub fn new_starting_block(timestamp_usecs: u64, quorum_cert: QuorumCert) -> Self {
assume!(quorum_cert.certified_block().epoch() < u64::MAX); // unlikely to be false in this universe
Self {
epoch: quorum_cert.certified_block().epoch() + 1,
epoch: quorum_cert.certified_block().epoch(),
round: 0,
timestamp_usecs,
quorum_cert,
Expand Down
9 changes: 5 additions & 4 deletions consensus/consensus-types/src/pipelined_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,10 +571,11 @@ impl PipelinedBlock {
}

pub async fn wait_for_compute_result(&self) -> ExecutorResult<(StateComputeResult, Duration)> {
self.pipeline_futs()
.ok_or(ExecutorError::InternalError {
error: "Pipeline aborted".to_string(),
})?
let pipeline_futs = self.pipeline_futs().ok_or(ExecutorError::InternalError {
error: "Pipeline aborted".to_string(),
})?;

pipeline_futs
.ledger_update_fut
.await
.map(|(compute_result, execution_time, _)| (compute_result, execution_time))
Expand Down
44 changes: 32 additions & 12 deletions consensus/consensus-types/src/quorum_cert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,31 +82,51 @@ impl QuorumCert {
/// - the accumulator root hash of the LedgerInfo is set to the last executed state of previous
/// epoch.
/// - the map of signatures is empty because genesis block is implicitly agreed.
// TODO(l1-migration): This is for recovery when we lost consensu DB data
// We create this virual block and don't want to add 1 since it is not epoch_ending block

pub fn certificate_for_genesis_from_ledger_info(
ledger_info: &LedgerInfo,
genesis_id: HashValue,
) -> QuorumCert {
let ancestor = BlockInfo::new(
let ancestor_epoch = if ledger_info.ends_epoch() {
ledger_info
.epoch()
.checked_add(1)
.expect("Integer overflow when creating cert for genesis from ledger info"),
0,
genesis_id,
ledger_info.transaction_accumulator_hash(),
ledger_info.version(),
ledger_info.timestamp_usecs(),
None,
);
.expect("Integer overflow when creating cert for genesis from ledger info")
} else {
ledger_info.epoch()
};

let ancestor = if ledger_info.ends_epoch() {
BlockInfo::new(
ancestor_epoch,
0,
genesis_id,
ledger_info.transaction_accumulator_hash(),
ledger_info.version(),
ledger_info.timestamp_usecs(),
None,
)
} else {
BlockInfo::new(
ancestor_epoch,
0,
genesis_id,
ledger_info.transaction_accumulator_hash(),
ledger_info.version(),
ledger_info.timestamp_usecs(),
None,
)
};

let vote_data = VoteData::new(ancestor.clone(), ancestor.clone());
let li = LedgerInfo::new(ancestor, vote_data.hash());

let validator_set_size = ledger_info
.next_epoch_state()
.expect("Next epoch state not found in ledger info")
.verifier
.len();
.map(|epoch_state| epoch_state.verifier.len())
.unwrap_or(1);

QuorumCert::new(
vote_data,
Expand Down
2 changes: 2 additions & 0 deletions consensus/safety-rules/src/safety_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ impl SafetyRules {
let mut updated = false;
let one_chain = qc.certified_block().round();
let two_chain = qc.parent_block().round();

if one_chain > safety_data.one_chain_round {
safety_data.one_chain_round = one_chain;
trace!(
Expand Down Expand Up @@ -260,6 +261,7 @@ impl SafetyRules {
let last_li = proof
.verify(&waypoint)
.map_err(|e| Error::InvalidEpochChangeProof(format!("{}", e)))?;

let ledger_info = last_li.ledger_info();
let epoch_state = ledger_info
.next_epoch_state()
Expand Down
3 changes: 3 additions & 0 deletions consensus/src/block_storage/block_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,9 @@ impl BlockStore {
let block_to_commit = self
.get_block(block_id_to_commit)
.ok_or_else(|| format_err!("Committed block id not found"))?;
if block_to_commit.block().is_genesis_block() && block_to_commit.round() == 0 {
return Ok(());
}

// First make sure that this commit is new.
ensure!(
Expand Down
11 changes: 6 additions & 5 deletions consensus/src/consensus_observer/observer/consensus_observer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1077,16 +1077,17 @@ impl ConsensusObserver {
.start_epoch(
sk,
epoch_state.clone(),
dummy_signer.clone(),
dummy_signer,
payload_manager,
&consensus_config,
&execution_config,
&randomness_config,
None,
None,
None, // rand_config
None, // fast_rand_config
rand_msg_rx,
0,
self.pipeline_enabled(),
0, // highest_committed_round
self.observer_epoch_state.pipeline_enabled(),
None, // Consensus observer doesn't use virtual genesis
)
.await;
if self.pipeline_enabled() {
Expand Down
10 changes: 10 additions & 0 deletions consensus/src/epoch_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,13 @@ impl<P: OnChainConfigProvider> EpochManager<P> {

let safety_rules_container = Arc::new(Mutex::new(safety_rules));

// Extract virtual genesis block ID if consensus created one
let virtual_genesis_block_id = if recovery_data.commit_root_block().is_genesis_block() {
Some(recovery_data.commit_root_block().id())
} else {
None
};

self.execution_client
.start_epoch(
consensus_key.clone(),
Expand All @@ -858,6 +865,7 @@ impl<P: OnChainConfigProvider> EpochManager<P> {
rand_msg_rx,
recovery_data.commit_root_block().round(),
self.config.enable_pipeline,
virtual_genesis_block_id,
)
.await;
let consensus_sk = consensus_key;
Expand Down Expand Up @@ -1422,6 +1430,7 @@ impl<P: OnChainConfigProvider> EpochManager<P> {
rand_msg_rx,
highest_committed_round,
self.config.enable_pipeline,
None, // DAG doesn't use virtual genesis
)
.await;

Expand Down Expand Up @@ -1476,6 +1485,7 @@ impl<P: OnChainConfigProvider> EpochManager<P> {
tokio::spawn(bootstrapper.start(dag_rpc_rx, dag_shutdown_rx));
}

//TODO(l1-migration) turn on quorum store
fn enable_quorum_store(&mut self, onchain_config: &OnChainConsensusConfig) -> bool {
fail_point!("consensus::start_new_epoch::disable_qs", |_| false);
onchain_config.quorum_store_enabled()
Expand Down
1 change: 1 addition & 0 deletions consensus/src/execution_pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ impl ExecutionPipeline {
{
counters::APPLY_LEDGER_WAIT_TIME.observe_duration(command_creation_time.elapsed());
debug!("ledger_apply stage received block {}.", block_id);

let res = async {
let execution_duration = execution_time?;
let executor = executor.clone();
Expand Down
27 changes: 15 additions & 12 deletions consensus/src/liveness/leader_reputation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -665,18 +665,21 @@ impl LeaderReputation {

if chosen {
// do not treat chain as unhealthy, if chain just started, and we don't have enough history to decide.
let voting_power_participation_ratio: VotingPowerRatio =
if history.len() < *participants_window_size && self.epoch <= 2 {
1.0
} else if total_voting_power >= 1.0 {
participating_voting_power / total_voting_power
} else {
error!(
"Total voting power is {}, should never happen",
total_voting_power
);
1.0
};
// Also handle single validator case where participation should always be 1.0
let voting_power_participation_ratio: VotingPowerRatio = if history.len()
< *participants_window_size
&& (self.epoch <= 2 || candidates.len() == 1)
{
1.0
} else if total_voting_power >= 1.0 {
participating_voting_power / total_voting_power
} else {
error!(
"Total voting power is {}, should never happen",
total_voting_power
);
1.0
};
CHAIN_HEALTH_REPUTATION_PARTICIPATING_VOTING_POWER_FRACTION
.set(voting_power_participation_ratio);
result = Some(voting_power_participation_ratio);
Expand Down
Loading
Loading