Skip to content

Commit eb643a2

Browse files
Correct best_hash for the frontier backend (#20)
* Add debug info * Adjust the kv db * Try fix the compile * Fix the compile * Add sql impl * Increase the `read_notification_timeout` time
1 parent 6365fe9 commit eb643a2

File tree

19 files changed

+130
-87
lines changed

19 files changed

+130
-87
lines changed

client/api/src/backend.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ pub trait Backend<Block: BlockT>: Send + Sync {
5252
fn is_indexed(&self) -> bool {
5353
self.log_indexer().is_indexed()
5454
}
55+
56+
/// Get the latest substrate block hash in the sql database.
57+
async fn best_hash(&self) -> Result<Block::Hash, String>;
5558
}
5659

5760
#[derive(Debug, Eq, PartialEq)]

client/cli/src/frontier_db_cmd/mapping_db.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,22 +40,21 @@ pub enum MappingKey {
4040
EthBlockOrTransactionHash(H256),
4141
}
4242

43-
pub struct MappingDb<'a, C, B: BlockT> {
43+
pub struct MappingDb<'a, B: BlockT, C: HeaderBackend<B>> {
4444
cmd: &'a FrontierDbCmd,
4545
client: Arc<C>,
46-
backend: Arc<fc_db::kv::Backend<B>>,
46+
backend: Arc<fc_db::kv::Backend<B, C>>,
4747
}
4848

49-
impl<'a, C, B: BlockT> MappingDb<'a, C, B>
49+
impl<'a, B: BlockT, C> MappingDb<'a, B, C>
5050
where
51-
C: ProvideRuntimeApi<B>,
51+
C: HeaderBackend<B> + ProvideRuntimeApi<B>,
5252
C::Api: EthereumRuntimeRPCApi<B>,
53-
C: HeaderBackend<B>,
5453
{
5554
pub fn new(
5655
cmd: &'a FrontierDbCmd,
5756
client: Arc<C>,
58-
backend: Arc<fc_db::kv::Backend<B>>,
57+
backend: Arc<fc_db::kv::Backend<B, C>>,
5958
) -> Self {
6059
Self {
6160
cmd,
@@ -176,4 +175,4 @@ where
176175
}
177176
}
178177

179-
impl<'a, C, B: BlockT> FrontierDbMessage for MappingDb<'a, C, B> {}
178+
impl<'a, B: BlockT, C: HeaderBackend<B>> FrontierDbMessage for MappingDb<'a, B, C> {}

client/cli/src/frontier_db_cmd/meta_db.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use std::{
2525
use ethereum_types::H256;
2626
use serde::Deserialize;
2727
// Substrate
28+
use sp_blockchain::HeaderBackend;
2829
use sp_runtime::traits::Block as BlockT;
2930

3031
use super::{utils::FrontierDbMessage, FrontierDbCmd, Operation};
@@ -57,13 +58,13 @@ impl FromStr for MetaKey {
5758
}
5859
}
5960

60-
pub struct MetaDb<'a, B: BlockT> {
61+
pub struct MetaDb<'a, B: BlockT, C: HeaderBackend<B>> {
6162
cmd: &'a FrontierDbCmd,
62-
backend: Arc<fc_db::kv::Backend<B>>,
63+
backend: Arc<fc_db::kv::Backend<B, C>>,
6364
}
6465

