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

refactor: prepare shard update impl for stateless validation #10187

Merged
merged 17 commits into from
Nov 20, 2023

Conversation

Longarithm
Copy link
Member

@Longarithm Longarithm commented Nov 16, 2023

This is just a refactor, which shouldn't change any behaviour of the code but prepares it for stateless validation.

We came up with idea that logic contained in get_apply_chunk_job_* method should not depend on Chain that heavily. Here I extract all logic where Chain is required to get_apply_chunk_job only. All remaining logic is moved to update_shard.rs. For better readability, I introduce more updates:

  • "apply_chunk" is mostly replaced with "update_shard" because it is closer to what actually happens. When new chunk exists, we indeed apply it. But in two other cases listed in ShardUpdateReason enum we only update validator accounts or process split state info.
  • excessive info about blocks and chunks is replaced with exact BlockContext and ShardUpdateReason contents which are specific for all shard updates. Now it should be much more clear which data is necessary. Note that receipts are passed only when new chunk appears.

chain.rs size is reduced by 250 lines which is good I think.

In the follow-up PRs you can see more refactoring (but less invasive) and introducing of "shadow" jobs for stateless validation on nightly, which will in fact call apply_old_chunk N times and then apply_new_chunk 1 time. It was impossible to do using previous API.

Nayduck https://nayduck.near.org/#/run/3276

@Longarithm Longarithm requested a review from a team as a code owner November 16, 2023 11:38
Copy link
Contributor

@pugachAG pugachAG left a comment

Choose a reason for hiding this comment

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

overall looks very good, added a couple of suggestions!

prev_block_header: &BlockHeader,
chunk: &ShardChunk,
) -> Result<(), Error> {
let protocol_version =
Copy link
Contributor

Choose a reason for hiding this comment

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

please change the order of those ifs to have validate_transactions_order first in order to preserve the behaviour of the original code to avoid accidental protocol change:

Copy link
Member Author

Choose a reason for hiding this comment

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

I think that's not a protocol change - if there is an error, block with chunk is not saved on chain. But I swapped order by accident anyway

/// - queries to epoch manager
/// - allowing contracts to get current chain data
#[derive(Clone, Debug)]
pub struct BlockContext {
Copy link
Contributor

Choose a reason for hiding this comment

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

let's make all structs s here pub(crate) instead of pub


#[derive(Debug)]
pub struct SameHeightResult {
pub(crate) shard_uid: ShardUId,
Copy link
Contributor

Choose a reason for hiding this comment

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

I guest we can just make it pub if SameHeightResult is pub(crate)

Copy link
Member Author

Choose a reason for hiding this comment

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

pub(crate) worked for Context-s, but didn't work for ApplyChunkResult. It is actually leaked to other crates in BlockCatchUpRequest
It doesn't look right, but it is outside of scope of the PR I think

}

/// Reason to update a shard when new block appears on chain.
pub enum ShardUpdateReason {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I suggest just calling it ShardUpdate

Copy link
Member Author

Choose a reason for hiding this comment

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

Discussed offline. Can choose ShardUpdateMode and rename ApplyChunksMode in chain.rs later

chain/chain/src/update_shard.rs Outdated Show resolved Hide resolved
chain/chain/src/update_shard.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@wacban wacban left a comment

Choose a reason for hiding this comment

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

This looks much cleaner, thanks!

chain/chain/src/chain.rs Outdated Show resolved Hide resolved
chain/chain/src/chain.rs Show resolved Hide resolved
Comment on lines +3539 to +3547
// Before `FixApplyChunks` feature, gas price was taken from current
// block by mistake. Preserve it for backwards compatibility.
let gas_price = if !is_new_chunk
&& protocol_version < ProtocolFeature::FixApplyChunks.protocol_version()
{
block_header.next_gas_price()
} else {
prev_block_header.next_gas_price()
};
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Can you move it to a helper method?

Copy link
Member Author

Choose a reason for hiding this comment

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

Move what exactly? :) The logic for getting gas price is very simple, the whole method is quite small.

chain/chain/src/chain.rs Outdated Show resolved Hide resolved
chain/chain/src/update_shard.rs Outdated Show resolved Hide resolved
chain/chain/src/update_shard.rs Outdated Show resolved Hide resolved
chain/chain/src/update_shard.rs Show resolved Hide resolved
shard_info.shard_uid,
runtime,
epoch_manager,
split_state_roots.unwrap(),
Copy link
Contributor

Choose a reason for hiding this comment

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

I suppose this is safe dynamically but it still looks a bit scary. Can you make the split_state_roots part of the reason where it can be already checked to be not none and typed as such?

Copy link
Member Author

Choose a reason for hiding this comment

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

It makes Reason struct more ugly... But that's fine for now

Copy link
Contributor

@robin-near robin-near left a comment

Choose a reason for hiding this comment

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

Very nice! I love this change, it's so much more readable and it's awesome that we explicitly pass empty receipts and transactions when they aren't actually used.

Copy link
Contributor

@pugachAG pugachAG left a comment

Choose a reason for hiding this comment

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

Everything looks great, thanks!

@Longarithm Longarithm added this pull request to the merge queue Nov 20, 2023
Merged via the queue into near:master with commit 88c3efc Nov 20, 2023
@Longarithm Longarithm deleted the update-shard branch November 20, 2023 09:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants