diff --git a/Cargo.lock b/Cargo.lock index 75179116be6..8ed1250c483 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7333,6 +7333,7 @@ dependencies = [ "const-hex", "constant_time_eq 0.4.2", "crc32fast", + "crossbeam-channel", "crossbeam-epoch", "crossbeam-utils", "crunchy", @@ -7405,7 +7406,7 @@ dependencies = [ "indexmap 2.13.0", "ipnet", "itertools 0.10.5", - "itertools 0.11.0", + "itertools 0.13.0", "js-sys", "jsonrpsee", "jsonrpsee-client-transport", @@ -7534,7 +7535,6 @@ dependencies = [ "signature", "slice-group-by", "smallvec", - "socket2 0.4.10", "soketto", "sp-allocator", "sp-api", diff --git a/ethexe/common/src/db.rs b/ethexe/common/src/db.rs index 1557b54f404..e015223b9a1 100644 --- a/ethexe/common/src/db.rs +++ b/ethexe/common/src/db.rs @@ -43,9 +43,6 @@ pub struct BlockMeta { /// Block has been prepared, meaning: /// all metadata is ready, all predecessors till start block are prepared too. pub prepared: bool, - // TODO: #4945 remove announces from here - /// Set of announces included in the block. - pub announces: Option>>, /// Queue of code ids waiting for validation status commitment on-chain. pub codes_queue: Option>, /// Last committed on-chain batch hash. @@ -58,7 +55,6 @@ impl BlockMeta { pub fn default_prepared() -> Self { Self { prepared: true, - announces: Some(Default::default()), codes_queue: Some(Default::default()), last_committed_batch: Some(Default::default()), last_committed_announce: Some(Default::default()), @@ -152,11 +148,13 @@ pub trait AnnounceStorageRO { fn announce_outcome(&self, announce_hash: HashOf) -> Option>; fn announce_schedule(&self, announce_hash: HashOf) -> Option; fn announce_meta(&self, announce_hash: HashOf) -> AnnounceMeta; + fn block_announces(&self, block_hash: H256) -> Option>>; } #[auto_impl::auto_impl(&)] pub trait AnnounceStorageRW: AnnounceStorageRO { fn set_announce(&self, announce: Announce) -> HashOf; + fn set_block_announces(&self, block_hash: H256, announces: BTreeSet>); fn set_announce_program_states( &self, announce_hash: HashOf, @@ -170,6 +168,11 @@ pub trait AnnounceStorageRW: AnnounceStorageRO { announce_hash: HashOf, f: impl FnOnce(&mut AnnounceMeta), ); + fn mutate_block_announces( + &self, + block_hash: H256, + f: impl FnOnce(&mut BTreeSet>), + ); } pub struct PreparedBlockData { @@ -260,7 +263,7 @@ mod tests { #[test] fn ensure_types_unchanged() { const EXPECTED_TYPE_INFO_HASH: &str = - "36d0e8436bb8fa8ea920012e1b4b079f9b6a83414e016771afc977568d30f29b"; + "fe6086aaff64c357bccf5f0dd0c931467de148eb4ef34d8ca2114169c8008d35"; let types = [ meta_type::(), diff --git a/ethexe/common/src/mock.rs b/ethexe/common/src/mock.rs index bc3a60ec452..de1746f0570 100644 --- a/ethexe/common/src/mock.rs +++ b/ethexe/common/src/mock.rs @@ -439,10 +439,13 @@ impl BlockChain { last_committed_announce, }) = prepared { + if let Some(announces) = announces { + db.set_block_announces(hash, announces); + } + db.mutate_block_meta(hash, |meta| { *meta = BlockMeta { prepared: true, - announces, codes_queue: Some(codes_queue), last_committed_batch: Some(last_committed_batch), last_committed_announce: Some(last_committed_announce), @@ -601,7 +604,7 @@ pub trait DBMockExt { fn top_announce_hash(&self, block: H256) -> HashOf; } -impl DBMockExt for DB { +impl DBMockExt for DB { #[track_caller] fn simple_block_data(&self, block: H256) -> SimpleBlockData { let header = self.block_header(block).expect("block header not found"); @@ -613,8 +616,7 @@ impl DBMockExt for DB { #[track_caller] fn top_announce_hash(&self, block: H256) -> HashOf { - self.block_meta(block) - .announces + self.block_announces(block) .expect("block announces not found") .into_iter() .next() diff --git a/ethexe/common/src/utils.rs b/ethexe/common/src/utils.rs index be5be66e78f..013181b2493 100644 --- a/ethexe/common/src/utils.rs +++ b/ethexe/common/src/utils.rs @@ -44,7 +44,7 @@ pub const fn u64_into_uint48_be_bytes_lossy(val: u64) -> [u8; 6] { [b1, b2, b3, b4, b5, b6] } -pub fn setup_block_in_db( +pub fn setup_block_in_db( db: &DB, block_hash: H256, block_data: PreparedBlockData, @@ -53,10 +53,11 @@ pub fn setup_block_in_db( db.set_block_events(block_hash, &block_data.events); db.set_block_synced(block_hash); + db.set_block_announces(block_hash, block_data.announces); + db.mutate_block_meta(block_hash, |meta| { *meta = BlockMeta { prepared: true, - announces: Some(block_data.announces), codes_queue: Some(block_data.codes_queue), last_committed_batch: Some(block_data.last_committed_batch), last_committed_announce: Some(block_data.last_committed_announce), diff --git a/ethexe/compute/src/tests.rs b/ethexe/compute/src/tests.rs index 7aabd3ca808..afd5574ade4 100644 --- a/ethexe/compute/src/tests.rs +++ b/ethexe/compute/src/tests.rs @@ -226,9 +226,10 @@ impl TestEnv { let computed_announce = event.unwrap_announce_computed(); assert_eq!(computed_announce, announce_hash); - self.db.mutate_block_meta(announce.block_hash, |meta| { - meta.announces.get_or_insert_default().insert(announce_hash); - }); + self.db + .mutate_block_announces(announce.block_hash, |announces| { + announces.insert(announce_hash); + }); } } @@ -273,11 +274,10 @@ async fn multiple_preparation_and_one_processing() -> Result<()> { // append announces to prepared blocks, except the last one, so that it can be computed for i in 1..3 { let announce = new_announce(&env.db, env.chain.blocks[i].hash, Some(100)); - env.db.mutate_block_meta(announce.block_hash, |meta| { - meta.announces - .get_or_insert_default() - .insert(announce.to_hash()); - }); + env.db + .mutate_block_announces(announce.block_hash, |announces| { + announces.insert(announce.to_hash()); + }); env.db.set_announce(announce); } diff --git a/ethexe/consensus/src/announces.rs b/ethexe/consensus/src/announces.rs index 16509ca2211..cf792cf0736 100644 --- a/ethexe/consensus/src/announces.rs +++ b/ethexe/consensus/src/announces.rs @@ -147,7 +147,7 @@ impl< .block_header(current_block) .ok_or_else(|| anyhow!("header not found for block({current_block})"))?; - if self.block_meta(current_block).announces.is_some() { + if self.block_announces(current_block).is_some() { break; } @@ -168,11 +168,10 @@ impl< let announce_hash = self.set_announce(announce); let mut newly_included = None; - self.mutate_block_meta(block_hash, |meta| { - if let Some(announces) = &mut meta.announces { - newly_included = Some(announces.insert(announce_hash)); - } - }); + if let Some(mut announces) = self.block_announces(block_hash) { + newly_included = Some(announces.insert(announce_hash)); + self.set_block_announces(block_hash, announces); + } if let Some(newly_included) = newly_included { Ok((announce_hash, newly_included)) @@ -190,7 +189,7 @@ impl< } self.announce(announce_hash) - .and_then(|announce| self.block_meta(announce.block_hash).announces) + .and_then(|announce| self.block_announces(announce.block_hash)) .map(|announces| announces.contains(&announce_hash)) .unwrap_or(false) } @@ -225,7 +224,7 @@ pub fn propagate_announces( // iterate over the collected blocks from oldest to newest and propagate announces for block in chain { debug_assert!( - db.block_meta(block.hash).announces.is_none(), + db.block_announces(block.hash).is_none(), "Block {} should not have announces propagated yet", block.hash ); @@ -249,15 +248,14 @@ pub fn propagate_announces( )?; let mut new_base_announces = BTreeSet::new(); - for parent_announce_hash in db - .block_meta(block.header.parent_hash) - .announces - .ok_or_else(|| { - anyhow!( - "Parent block({}) announces are missing", - block.header.parent_hash - ) - })? + for parent_announce_hash in + db.block_announces(block.header.parent_hash) + .ok_or_else(|| { + anyhow!( + "Parent block({}) announces are missing", + block.header.parent_hash + ) + })? { if let Some(new_base_announce) = propagate_one_base_announce( db, @@ -278,14 +276,12 @@ pub fn propagate_announces( block.hash ); - db.mutate_block_meta(block.hash, |meta| { - debug_assert!( - meta.announces.is_none(), - "block({}) announces must be None before propagation", - block.hash - ); - meta.announces = Some(new_base_announces); - }); + debug_assert!( + db.block_announces(block.hash).is_none(), + "block({}) announces must be None before propagation", + block.hash + ); + db.set_block_announces(block.hash, new_base_announces); } Ok(()) @@ -446,8 +442,7 @@ fn propagate_one_base_announce( // Check neighbor announces to be last committed announce if db - .block_meta(current_announce.block_hash) - .announces + .block_announces(current_announce.block_hash) .ok_or_else(|| { anyhow!( "announces are missing for block({})", @@ -562,8 +557,7 @@ fn find_announces_common_predecessor( let start_announce_hash = db.globals().start_announce_hash; let mut announces = db - .block_meta(block_hash) - .announces + .block_announces(block_hash) .ok_or_else(|| anyhow!("announces not found for block {block_hash}"))?; for _ in 0..commitment_delay_limit { @@ -606,7 +600,7 @@ pub fn best_parent_announce( // so we take parents of all announces from `block_hash`, // to be sure that we take only not expired parent announces. let parent_announces = - db.announces_parents(db.block_meta(block_hash).announces.into_iter().flatten())?; + db.announces_parents(db.block_announces(block_hash).into_iter().flatten())?; best_announce(db, parent_announces, commitment_delay_limit) } @@ -836,8 +830,7 @@ mod tests { ) -> (H256, usize) { let block_hash = chain.blocks[idx].hash; let announces_amount = db - .block_meta(block_hash) - .announces + .block_announces(block_hash) .unwrap_or_else(|| panic!("announces not found for block {block_hash}")) .len(); (block_hash, announces_amount) diff --git a/ethexe/consensus/src/validator/batch/manager.rs b/ethexe/consensus/src/validator/batch/manager.rs index 5594d52649a..54838ce82bc 100644 --- a/ethexe/consensus/src/validator/batch/manager.rs +++ b/ethexe/consensus/src/validator/batch/manager.rs @@ -200,12 +200,7 @@ impl BatchCommitmentManager { }); } - let candidates = self - .db - .block_meta(block.hash) - .announces - .into_iter() - .flatten(); + let candidates = self.db.block_announces(block.hash).into_iter().flatten(); let best_announce_hash = announces::best_announce(&self.db, candidates, self.limits.commitment_delay_limit)?; diff --git a/ethexe/consensus/src/validator/initial.rs b/ethexe/consensus/src/validator/initial.rs index 8d0d0f5f03b..53201e33516 100644 --- a/ethexe/consensus/src/validator/initial.rs +++ b/ethexe/consensus/src/validator/initial.rs @@ -443,11 +443,11 @@ mod tests { let ctx = state.into_context(); assert_eq!(ctx.output, vec![]); for i in last - 5..last - 5 + ctx.core.commitment_delay_limit as usize { - let announces = ctx.core.db.block_meta(chain.blocks[i].hash).announces; + let announces = ctx.core.db.block_announces(chain.blocks[i].hash); assert_eq!(announces.unwrap().len(), 2); } for i in last - 5 + ctx.core.commitment_delay_limit as usize..=last { - let announces = ctx.core.db.block_meta(chain.blocks[i].hash).announces; + let announces = ctx.core.db.block_announces(chain.blocks[i].hash); assert_eq!(announces.unwrap().len(), 1); } } @@ -480,7 +480,7 @@ mod tests { assert_eq!(ctx.output, vec![]); (last - 9..=last).for_each(|idx| { let block_hash = chain.blocks[idx].hash; - let announces = ctx.core.db.block_meta(block_hash).announces; + let announces = ctx.core.db.block_announces(block_hash); assert!( announces.is_some(), "expected announces to be propagated for block {block_hash}" @@ -549,7 +549,6 @@ mod tests { let (ctx, _, _) = mock_validator_context(); let block = BlockChain::mock(1) - .setup(&ctx.core.db) .tap_mut(|chain| { chain.blocks[1].as_prepared_mut().announces = None; chain.blocks[1].as_prepared_mut().last_committed_announce = HashOf::random(); diff --git a/ethexe/db/src/database.rs b/ethexe/db/src/database.rs index 13af1ada3fb..6d16f3a808a 100644 --- a/ethexe/db/src/database.rs +++ b/ethexe/db/src/database.rs @@ -48,6 +48,7 @@ use gear_core::{ }; use gprimitives::H256; use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; use std::{ collections::BTreeSet, mem::size_of, @@ -59,6 +60,7 @@ enum Key { // TODO (kuzmindev): use `HashOf` here BlockSmallData(H256) = 0, BlockEvents(H256) = 1, + BlockAnnounces(H256) = 13, ValidatorSet(u64) = 2, @@ -75,7 +77,6 @@ enum Key { InjectedTransaction(HashOf) = 12, - // TODO kuzmindev: make keys prefixes consistent. We don't change it to avoid corrupting existing key layout. Globals = 14, Config = 15, @@ -100,6 +101,7 @@ impl Key { match self { Self::BlockSmallData(hash) | Self::BlockEvents(hash) + | Self::BlockAnnounces(hash) | Self::LatestEraValidatorsCommitted(hash) => bytes.extend(hash.as_ref()), Self::ValidatorSet(era_index) => { @@ -417,6 +419,15 @@ impl AnnounceStorageRO for RawDatabase { }) .unwrap_or_default() } + + fn block_announces(&self, block_hash: H256) -> Option>> { + self.kv + .get(&Key::BlockAnnounces(block_hash).to_bytes()) + .map(|data| { + BTreeSet::>::decode(&mut data.as_slice()) + .expect("Failed to decode data into `BTreeSet>`") + }) + } } impl AnnounceStorageRW for RawDatabase { @@ -464,6 +475,28 @@ impl AnnounceStorageRW for RawDatabase { self.kv .put(&Key::AnnounceMeta(announce_hash).to_bytes(), meta.encode()); } + + fn set_block_announces(&self, block_hash: H256, announces: BTreeSet>) { + tracing::trace!("Set block {block_hash} announces: len {}", announces.len()); + self.kv.put( + &Key::BlockAnnounces(block_hash).to_bytes(), + announces.encode(), + ); + } + + fn mutate_block_announces( + &self, + block_hash: H256, + f: impl FnOnce(&mut BTreeSet>), + ) { + tracing::trace!("For block {block_hash} mutate announces"); + let mut announces = self.block_announces(block_hash).unwrap_or_default(); + f(&mut announces); + self.kv.put( + &Key::BlockAnnounces(block_hash).to_bytes(), + announces.encode(), + ); + } } impl OnChainStorageRO for RawDatabase { @@ -797,11 +830,11 @@ impl HashStorageRO for Database { } } -#[derive(Debug, Clone, Default, Encode, Decode, PartialEq, Eq)] -struct BlockSmallData { - block_header: Option, - block_is_synced: bool, - meta: BlockMeta, +#[derive(Debug, Clone, Default, Encode, Decode, TypeInfo, PartialEq, Eq)] +pub(crate) struct BlockSmallData { + pub block_header: Option, + pub block_is_synced: bool, + pub meta: BlockMeta, } impl BlockMetaStorageRO for Database { @@ -883,6 +916,7 @@ impl AnnounceStorageRO for Database { fn announce_outcome(&self, announce_hash: HashOf) -> Option>; fn announce_schedule(&self, announce_hash: HashOf) -> Option; fn announce_meta(&self, announce_hash: HashOf) -> AnnounceMeta; + fn block_announces(&self, block_hash: H256) -> Option>>; }); } @@ -901,6 +935,12 @@ impl AnnounceStorageRW for Database { announce_hash: HashOf, f: impl FnOnce(&mut AnnounceMeta), ); + fn set_block_announces(&self, block_hash: H256, announces: BTreeSet>); + fn mutate_block_announces( + &self, + block_hash: H256, + f: impl FnOnce(&mut BTreeSet>), + ); }); } diff --git a/ethexe/db/src/iterator.rs b/ethexe/db/src/iterator.rs index b77089cae8c..99008a6c91f 100644 --- a/ethexe/db/src/iterator.rs +++ b/ethexe/db/src/iterator.rs @@ -525,14 +525,13 @@ where fn iter_block_meta(&mut self, BlockMetaNode { block, meta }: &BlockMetaNode) { let BlockMeta { prepared: _, - announces, codes_queue, last_committed_batch: _, last_committed_announce: _, } = meta; - if let Some(announces) = announces { - for &announce_hash in announces { + if let Some(announces) = self.storage.block_announces(*block) { + for announce_hash in announces.into_iter() { try_push_node!(with_hash: self.announce(announce_hash)); } } else { diff --git a/ethexe/db/src/migrations/mod.rs b/ethexe/db/src/migrations/mod.rs index ce9ad2a33db..db216e4d05e 100644 --- a/ethexe/db/src/migrations/mod.rs +++ b/ethexe/db/src/migrations/mod.rs @@ -31,10 +31,11 @@ mod migration; mod v0; mod v1; +mod v2; pub const OLDEST_SUPPORTED_VERSION: u32 = v0::VERSION; -pub const LATEST_VERSION: u32 = v1::VERSION; -pub const MIGRATIONS: &[&dyn Migration] = &[&v1::migration_from_v0]; +pub const LATEST_VERSION: u32 = v2::VERSION; +pub const MIGRATIONS: &[&dyn Migration] = &[&v1::migration_from_v0, &v2::migration_from_v1]; const _: () = assert!( (LATEST_VERSION - OLDEST_SUPPORTED_VERSION) as usize == MIGRATIONS.len(), diff --git a/ethexe/db/src/migrations/v0.rs b/ethexe/db/src/migrations/v0.rs index 70947abb2d2..3dcb27cdae1 100644 --- a/ethexe/db/src/migrations/v0.rs +++ b/ethexe/db/src/migrations/v0.rs @@ -16,10 +16,12 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use ethexe_common::{Announce, HashOf, SimpleBlockData}; -use gprimitives::H256; +use ethexe_common::{Announce, BlockHeader, HashOf, SimpleBlockData}; +use gprimitives::{CodeId, H256}; +use gsigner::Digest; use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; +use std::collections::{BTreeSet, VecDeque}; pub const VERSION: u32 = 0; @@ -40,3 +42,19 @@ pub struct ProtocolTimelines { pub era: u64, pub election: u64, } + +#[derive(Encode, Decode, TypeInfo)] +pub struct BlockMeta { + pub prepared: bool, + pub announces: Option>>, + pub codes_queue: Option>, + pub last_committed_batch: Option, + pub last_committed_announce: Option>, +} + +#[derive(Encode, Decode, TypeInfo)] +pub struct BlockSmallData { + pub block_header: Option, + pub block_is_synced: bool, + pub meta: BlockMeta, +} diff --git a/ethexe/db/src/migrations/v2.rs b/ethexe/db/src/migrations/v2.rs new file mode 100644 index 00000000000..edc0fba42b1 --- /dev/null +++ b/ethexe/db/src/migrations/v2.rs @@ -0,0 +1,109 @@ +// This file is part of Gear. +// +// Copyright (C) 2026 Gear Technologies Inc. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use crate::{InitConfig, RawDatabase, database::BlockSmallData, migrations::v0}; +use anyhow::{Context, Result}; +use ethexe_common::db::{BlockMeta, DBConfig}; +use gprimitives::H256; +use parity_scale_codec::{Decode, Encode}; + +pub const VERSION: u32 = 2; + +pub async fn migration_from_v1(_: &InitConfig, db: &RawDatabase) -> Result<()> { + // Changes from v1 to v2: + // - Block announces are moved from `BlockMeta` to `BlockAnnounces` key. + + let block_small_data_prefix = H256::from_low_u64_be(0); + let block_announces_prefix = H256::from_low_u64_be(13); + + for (key, value) in db.kv.iter_prefix(block_small_data_prefix.as_bytes()) { + let v0::BlockSmallData { + block_header, + block_is_synced, + meta: + v0::BlockMeta { + prepared, + announces, + codes_queue, + last_committed_batch, + last_committed_announce, + }, + } = v0::BlockSmallData::decode(&mut value.as_slice())?; + + let block_hash = &key[32..]; + let announces_key = [block_announces_prefix.as_bytes(), block_hash].concat(); + + db.kv.put(&announces_key, announces.encode()); + + db.kv.put( + &key, + BlockSmallData { + block_header, + block_is_synced, + meta: BlockMeta { + prepared, + codes_queue, + last_committed_batch, + last_committed_announce, + }, + } + .encode(), + ); + } + + let config_key = [H256::from_low_u64_be(15).0.as_slice(), &[0u8; 8]].concat(); + + let old_config = db + .kv + .get(&config_key) + .context("Database config are guaranteed for version 1, but not found") + .and_then(|bytes| Ok(DBConfig::decode(&mut bytes.as_slice())?))?; + + db.kv.put( + &config_key, + DBConfig { + version: VERSION, + ..old_config + } + .encode(), + ); + + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::migrations::test::assert_migration_types_hash; + use scale_info::meta_type; + + #[test] + fn ensure_migration_types() { + assert_migration_types_hash( + "v1->v2", + vec![ + meta_type::(), + meta_type::(), + meta_type::(), + meta_type::(), + meta_type::(), + ], + "6506461993fe4e74645148eb4af27aecfef09e5b4789b5b9936c86adab62a8ff", + ); + } +} diff --git a/ethexe/db/src/verifier.rs b/ethexe/db/src/verifier.rs index f321b459f59..89f1f6c973b 100644 --- a/ethexe/db/src/verifier.rs +++ b/ethexe/db/src/verifier.rs @@ -23,7 +23,7 @@ use crate::{ }; use ethexe_common::{ Announce, BlockHeader, HashOf, ScheduledTask, - db::{AnnounceStorageRO, BlockMeta, BlockMetaStorageRO, OnChainStorageRO}, + db::{AnnounceStorageRO, BlockMeta, OnChainStorageRO}, }; use ethexe_runtime_common::state::{MessageQueue, MessageQueueHashWithSize}; use gear_core::code::CodeMetadata; @@ -166,7 +166,7 @@ impl DatabaseVisitor for IntegrityVerifier { self.errors .push(IntegrityVerifierError::NoBlockLastCommittedAnnounce(block)); } - if let Some(announces) = meta.announces { + if let Some(announces) = self.db.block_announces(block) { if announces.is_empty() { self.errors .push(IntegrityVerifierError::BlockAnnouncesIsEmpty(block)); @@ -185,8 +185,7 @@ impl DatabaseVisitor for IntegrityVerifier { } if self .db - .block_meta(announce.block_hash) - .announces + .block_announces(announce.block_hash) .map(|announces| announces.iter().all(|a| *a != announce_hash)) .unwrap_or(true) { @@ -694,11 +693,11 @@ mod tests { db.set_block_header(block_hash, block_header); db.set_block_events(block_hash, &[]); + db.set_block_announces(block_hash, [announce_hash].into()); db.mutate_block_meta(block_hash, |meta| { meta.prepared = true; meta.last_committed_batch = Some(Digest::random()); meta.last_committed_announce = Some(announce_hash); - meta.announces = Some([announce_hash].into()); meta.codes_queue = Some(Default::default()); }); db.set_block_synced(block_hash); diff --git a/ethexe/network/src/db_sync/mod.rs b/ethexe/network/src/db_sync/mod.rs index a021344d006..20b3d92d3a7 100644 --- a/ethexe/network/src/db_sync/mod.rs +++ b/ethexe/network/src/db_sync/mod.rs @@ -1351,13 +1351,12 @@ pub(crate) mod tests { .set_programs_code_ids_at(program_ids.clone(), H256::zero(), code_ids.clone()) .await; - let mut announce_hash = HashOf::zero(); - right_db.mutate_block_meta(H256::zero(), |meta| { - assert!(meta.announces.is_none()); - let announce = Announce::base(H256::zero(), HashOf::zero()); - announce_hash = announce.to_hash(); - meta.announces = Some([announce_hash].into()); + let announce = Announce::base(H256::zero(), HashOf::zero()); + let announce_hash = announce.to_hash(); + right_db.mutate_block_announces(H256::zero(), |announces| { + announces.insert(announce_hash); }); + right_db.mutate_block_meta(H256::zero(), |_meta| {}); right_db.set_announce_program_states( announce_hash, diff --git a/ethexe/network/src/db_sync/responses.rs b/ethexe/network/src/db_sync/responses.rs index 8981d3f8017..34c4ae0a01b 100644 --- a/ethexe/network/src/db_sync/responses.rs +++ b/ethexe/network/src/db_sync/responses.rs @@ -25,7 +25,7 @@ use crate::{ }; use ethexe_common::{ Announce, HashOf, - db::{AnnounceStorageRO, BlockMetaStorageRO, ConfigStorageRO, GlobalsStorageRO}, + db::{AnnounceStorageRO, ConfigStorageRO, GlobalsStorageRO}, network::{AnnouncesRequest, AnnouncesRequestUntil}, }; use libp2p::request_response; @@ -84,8 +84,7 @@ impl OngoingResponses { ) .into(), InnerRequest::ProgramIds(request) => InnerProgramIdsResponse( - db.block_meta(request.at) - .announces + db.block_announces(request.at) .into_iter() .flatten() .find_map(|announce_hash| db.announce_program_states(announce_hash)) diff --git a/ethexe/rpc/src/apis/mod.rs b/ethexe/rpc/src/apis/mod.rs index 8ed642f4ca1..8a0d0275584 100644 --- a/ethexe/rpc/src/apis/mod.rs +++ b/ethexe/rpc/src/apis/mod.rs @@ -24,9 +24,11 @@ mod program; pub use block::{BlockApi, BlockServer}; pub use code::{CodeApi, CodeServer}; pub use injected::{InjectedApi, InjectedServer}; -pub use program::{FullProgramState, ProgramApi, ProgramServer}; +pub use program::{ProgramApi, ProgramServer}; #[cfg(feature = "client")] pub use crate::apis::{ block::BlockClient, code::CodeClient, injected::InjectedClient, program::ProgramClient, }; +#[cfg(feature = "client")] +pub use program::FullProgramState; diff --git a/ethexe/rpc/src/utils.rs b/ethexe/rpc/src/utils.rs index 9bd1cec3bd3..a96aeafbd7c 100644 --- a/ethexe/rpc/src/utils.rs +++ b/ethexe/rpc/src/utils.rs @@ -19,7 +19,7 @@ use crate::errors; use ethexe_common::{ Announce, HashOf, SimpleBlockData, - db::{AnnounceStorageRO, BlockMetaStorageRO, GlobalsStorageRO, OnChainStorageRO}, + db::{AnnounceStorageRO, GlobalsStorageRO, OnChainStorageRO}, }; use ethexe_db::Database; use jsonrpsee::core::RpcResult; @@ -54,8 +54,7 @@ pub fn announce_at_or_latest_computed( ) -> RpcResult> { if let Some(at) = at.into() { let computed_announces: Vec<_> = db - .block_meta(at) - .announces + .block_announces(at) .into_iter() .flatten() .filter(|announce_hash| db.announce_meta(*announce_hash).computed) diff --git a/ethexe/service/src/tests/mod.rs b/ethexe/service/src/tests/mod.rs index a02f55aaae4..7c225b78d68 100644 --- a/ethexe/service/src/tests/mod.rs +++ b/ethexe/service/src/tests/mod.rs @@ -1646,9 +1646,9 @@ async fn fast_sync() { bob_meta.last_committed_batch ); - let Some((alice_announces, bob_announces)) = - alice_meta.announces.zip(bob_meta.announces) - else { + let alice_announces = alice.db.block_announces(block); + let bob_announces = bob.db.block_announces(block); + let Some((alice_announces, bob_announces)) = alice_announces.zip(bob_announces) else { panic!("alice or bob has no announces"); }; @@ -2983,8 +2983,7 @@ async fn announces_conflicts() { let timelines = env.db.config().timelines; let era_index = timelines.era_from_ts(block.header.timestamp); let parent = validator1_db - .block_meta(block.header.parent_hash) - .announces + .block_announces(block.header.parent_hash) .into_iter() .flatten() .find(|&announce_hash| validator1_db.announce(announce_hash).unwrap().is_base()) diff --git a/utils/gear-workspace-hack/Cargo.toml b/utils/gear-workspace-hack/Cargo.toml index 147d61f8e92..6d7413ed7f8 100644 --- a/utils/gear-workspace-hack/Cargo.toml +++ b/utils/gear-workspace-hack/Cargo.toml @@ -262,6 +262,7 @@ concurrent-queue = { version = "2" } const-hex = { version = "1", features = ["core-error", "serde"] } constant_time_eq = { version = "0.4", default-features = false, features = ["std"] } crc32fast = { version = "1" } +crossbeam-channel = { version = "0.5" } crossbeam-utils = { version = "0.8" } crunchy = { version = "0.2", features = ["std"] } crypto-common = { version = "0.1", default-features = false, features = ["getrandom", "std"] } @@ -403,7 +404,6 @@ sha3 = { version = "0.10", features = ["asm"] } signature = { version = "2", default-features = false, features = ["digest", "rand_core", "std"] } slice-group-by = { version = "0.3" } smallvec = { version = "1", default-features = false, features = ["const_new", "serde", "union"] } -socket2 = { version = "0.4", default-features = false, features = ["all"] } soketto = { version = "0.8", features = ["http"] } sp-allocator = { git = "https://github.com/gear-tech/polkadot-sdk.git", branch = "gear-polkadot-stable2409-wasm32v1-none" } sp-api = { git = "https://github.com/gear-tech/polkadot-sdk.git", branch = "gear-polkadot-stable2409-wasm32v1-none", features = ["frame-metadata"] } @@ -539,6 +539,7 @@ concurrent-queue = { version = "2" } const-hex = { version = "1", features = ["core-error", "serde"] } constant_time_eq = { version = "0.4", default-features = false, features = ["std"] } crc32fast = { version = "1" } +crossbeam-channel = { version = "0.5" } crossbeam-utils = { version = "0.8" } crunchy = { version = "0.2", features = ["std"] } crypto-common = { version = "0.1", default-features = false, features = ["getrandom", "std"] } @@ -688,7 +689,6 @@ sha3 = { version = "0.10", features = ["asm"] } signature = { version = "2", default-features = false, features = ["digest", "rand_core", "std"] } slice-group-by = { version = "0.3" } smallvec = { version = "1", default-features = false, features = ["const_new", "serde", "union"] } -socket2 = { version = "0.4", default-features = false, features = ["all"] } soketto = { version = "0.8", features = ["http"] } sp-allocator = { git = "https://github.com/gear-tech/polkadot-sdk.git", branch = "gear-polkadot-stable2409-wasm32v1-none" } sp-api = { git = "https://github.com/gear-tech/polkadot-sdk.git", branch = "gear-polkadot-stable2409-wasm32v1-none", features = ["frame-metadata"] } @@ -781,7 +781,7 @@ errno = { version = "0.3" } gimli = { version = "0.28" } hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "logging", "ring", "tls12", "webpki-tokio"] } hyper-util = { version = "0.1", default-features = false, features = ["client-proxy"] } -itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" } +itertools-594e8ee84c453af0 = { package = "itertools", version = "0.13", default-features = false, features = ["use_std"] } libc = { version = "0.2", default-features = false, features = ["extra_traits"] } miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } mio = { version = "1", features = ["net", "os-ext"] } @@ -806,7 +806,7 @@ errno = { version = "0.3" } gimli = { version = "0.28" } hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "logging", "ring", "tls12", "webpki-tokio"] } hyper-util = { version = "0.1", default-features = false, features = ["client-proxy"] } -itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" } +itertools-594e8ee84c453af0 = { package = "itertools", version = "0.13", default-features = false, features = ["use_std"] } libc = { version = "0.2", default-features = false, features = ["extra_traits"] } miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } mio = { version = "1", features = ["net", "os-ext"] } @@ -832,7 +832,7 @@ errno = { version = "0.3" } gimli = { version = "0.28" } hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "logging", "ring", "tls12", "webpki-tokio"] } hyper-util = { version = "0.1", default-features = false, features = ["client-proxy"] } -itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" } +itertools-594e8ee84c453af0 = { package = "itertools", version = "0.13", default-features = false, features = ["use_std"] } libc = { version = "0.2", default-features = false, features = ["extra_traits"] } miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } mio = { version = "1", features = ["net", "os-ext"] } @@ -856,7 +856,7 @@ errno = { version = "0.3" } gimli = { version = "0.28" } hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "logging", "ring", "tls12", "webpki-tokio"] } hyper-util = { version = "0.1", default-features = false, features = ["client-proxy"] } -itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" } +itertools-594e8ee84c453af0 = { package = "itertools", version = "0.13", default-features = false, features = ["use_std"] } libc = { version = "0.2", default-features = false, features = ["extra_traits"] } miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } mio = { version = "1", features = ["net", "os-ext"] } @@ -881,7 +881,7 @@ errno = { version = "0.3" } gimli = { version = "0.28" } hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "logging", "ring", "tls12", "webpki-tokio"] } hyper-util = { version = "0.1", default-features = false, features = ["client-proxy"] } -itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" } +itertools-594e8ee84c453af0 = { package = "itertools", version = "0.13", default-features = false, features = ["use_std"] } libc = { version = "0.2", default-features = false, features = ["extra_traits"] } miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } nom = { version = "7" } @@ -903,7 +903,7 @@ errno = { version = "0.3" } gimli = { version = "0.28" } hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "logging", "ring", "tls12", "webpki-tokio"] } hyper-util = { version = "0.1", default-features = false, features = ["client-proxy"] } -itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" } +itertools-594e8ee84c453af0 = { package = "itertools", version = "0.13", default-features = false, features = ["use_std"] } libc = { version = "0.2", default-features = false, features = ["extra_traits"] } miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } nom = { version = "7" }