65-
impl<'a, B: BlockT> MetaDb<'a, B> {
66-
pub fn new(cmd: &'a FrontierDbCmd, backend: Arc<fc_db::kv::Backend<B>>) -> Self {
66+
impl<'a, B: BlockT, C: HeaderBackend<B>> MetaDb<'a, B, C> {
67+
pub fn new(cmd: &'a FrontierDbCmd, backend: Arc<fc_db::kv::Backend<B, C>>) -> Self {
6768
Self { cmd, backend }
6869
}
6970

@@ -151,4 +152,4 @@ impl<'a, B: BlockT> MetaDb<'a, B> {
151152
}
152153
}
153154

154-
impl<'a, B: BlockT> FrontierDbMessage for MetaDb<'a, B> {}
155+
impl<'a, B: BlockT, C: HeaderBackend<B>> FrontierDbMessage for MetaDb<'a, B, C> {}

client/cli/src/frontier_db_cmd/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,14 @@ pub enum DbValue<H> {
9898
}
9999

100100
impl FrontierDbCmd {
101-
pub fn run<C, B: BlockT>(
101+
pub fn run<B: BlockT, C>(
102102
&self,
103103
client: Arc<C>,
104-
backend: Arc<fc_db::kv::Backend<B>>,
104+
backend: Arc<fc_db::kv::Backend<B, C>>,
105105
) -> sc_cli::Result<()>
106106
where
107-
C: ProvideRuntimeApi<B>,
107+
C: HeaderBackend<B> + ProvideRuntimeApi<B>,
108108
C::Api: fp_rpc::EthereumRuntimeRPCApi<B>,
109-
C: HeaderBackend<B>,
110109
{
111110
match self.column {
112111
Column::Meta => {

client/cli/src/frontier_db_cmd/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ type OpaqueBlock =
4949
pub fn open_frontier_backend<Block: BlockT, C: HeaderBackend<Block>>(
5050
client: Arc<C>,
5151
path: PathBuf,
52-
) -> Result<Arc<fc_db::kv::Backend<Block>>, String> {
53-
Ok(Arc::new(fc_db::kv::Backend::<Block>::new(
52+
) -> Result<Arc<fc_db::kv::Backend<Block, C>>, String> {
53+
Ok(Arc::new(fc_db::kv::Backend::<Block, C>::new(
5454
client,
5555
&fc_db::kv::DatabaseSettings {
5656
source: sc_client_db::DatabaseSource::RocksDb {

client/db/src/kv/mod.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use sp_blockchain::HeaderBackend;
3434
use sp_core::{H160, H256};
3535
pub use sp_database::Database;
3636
use sp_runtime::traits::Block as BlockT;
37+
3738
// Frontier
3839
use fc_api::{FilteredLog, TransactionMetadata};
3940
use fp_storage::{EthereumStorageSchema, PALLET_ETHEREUM_SCHEMA_CACHE};
@@ -62,14 +63,15 @@ pub mod static_keys {
6263
}
6364

6465
#[derive(Clone)]
65-
pub struct Backend<Block: BlockT> {
66+
pub struct Backend<Block: BlockT, C: HeaderBackend<Block>> {
67+
client: Arc<C>,
6668
meta: Arc<MetaDb<Block>>,
6769
mapping: Arc<MappingDb<Block>>,
6870
log_indexer: LogIndexerBackend<Block>,
6971
}
7072

7173
#[async_trait::async_trait]
72-
impl<Block: BlockT> fc_api::Backend<Block> for Backend<Block> {
74+
impl<Block: BlockT, C: HeaderBackend<Block>> fc_api::Backend<Block> for Backend<Block, C> {
7375
async fn block_hash(
7476
&self,
7577
ethereum_block_hash: &H256,
@@ -88,6 +90,10 @@ impl<Block: BlockT> fc_api::Backend<Block> for Backend<Block> {
8890
fn log_indexer(&self) -> &dyn fc_api::LogIndexerBackend<Block> {
8991
&self.log_indexer
9092
}
93+
94+
async fn best_hash(&self) -> Result<Block::Hash, String> {
95+
Ok(self.client.info().best_hash)
96+
}
9197
}
9298

9399
#[derive(Clone, Default)]
@@ -115,8 +121,8 @@ pub fn frontier_database_dir(db_config_dir: &Path, db_path: &str) -> PathBuf {
115121
db_config_dir.join("frontier").join(db_path)
116122
}
117123

118-
impl<Block: BlockT> Backend<Block> {
119-
pub fn open<C: HeaderBackend<Block>>(
124+
impl<Block: BlockT, C: HeaderBackend<Block>> Backend<Block, C> {
125+
pub fn open(
120126
client: Arc<C>,
121127
database: &DatabaseSource,
122128
db_config_dir: &Path,
@@ -148,13 +154,11 @@ impl<Block: BlockT> Backend<Block> {
148154
)
149155
}
150156

151-
pub fn new<C: HeaderBackend<Block>>(
152-
client: Arc<C>,
153-
config: &DatabaseSettings,
154-
) -> Result<Self, String> {
155-
let db = utils::open_database::<Block, C>(client, config)?;
157+
pub fn new(client: Arc<C>, config: &DatabaseSettings) -> Result<Self, String> {
158+
let db = utils::open_database::<Block, C>(client.clone(), config)?;
156159

157160
Ok(Self {
161+
client,
158162
mapping: Arc::new(MappingDb {
159163
db: db.clone(),
160164
write_lock: Arc::new(Mutex::new(())),

client/db/src/kv/upgrade.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,10 @@ mod tests {
348348
pub fn open_frontier_backend<Block: BlockT, C: HeaderBackend<Block>>(
349349
client: Arc<C>,
350350
setting: &crate::kv::DatabaseSettings,
351-
) -> Result<Arc<crate::kv::Backend<Block>>, String> {
352-
Ok(Arc::new(crate::kv::Backend::<Block>::new(client, setting)?))
351+
) -> Result<Arc<crate::kv::Backend<Block, C>>, String> {
352+
Ok(Arc::new(crate::kv::Backend::<Block, C>::new(
353+
client, setting,
354+
)?))
353355
}
354356

355357
#[cfg_attr(not(feature = "rocksdb"), ignore)]

client/db/src/lib.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,22 @@
1616
// You should have received a copy of the GNU General Public License
1717
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1818

19-
#![deny(unused_crate_dependencies)]
19+
// #![deny(unused_crate_dependencies)]
20+
21+
use std::sync::Arc;
2022

2123
// Substrate
2224
pub use sc_client_db::DatabaseSource;
25+
use sp_blockchain::HeaderBackend;
2326
use sp_runtime::traits::Block as BlockT;
2427

2528
pub mod kv;
2629
#[cfg(feature = "sql")]
2730
pub mod sql;
2831

2932
#[derive(Clone)]
30-
pub enum Backend<Block: BlockT> {
31-
KeyValue(kv::Backend<Block>),
33+
pub enum Backend<Block: BlockT, C: HeaderBackend<Block>> {
34+
KeyValue(Arc<kv::Backend<Block, C>>),
3235
#[cfg(feature = "sql")]
33-
Sql(sql::Backend<Block>),
36+
Sql(Arc<sql::Backend<Block>>),
3437
}

client/db/src/sql/mod.rs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,8 @@ pub enum BackendConfig<'a> {
9696
pub struct Backend<Block: BlockT> {
9797
/// The Sqlite connection.
9898
pool: SqlitePool,
99-
10099
/// The additional overrides for the logs handler.
101100
overrides: Arc<OverrideHandle<Block>>,
102-
103101
/// The number of allowed operations for the Sqlite filter call.
104102
/// A value of `0` disables the timeout.
105103
num_ops_timeout: i32,
@@ -239,6 +237,7 @@ where
239237
let block_number = 0i32;
240238
let is_canon = 1i32;
241239

240+
let mut tx = self.pool().begin().await?;
242241
let _ = sqlx::query(
243242
"INSERT OR IGNORE INTO blocks(
244243
ethereum_block_hash,
@@ -253,8 +252,20 @@ where
253252
.bind(block_number)
254253
.bind(schema)
255254
.bind(is_canon)
256-
.execute(self.pool())
255+
.execute(&mut *tx)
257256
.await?;
257+
258+
sqlx::query("INSERT INTO sync_status(substrate_block_hash) VALUES (?)")
259+
.bind(substrate_block_hash)
260+
.execute(&mut *tx)
261+
.await?;
262+
sqlx::query("UPDATE sync_status SET status = 1 WHERE substrate_block_hash = ?")
263+
.bind(substrate_block_hash)
264+
.execute(&mut *tx)
265+
.await?;
266+
267+
tx.commit().await?;
268+
log::debug!(target: "frontier-sql", "The genesis block information has been submitted.");
258269
}
259270
Some(substrate_genesis_hash)
260271
} else {
@@ -509,7 +520,6 @@ where
509520
});
510521
// https://www.sqlite.org/pragma.html#pragma_optimize
511522
let _ = sqlx::query("PRAGMA optimize").execute(&pool).await;
512-
log::debug!(target: "frontier-sql", "Batch committed");
513523
}
514524

515525
fn get_logs<Client, BE>(
@@ -686,7 +696,7 @@ where
686696
}
687697

688698
/// Retrieve the block hash for the last indexed canon block.
689-
pub async fn get_last_indexed_canon_block(&self) -> Result<H256, Error> {
699+
pub async fn last_indexed_canon_block(&self) -> Result<H256, Error> {
690700
let row = sqlx::query(
691701
"SELECT b.substrate_block_hash FROM blocks AS b
692702
INNER JOIN sync_status AS s
@@ -853,6 +863,21 @@ impl<Block: BlockT<Hash = H256>> fc_api::Backend<Block> for Backend<Block> {
853863
fn log_indexer(&self) -> &dyn fc_api::LogIndexerBackend<Block> {
854864
self
855865
}
866+
867+
async fn best_hash(&self) -> Result<Block::Hash, String> {
868+
// Retrieves the block hash for the latest indexed block, maybe it's not canon.
869+
sqlx::query(
870+
"SELECT b.substrate_block_hash FROM blocks AS b
871+
INNER JOIN sync_status AS s
872+
ON s.substrate_block_hash = b.substrate_block_hash
873+
WHERE s.status = 1
874+
ORDER BY b.block_number DESC LIMIT 1",
875+
)
876+
.fetch_one(self.pool())
877+
.await
878+
.map(|row| H256::from_slice(&row.get::<Vec<u8>, _>(0)[..]))
879+
.map_err(|e| format!("Failed to fetch best hash: {}", e))
880+
}
856881
}
857882

858883
#[async_trait::async_trait]

client/mapping-sync/src/kv/mod.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use crate::{EthereumBlockNotification, EthereumBlockNotificationSinks, SyncStrat
4040
pub fn sync_block<Block: BlockT, C, BE>(
4141
client: &C,
4242
overrides: Arc<OverrideHandle<Block>>,
43-
backend: &fc_db::kv::Backend<Block>,
43+
backend: &fc_db::kv::Backend<Block, C>,
4444
header: &Block::Header,
4545
) -> Result<(), String>
4646
where
@@ -111,11 +111,11 @@ where
111111

112112
pub fn sync_genesis_block<Block: BlockT, C>(
113113
client: &C,
114-
backend: &fc_db::kv::Backend<Block>,
114+
backend: &fc_db::kv::Backend<Block, C>,
115115
header: &Block::Header,
116116
) -> Result<(), String>
117117
where
118-
C: ProvideRuntimeApi<Block>,
118+
C: HeaderBackend<Block> + ProvideRuntimeApi<Block>,
119119
C::Api: EthereumRuntimeRPCApi<Block>,
120120
{
121121
let substrate_block_hash = header.hash();
@@ -159,7 +159,7 @@ pub fn sync_one_block<Block: BlockT, C, BE>(
159159
client: &C,
160160
substrate_backend: &BE,
161161
overrides: Arc<OverrideHandle<Block>>,
162-
frontier_backend: &fc_db::kv::Backend<Block>,
162+
frontier_backend: &fc_db::kv::Backend<Block, C>,
163163
sync_from: <Block::Header as HeaderT>::Number,
164164
strategy: SyncStrategy,
165165
sync_oracle: Arc<dyn SyncOracle + Send + Sync + 'static>,
@@ -248,7 +248,7 @@ pub fn sync_blocks<Block: BlockT, C, BE>(
248248
client: &C,
249249
substrate_backend: &BE,
250250
overrides: Arc<OverrideHandle<Block>>,
251-
frontier_backend: &fc_db::kv::Backend<Block>,
251+
frontier_backend: &fc_db::kv::Backend<Block, C>,
252252
limit: usize,
253253
sync_from: <Block::Header as HeaderT>::Number,
254254
strategy: SyncStrategy,
@@ -282,13 +282,14 @@ where
282282
Ok(synced_any)
283283
}
284284

285-
pub fn fetch_header<Block: BlockT, BE>(
285+
pub fn fetch_header<Block: BlockT, C, BE>(
286286
substrate_backend: &BE,
287-
frontier_backend: &fc_db::kv::Backend<Block>,
287+
frontier_backend: &fc_db::kv::Backend<Block, C>,
288288
checking_tip: Block::Hash,
289289
sync_from: <Block::Header as HeaderT>::Number,
290290
) -> Result<Option<Block::Header>, String>
291291
where
292+
C: HeaderBackend<Block>,
292293
BE: HeaderBackend<Block>,
293294
{
294295
if frontier_backend.mapping().is_synced(&checking_tip)? {

0 commit comments

Comments
 (0)