From 192ccba88fb513956e0668b7783c69b8016f888b Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Fri, 16 Apr 2021 10:41:24 +0300 Subject: [PATCH 1/2] Fix loading the last block number in state keeper --- core/bin/zksync_core/src/state_keeper/mod.rs | 11 +++++++++++ core/lib/storage/sqlx-data.json | 18 ++++++++++++++++++ core/lib/storage/src/chain/block/mod.rs | 14 +++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/core/bin/zksync_core/src/state_keeper/mod.rs b/core/bin/zksync_core/src/state_keeper/mod.rs index ba024885a9..4b6f14dd66 100644 --- a/core/bin/zksync_core/src/state_keeper/mod.rs +++ b/core/bin/zksync_core/src/state_keeper/mod.rs @@ -289,6 +289,17 @@ impl ZkSyncStateInitParams { "restored root_hash is different" ); } + + // We have to load actual number of the last committed block, since above we load the block number from state, + // and in case of empty block being sealed (that may happen because of bug). + let last_actually_committed_block_number = storage + .chain() + .block_schema() + .get_last_saved_block() + .await?; + + let block_number = std::cmp::max(last_actually_committed_block_number, block_number); + Ok(block_number) } diff --git a/core/lib/storage/sqlx-data.json b/core/lib/storage/sqlx-data.json index 1761eb8589..b2b78fa306 100644 --- a/core/lib/storage/sqlx-data.json +++ b/core/lib/storage/sqlx-data.json @@ -3428,6 +3428,24 @@ ] } }, + "bf88992c521353535925401702028307ba3d79dfa2e60d939a117e7aae5a6403": { + "query": "SELECT MAX(number) FROM blocks", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "max", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null + ] + } + }, "c0bc09d944da0d6a2eb2108185c757ff16440ed9c3d1fb2835cf3d4f552078f2": { "query": "SELECT * FROM executed_priority_operations WHERE block_number = $1", "describe": { diff --git a/core/lib/storage/src/chain/block/mod.rs b/core/lib/storage/src/chain/block/mod.rs index d296a20656..5b8d95614b 100644 --- a/core/lib/storage/src/chain/block/mod.rs +++ b/core/lib/storage/src/chain/block/mod.rs @@ -491,7 +491,19 @@ impl<'a, 'c> BlockSchema<'a, 'c> { result } - /// Returns the number of last block + /// Returns the number of last block saved to the database. + pub async fn get_last_saved_block(&mut self) -> QueryResult { + let start = Instant::now(); + let count = sqlx::query!("SELECT MAX(number) FROM blocks") + .fetch_one(self.0.conn()) + .await? + .max + .unwrap_or(0); + metrics::histogram!("sql.chain.block.get_last_committed_block", start.elapsed()); + Ok(BlockNumber(count as u32)) + } + + /// Returns the number of last block for which an aggregated operation exists. pub async fn get_last_committed_block(&mut self) -> QueryResult { let start = Instant::now(); let result = OperationsSchema(self.0) From 1b149c50721e1e0b5941cf8328b50bf370a4c67b Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Fri, 16 Apr 2021 10:43:46 +0300 Subject: [PATCH 2/2] Move loading actual block number before checking the root hash --- core/bin/zksync_core/src/state_keeper/mod.rs | 23 +++++++++++--------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/core/bin/zksync_core/src/state_keeper/mod.rs b/core/bin/zksync_core/src/state_keeper/mod.rs index 4b6f14dd66..5572c2c54f 100644 --- a/core/bin/zksync_core/src/state_keeper/mod.rs +++ b/core/bin/zksync_core/src/state_keeper/mod.rs @@ -276,6 +276,19 @@ impl ZkSyncStateInitParams { } } } + + // We have to load actual number of the last committed block, since above we load the block number from state, + // and in case of empty block being sealed (that may happen because of bug). + // Note that if this block is greater than the `block_number`, it means that some empty blocks were committed, + // so the root hash has not changed and we don't need to update the tree in order to get the right root hash. + let last_actually_committed_block_number = storage + .chain() + .block_schema() + .get_last_saved_block() + .await?; + + let block_number = std::cmp::max(last_actually_committed_block_number, block_number); + if *block_number != 0 { let storage_root_hash = storage .chain() @@ -290,16 +303,6 @@ impl ZkSyncStateInitParams { ); } - // We have to load actual number of the last committed block, since above we load the block number from state, - // and in case of empty block being sealed (that may happen because of bug). - let last_actually_committed_block_number = storage - .chain() - .block_schema() - .get_last_saved_block() - .await?; - - let block_number = std::cmp::max(last_actually_committed_block_number, block_number); - Ok(block_number) }