提交 086ed3b9 编写于 作者: P Philip Hayes 提交者: bors-libra

[types] Extract genesis definitions from executor to types

+ Rename and gate previous `::genesis` functions to `::mock_genesis`
to reflect their actual use as test data generators.

+ Now `BlockInfo::genesis`, `LedgerInfo::genesis`, and
`LedgerInfoWithSigs::genesis` are the "real" way to create genesis
types.

+ Add an assertion that genesis transaction always outputs a
validator_set; i.e., genesis is always an epoch change.

+ Gate `BlockInfo::random` behind test flags.

+ Update usages in various tests.

Closes: #2621
Approved by: dmitri-perelman
上级 599ec5fe
......@@ -142,7 +142,7 @@ where
{
#[cfg(any(test, feature = "fuzzing"))]
pub fn make_genesis_block() -> Self {
Self::make_genesis_block_from_ledger_info(&LedgerInfo::genesis())
Self::make_genesis_block_from_ledger_info(&LedgerInfo::mock_genesis())
}
/// Construct new genesis block for next epoch deterministically from the end-epoch LedgerInfo
......
......@@ -221,7 +221,7 @@ pub fn placeholder_certificate_for_block(
certified_parent_block_round: u64,
) -> QuorumCert {
// Assuming executed state to be Genesis state.
let genesis_ledger_info = LedgerInfo::genesis();
let genesis_ledger_info = LedgerInfo::mock_genesis();
let vote_data = VoteData::new(
BlockInfo::new(
genesis_ledger_info.epoch() + 1,
......@@ -264,7 +264,7 @@ pub fn placeholder_certificate_for_block(
}
pub fn certificate_for_genesis() -> QuorumCert {
let ledger_info = LedgerInfo::genesis();
let ledger_info = LedgerInfo::mock_genesis();
QuorumCert::certificate_for_genesis_from_ledger_info(
&ledger_info,
Block::<Vec<usize>>::make_genesis_block_from_ledger_info(&ledger_info).id(),
......
......@@ -55,7 +55,7 @@ impl<T: Payload> MockStorage<T> {
pub fn new(shared_storage: Arc<MockSharedStorage<T>>) -> Self {
MockStorage {
shared_storage,
storage_ledger: Mutex::new(LedgerInfo::genesis()),
storage_ledger: Mutex::new(LedgerInfo::mock_genesis()),
}
}
......@@ -248,7 +248,7 @@ impl<T: Payload> PersistentLivenessStorage<T> for EmptyStorage {
}
async fn recover_from_ledger(&self) -> LedgerRecoveryData<T> {
LedgerRecoveryData::new(LedgerInfo::genesis(), ValidatorSet::new(vec![]))
LedgerRecoveryData::new(LedgerInfo::mock_genesis(), ValidatorSet::new(vec![]))
}
async fn start(&self) -> LivenessStorageData<T> {
......@@ -257,7 +257,7 @@ impl<T: Payload> PersistentLivenessStorage<T> for EmptyStorage {
self.recover_from_ledger().await,
vec![],
vec![],
&LedgerInfo::genesis(),
&LedgerInfo::mock_genesis(),
ExecutedTrees::new_empty(),
None,
) {
......
......@@ -17,7 +17,7 @@ use libra_config::config::{NodeConfig, VMConfig};
use libra_crypto::{
hash::{
CryptoHash, EventAccumulatorHasher, TransactionAccumulatorHasher,
ACCUMULATOR_PLACEHOLDER_HASH, PRE_GENESIS_BLOCK_ID, SPARSE_MERKLE_PLACEHOLDER_HASH,
ACCUMULATOR_PLACEHOLDER_HASH, SPARSE_MERKLE_PLACEHOLDER_HASH,
},
HashValue,
};
......@@ -26,11 +26,10 @@ use libra_types::{
account_address::AccountAddress,
account_state::AccountState,
account_state_blob::AccountStateBlob,
block_info::{BlockInfo, Round},
block_info::Round,
contract_event::ContractEvent,
crypto_proxies::LedgerInfoWithSignatures,
crypto_proxies::ValidatorSet,
ledger_info::LedgerInfo,
proof::{accumulator::InMemoryAccumulator, definition::LeafCount, SparseMerkleProof},
transaction::{
Transaction, TransactionInfo, TransactionListWithProof, TransactionOutput,
......@@ -42,7 +41,7 @@ use once_cell::sync::Lazy;
use scratchpad::{ProofRead, SparseMerkleTree};
use serde::{Deserialize, Serialize};
use std::{
collections::{hash_map, BTreeMap, HashMap, HashSet},
collections::{hash_map, HashMap, HashSet},
convert::TryFrom,
marker::PhantomData,
sync::Arc,
......@@ -360,21 +359,14 @@ where
.execute_block(genesis_txns.clone(), &pre_genesis_trees, &pre_genesis_trees)
.expect("Failed to execute genesis block.");
let validator_set = output
.validators()
.clone()
.expect("Genesis transaction must emit a validator set.");
let root_hash = output.accu_root();
let ledger_info = LedgerInfo::new(
BlockInfo::new(
GENESIS_EPOCH,
GENESIS_ROUND,
*PRE_GENESIS_BLOCK_ID,
root_hash,
0,
0,
output.validators().clone(),
),
HashValue::zero(),
);
let ledger_info_with_sigs =
LedgerInfoWithSignatures::new(ledger_info, /* signatures = */ BTreeMap::new());
let ledger_info_with_sigs = LedgerInfoWithSignatures::genesis(root_hash, validator_set);
self.commit_blocks(
vec![(genesis_txns, Arc::new(output))],
ledger_info_with_sigs,
......
......@@ -12,20 +12,18 @@ use futures::executor::block_on;
use libra_config::config::RoleType;
use libra_crypto::{
ed25519::*,
hash::ACCUMULATOR_PLACEHOLDER_HASH,
test_utils::TEST_SEED,
x25519,
x25519::{X25519StaticPrivateKey, X25519StaticPublicKey},
HashValue,
};
use libra_logger::set_simple_logger;
use libra_mempool::mocks::MockSharedMempool;
use libra_types::{
block_info::BlockInfo,
crypto_proxies::{
random_validator_verifier, LedgerInfoWithSignatures, ValidatorChangeProof,
ValidatorPublicKeys, ValidatorSet, ValidatorSigner,
},
ledger_info::LedgerInfo,
proof::TransactionListProof,
transaction::TransactionListWithProof,
waypoint::Waypoint,
......@@ -40,7 +38,7 @@ use network::{
use parity_multiaddr::Multiaddr;
use rand::{rngs::StdRng, SeedableRng};
use std::{
collections::{BTreeMap, HashMap},
collections::HashMap,
sync::{
atomic::{AtomicUsize, Ordering},
Arc, RwLock,
......@@ -203,20 +201,9 @@ impl SynchronizerEnv {
}
fn genesis_li(validators: &[ValidatorPublicKeys]) -> LedgerInfoWithSignatures {
LedgerInfoWithSignatures::new(
LedgerInfo::new(
BlockInfo::new(
0,
0,
HashValue::zero(),
HashValue::zero(),
0,
0,
Some(ValidatorSet::new(validators.to_owned())),
),
HashValue::zero(),
),
BTreeMap::new(),
LedgerInfoWithSignatures::genesis(
*ACCUMULATOR_PLACEHOLDER_HASH,
ValidatorSet::new(validators.to_vec()),
)
}
......
......@@ -3,7 +3,7 @@
use cli::client_proxy::ClientProxy;
use libra_config::config::{NodeConfig, RoleType, VMPublishingOption};
use libra_crypto::{ed25519::*, hash::CryptoHash, test_utils::KeyPair, HashValue, SigningKey};
use libra_crypto::{ed25519::*, hash::CryptoHash, test_utils::KeyPair, SigningKey};
use libra_logger::prelude::*;
use libra_swarm::swarm::LibraNode;
use libra_swarm::swarm::LibraSwarm;
......@@ -11,7 +11,6 @@ use libra_temppath::TempPath;
use libra_types::{
account_address::AccountAddress,
account_config::association_address,
block_info::BlockInfo,
ledger_info::LedgerInfo,
transaction::{TransactionArgument, TransactionPayload},
waypoint::Waypoint,
......@@ -934,7 +933,7 @@ fn test_client_waypoints() {
);
// Verify that a client with the wrong waypoint is not going to be able to connect to the chain.
let bad_li = LedgerInfo::new(BlockInfo::genesis(), HashValue::zero());
let bad_li = LedgerInfo::mock_genesis();
let bad_waypoint = Waypoint::new(&bad_li).unwrap();
let mut client_with_bad_waypoint = env.get_validator_ac_client(1, Some(bad_waypoint));
assert!(client_with_bad_waypoint
......
......@@ -2,9 +2,9 @@
// SPDX-License-Identifier: Apache-2.0
use crate::{crypto_proxies::ValidatorSet, transaction::Version};
use libra_crypto::hash::HashValue;
#[cfg(any(test, feature = "fuzzing"))]
use libra_crypto::hash::ACCUMULATOR_PLACEHOLDER_HASH;
use libra_crypto::hash::{HashValue, PRE_GENESIS_BLOCK_ID};
#[cfg(any(test, feature = "fuzzing"))]
use proptest_derive::Arbitrary;
use serde::{Deserialize, Serialize};
......@@ -14,6 +14,12 @@ use std::fmt::{Display, Formatter};
/// monotonically.
pub type Round = u64;
// Constants for the initial genesis block.
pub const GENESIS_EPOCH: u64 = 0;
pub const GENESIS_ROUND: Round = 0;
pub const GENESIS_VERSION: Version = 0;
pub const GENESIS_TIMESTAMP_USECS: u64 = 0;
/// This structure contains all the information needed for tracking a block
/// without having access to the block or its execution output state. It
/// assumes that the block is the last block executed within the ledger.
......@@ -69,6 +75,7 @@ impl BlockInfo {
}
}
#[cfg(any(test, feature = "fuzzing"))]
pub fn random(round: Round) -> Self {
Self {
epoch: 1,
......@@ -81,19 +88,36 @@ impl BlockInfo {
}
}
#[cfg(any(test, feature = "fuzzing"))]
pub fn genesis() -> Self {
/// Create a new genesis block. The genesis block is effectively the
/// blockchain state after executing the initial genesis transaction.
///
/// * `genesis_state_root_hash` - the state tree root hash after executing the
/// initial genesis transaction.
///
/// * `validator_set` - the initial validator set, configured when generating
/// the genesis transaction itself and emitted after executing the genesis
/// transaction. Using this genesis block means transitioning to a new epoch
/// (GENESIS_EPOCH + 1) with this `validator_set`.
pub fn genesis(genesis_state_root_hash: HashValue, validator_set: ValidatorSet) -> Self {
Self {
epoch: 0,
round: 0,
id: HashValue::zero(),
executed_state_id: *ACCUMULATOR_PLACEHOLDER_HASH,
version: 0,
timestamp_usecs: 0,
next_validator_set: Some(ValidatorSet::new(vec![])),
epoch: GENESIS_EPOCH,
round: GENESIS_ROUND,
// We use `PRE_GENESIS_BLOCK_ID` as the parent of the genesis block.
id: *PRE_GENESIS_BLOCK_ID,
executed_state_id: genesis_state_root_hash,
version: GENESIS_VERSION,
timestamp_usecs: GENESIS_TIMESTAMP_USECS,
next_validator_set: Some(validator_set),
}
}
/// Create a mock genesis `BlockInfo` with an empty state tree and empty
/// validator set.
#[cfg(any(test, feature = "fuzzing"))]
pub fn mock_genesis() -> Self {
Self::genesis(*ACCUMULATOR_PLACEHOLDER_HASH, ValidatorSet::empty())
}
pub fn epoch(&self) -> u64 {
self.epoch
}
......
......@@ -65,6 +65,20 @@ impl LedgerInfo {
}
}
/// Create a new LedgerInfo at genesis with the given genesis state and
/// initial validator set.
pub fn genesis(genesis_state_root_hash: HashValue, validator_set: ValidatorSet) -> Self {
Self::new(
BlockInfo::genesis(genesis_state_root_hash, validator_set),
HashValue::zero(),
)
}
#[cfg(any(test, feature = "fuzzing"))]
pub fn mock_genesis() -> Self {
Self::new(BlockInfo::mock_genesis(), HashValue::zero())
}
/// The `BlockInfo` of a committed block.
pub fn commit_info(&self) -> &BlockInfo {
&self.commit_info
......@@ -108,12 +122,6 @@ impl LedgerInfo {
pub fn set_consensus_data_hash(&mut self, consensus_data_hash: HashValue) {
self.consensus_data_hash = consensus_data_hash;
}
/// To bootstrap the system until we execute and commit the genesis txn before start.
#[cfg(any(test, feature = "fuzzing"))]
pub fn genesis() -> Self {
Self::new(BlockInfo::genesis(), HashValue::zero())
}
}
impl TryFrom<crate::proto::types::LedgerInfo> for LedgerInfo {
......@@ -201,6 +209,20 @@ impl<Sig: Signature> LedgerInfoWithSignatures<Sig> {
}
}
/// Create a new `LedgerInfoWithSignatures` at genesis with the given genesis
/// state and initial validator set.
///
/// Note that the genesis `LedgerInfoWithSignatures` is unsigned. Validators
/// and FullNodes are configured with the same genesis transaction and generate
/// an identical genesis `LedgerInfoWithSignatures` independently. In contrast,
/// Clients will likely use a waypoint generated from the genesis `LedgerInfo`.
pub fn genesis(genesis_state_root_hash: HashValue, validator_set: ValidatorSet) -> Self {
Self::new(
LedgerInfo::genesis(genesis_state_root_hash, validator_set),
BTreeMap::new(),
)
}
pub fn ledger_info(&self) -> &LedgerInfo {
&self.ledger_info
}
......
......@@ -69,6 +69,10 @@ impl<PublicKey: VerifyingKey> ValidatorSet<PublicKey> {
ValidatorSet(payload)
}
pub fn empty() -> Self {
ValidatorSet::new(Vec::new())
}
pub fn change_event_key() -> EventKey {
EventKey::new_from_address(&account_config::validator_set_address(), 2)
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册