Skip to content
Merged
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
5 changes: 5 additions & 0 deletions linera-execution/src/committee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,4 +380,9 @@ impl Committee {
pub fn policy(&self) -> &ResourceControlPolicy {
&self.policy
}

/// Returns a mutable reference to this committee's [`ResourceControlPolicy`].
pub fn policy_mut(&mut self) -> &mut ResourceControlPolicy {
&mut self.policy
}
}
7 changes: 5 additions & 2 deletions linera-sdk/src/test/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use linera_chain::{
types::{ConfirmedBlock, ConfirmedBlockCertificate},
};
use linera_execution::{
committee::Epoch,
system::{Recipient, SystemChannel, SystemOperation},
Operation,
};
Expand Down Expand Up @@ -48,6 +49,7 @@ impl BlockBuilder {
pub(crate) fn new(
chain_id: ChainId,
owner: Owner,
epoch: Epoch,
previous_block: Option<&ConfirmedBlockCertificate>,
validator: TestValidator,
) -> Self {
Expand All @@ -64,7 +66,7 @@ impl BlockBuilder {

BlockBuilder {
block: ProposedBlock {
epoch: 0.into(),
epoch,
chain_id,
incoming_bundles: vec![],
operations: vec![],
Expand Down Expand Up @@ -224,7 +226,8 @@ impl BlockBuilder {
Round::Fast,
self.validator.key_pair(),
);
let mut builder = SignatureAggregator::new(value, Round::Fast, self.validator.committee());
let committee = self.validator.committee().await;
let mut builder = SignatureAggregator::new(value, Round::Fast, &committee);
let certificate = builder
.append(vote.public_key, vote.signature)
.expect("Failed to sign block")
Expand Down
16 changes: 16 additions & 0 deletions linera-sdk/src/test/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use linera_base::{
use linera_chain::{types::ConfirmedBlockCertificate, ChainError, ChainExecutionContext};
use linera_core::{data_types::ChainInfoQuery, worker::WorkerError};
use linera_execution::{
committee::Epoch,
system::{
SystemExecutionError, SystemOperation, SystemQuery, SystemResponse,
CREATE_APPLICATION_MESSAGE_INDEX,
Expand Down Expand Up @@ -93,6 +94,20 @@ impl ActiveChain {
self.key_pair = key_pair
}

/// Returns the current [`Epoch`] the chain is in.
pub async fn epoch(&self) -> Epoch {
self.validator
.worker()
.chain_state_view(self.id())
.await
.expect("Failed to load chain")
.execution_state
.system
.epoch
.get()
.expect("Active chains should be in an epoch")
}

/// Reads the current shared balance available to all of the owners of this microchain.
pub async fn chain_balance(&self) -> Amount {
let query = Query::System(SystemQuery);
Expand Down Expand Up @@ -244,6 +259,7 @@ impl ActiveChain {
let mut block = BlockBuilder::new(
self.description.into(),
self.key_pair.public().into(),
self.epoch().await,
tip.as_ref(),
self.validator.clone(),
);
Expand Down
80 changes: 64 additions & 16 deletions linera-sdk/src/test/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
use std::{num::NonZeroUsize, sync::Arc};

use dashmap::DashMap;
use futures::FutureExt as _;
use futures::{
lock::{MappedMutexGuard, Mutex, MutexGuard},
FutureExt as _,
};
use linera_base::{
crypto::{AccountSecretKey, ValidatorKeypair, ValidatorSecretKey},
data_types::{Amount, ApplicationPermissions, Timestamp},
Expand All @@ -19,8 +22,10 @@ use linera_base::{
use linera_core::worker::WorkerState;
use linera_execution::{
committee::{Committee, Epoch},
system::{OpenChainConfig, SystemOperation, OPEN_CHAIN_MESSAGE_INDEX},
WasmRuntime,
system::{
AdminOperation, OpenChainConfig, SystemChannel, SystemOperation, OPEN_CHAIN_MESSAGE_INDEX,
},
ResourceControlPolicy, WasmRuntime,
};
use linera_storage::{DbStorage, Storage, TestClock};
use linera_views::memory::MemoryStore;
Expand All @@ -45,7 +50,7 @@ use crate::ContractAbi;
pub struct TestValidator {
validator_secret: ValidatorSecretKey,
account_secret: AccountSecretKey,
committee: Committee,
committee: Arc<Mutex<(Epoch, Committee)>>,
Comment thread
afck marked this conversation as resolved.
storage: DbStorage<MemoryStore, TestClock>,
worker: WorkerState<DbStorage<MemoryStore, TestClock>>,
clock: TestClock,
Expand All @@ -71,10 +76,13 @@ impl TestValidator {
pub async fn new() -> Self {
let validator_keypair = ValidatorKeypair::generate();
let account_secret = AccountSecretKey::generate();
let committee = Committee::make_simple(vec![(
validator_keypair.public_key,
account_secret.public(),
)]);
let committee = Arc::new(Mutex::new((
Epoch::ZERO,
Committee::make_simple(vec![(
validator_keypair.public_key,
account_secret.public(),
)]),
)));
let wasm_runtime = Some(WasmRuntime::default());
let storage = DbStorage::<MemoryStore, _>::make_test_storage(wasm_runtime)
.now_or_never()
Expand Down Expand Up @@ -166,11 +174,50 @@ impl TestValidator {
&self.validator_secret
}

/// Returns the committee that this test validator is part of.
/// Returns the latest committee that this test validator is part of.
///
/// The committee contains only this validator.
pub fn committee(&self) -> &Committee {
&self.committee
pub async fn committee(&self) -> MappedMutexGuard<'_, (Epoch, Committee), Committee> {
MutexGuard::map(self.committee.lock().await, |(_epoch, committee)| committee)
}

/// Updates the admin chain, creating a new epoch with an updated
/// [`ResourceControlPolicy`].
pub async fn change_resource_control_policy(
&self,
adjustment: impl FnOnce(&mut ResourceControlPolicy),
) {
let (epoch, committee) = {
let (ref mut epoch, ref mut committee) = &mut *self.committee.lock().await;

epoch
.try_add_assign_one()
.expect("Reached the limit of epochs");

adjustment(committee.policy_mut());

(*epoch, committee.clone())
};

let admin_chain = self.get_chain(&ChainId::root(0));

let certificate = admin_chain
.add_block(|block| {
block.with_system_operation(SystemOperation::Admin(
AdminOperation::CreateCommittee { epoch, committee },
));
})
.await;

for entry in self.chains.iter() {
let chain = entry.value();

chain
.add_block(|block| {
block.with_system_messages_from(&certificate, SystemChannel::Admin);
})
.await;
}
}

/// Creates a new microchain and returns the [`ActiveChain`] that can be used to add blocks to
Expand Down Expand Up @@ -199,13 +246,13 @@ impl TestValidator {
.get(&admin_id)
.expect("Admin chain should be created when the `TestValidator` is constructed");

let (epoch, committee) = self.committee.lock().await.clone();

let new_chain_config = OpenChainConfig {
ownership: ChainOwnership::single(owner),
committees: [(Epoch::ZERO, self.committee.clone())]
.into_iter()
.collect(),
committees: [(epoch, committee)].into_iter().collect(),
admin_id,
epoch: Epoch::ZERO,
epoch,
balance: Amount::ZERO,
application_permissions: ApplicationPermissions::default(),
};
Expand Down Expand Up @@ -233,11 +280,12 @@ impl TestValidator {
async fn create_admin_chain(&self) {
let key_pair = AccountSecretKey::generate();
let description = ChainDescription::Root(0);
let committee = self.committee.lock().await.1.clone();

self.worker()
.storage_client()
.create_chain(
self.committee.clone(),
committee,
ChainId::root(0),
description,
key_pair.public().into(),
Expand Down
Loading