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

ChainStateView::execute_block can now activate a chain. #2379

Merged
merged 1 commit into from
Aug 15, 2024
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
59 changes: 42 additions & 17 deletions linera-chain/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ where
}

/// Executes a block: first the incoming messages, then the main operation.
/// * Modifies the state of inboxes, outboxes, and channels, if needed.
/// * Modifies the state of outboxes and channels, if needed.
/// * As usual, in case of errors, `self` may not be consistent any more and should be thrown
/// away.
/// * Returns the list of messages caused by the block being executed.
Expand All @@ -693,6 +693,47 @@ where

let chain_id = self.chain_id();
assert_eq!(block.chain_id, chain_id);
// The first incoming message of any child chain must be `OpenChain`. A root chain must
// already be initialized
if block.height == BlockHeight::ZERO
&& self
.execution_state
.system
.description
.get()
.map_or(true, |description| description.is_child())
{
let Some(in_bundle) = block
.incoming_bundles
.first()
.filter(|in_bundle| in_bundle.action == MessageAction::Accept)
else {
return Err(ChainError::InactiveChain(chain_id));
};
let Some(posted_message) =
in_bundle.bundle.messages.first().filter(|pm| {
matches!(pm.message, Message::System(SystemMessage::OpenChain(_)))
})
else {
return Err(ChainError::InactiveChain(chain_id));
};

if !self.is_active() {
let message_id = MessageId {
chain_id: in_bundle.origin.sender,
height: in_bundle.bundle.height,
index: posted_message.index,
};
self.execute_init_message(
message_id,
&posted_message.message,
block.timestamp,
local_time,
)
.await?;
}
}

ensure!(
*self.execution_state.system.timestamp.get() <= block.timestamp,
ChainError::InvalidBlockTimestamp
Expand All @@ -713,22 +754,6 @@ where
ChainError::ClosedChain
);
}

// The first incoming message of any child chain must be `OpenChain`. A root chain must
// already be initialized
if block.height == BlockHeight::ZERO
&& self
.execution_state
.system
.description
.get()
.map_or(true, |description| description.is_child())
{
ensure!(
block.starts_with_open_chain(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this helper method still used after this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I'll remove it!

ChainError::InactiveChain(self.chain_id())
);
}
let app_permissions = self.execution_state.system.application_permissions.get();
let mut mandatory = HashSet::<UserApplicationId>::from_iter(
app_permissions.mandatory_applications.iter().cloned(),
Expand Down
13 changes: 1 addition & 12 deletions linera-chain/src/data_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use linera_base::{
};
use linera_execution::{
committee::{Committee, Epoch, ValidatorName},
BytecodeLocation, Message, MessageKind, Operation, SystemMessage, SystemOperation,
BytecodeLocation, Message, MessageKind, Operation, SystemOperation,
};
use serde::{de::Deserializer, Deserialize, Serialize};

Expand Down Expand Up @@ -96,17 +96,6 @@ impl Block {
.all(|message| message.action == MessageAction::Reject)
}

/// Returns whether `OpenChain` is the first message in this block.
pub fn starts_with_open_chain(&self) -> bool {
let Some(posted_message) = self.incoming_messages().next() else {
return false;
};
matches!(
posted_message.message,
Message::System(SystemMessage::OpenChain(_))
)
}

/// Returns an iterator over all incoming [`PostedMessage`]s in this block.
pub fn incoming_messages(&self) -> impl Iterator<Item = &PostedMessage> {
self.incoming_bundles
Expand Down
2 changes: 0 additions & 2 deletions linera-core/src/chain_worker/state/temporary_changes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,6 @@ where
&mut self,
block: Block,
) -> Result<(ExecutedBlock, ChainInfoResponse), WorkerError> {
self.0.ensure_is_active()?;

let local_time = self.0.storage.clock().current_time();
let signer = block.authenticated_signer;

Expand Down
Loading