Skip to content

Commit 681f7c3

Browse files
insipxdvdplm
andauthored
General Cargo docs, wip (#432)
* update substrate to latest, document backend portion Signed-off-by: Andrew Plaza <aplaza@liquidthink.net> * update schema * document sa-work-queue * bring up to date with latest substrate master * more general docs for archive * language * fmt * Update substrate-archive-backend/src/frontend/client.rs Co-authored-by: David <dvdplm@gmail.com> * fix tests Co-authored-by: David <dvdplm@gmail.com>
1 parent b5ee4d6 commit 681f7c3

File tree

22 files changed

+1445
-1221
lines changed

22 files changed

+1445
-1221
lines changed

Cargo.lock

Lines changed: 1235 additions & 1117 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

SubstrateArchiveSchema.pdf

21.2 KB
Binary file not shown.

SubstrateArchiveSchema.png

17.1 KB
Loading

examples/simple.rs

Lines changed: 0 additions & 27 deletions
This file was deleted.

substrate-archive-backend/src/database.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with substrate-archive. If not, see <http://www.gnu.org/licenses/>.
1616

17-
//! Custom Read-Only Database Instance using RocksDB Secondary features
18-
//! Will try catching up with primary database on every `get()`
17+
//! Custom Read-Only Database Instance using RocksDB Secondary features.
18+
//! Will try catching up with primary database on every `get()`.
1919
2020
use std::{collections::HashMap, fmt, io, path::PathBuf};
2121

@@ -28,7 +28,9 @@ const NUM_COLUMNS: u32 = 11;
2828

2929
pub type KeyValuePair = (Box<[u8]>, Box<[u8]>);
3030

31-
// Archive specific K/V database reader implementation
31+
/// Archive specific K/V database reader implementation.
32+
/// Any backend database similiar to RocksDB (e.g ParityDb)
33+
/// should implement this trait in order to be used with archive.
3234
pub trait ReadOnlyDb: Send + Sync {
3335
/// Read key/value pairs from the database
3436
fn get(&self, col: u32, key: &[u8]) -> Option<Vec<u8>>;

substrate-archive-backend/src/frontend.rs

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ mod client;
1818

1919
use serde::Deserialize;
2020
use std::{
21-
collections::HashMap,
21+
collections::{BTreeMap, HashMap},
2222
convert::{TryFrom, TryInto},
2323
path::PathBuf,
2424
str::FromStr,
@@ -33,9 +33,7 @@ use sc_executor::{WasmExecutionMethod, WasmExecutor};
3333
use sc_service::{ChainSpec, ClientConfig, LocalCallExecutor, TransactionStorageMode};
3434
use sp_api::ConstructRuntimeApi;
3535
use sp_core::traits::SpawnNamed;
36-
use sp_runtime::traits::{BlakeTwo256, Block as BlockT};
37-
use sp_wasm_interface::Function;
38-
use sp_wasm_interface::HostFunctions;
36+
use sp_runtime::traits::{BlakeTwo256, Block as BlockT, NumberFor};
3937

4038
pub use self::client::{Client, GetMetadata};
4139
use crate::{database::ReadOnlyDb, error::BackendError, read_only_backend::ReadOnlyBackend, RuntimeApiCollection};
@@ -44,7 +42,8 @@ use crate::{database::ReadOnlyDb, error::BackendError, read_only_backend::ReadOn
4442
pub type TArchiveClient<TBl, TRtApi, D> = Client<TFullCallExecutor<TBl, D>, TBl, TRtApi, D>;
4543

4644
/// Full client call executor type.
47-
type TFullCallExecutor<TBl, D> = LocalCallExecutor<TBl, ReadOnlyBackend<TBl, D>, WasmExecutor>;
45+
type TFullCallExecutor<TBl, D> =
46+
LocalCallExecutor<TBl, ReadOnlyBackend<TBl, D>, WasmExecutor<sp_io::SubstrateHostFunctions>>;
4847

4948
#[derive(Copy, Clone, Debug, Deserialize)]
5049
pub enum ExecutionMethod {
@@ -67,6 +66,8 @@ impl From<ExecutionMethod> for WasmExecutionMethod {
6766
}
6867
}
6968

69+
/// Configuration controls how Archive executes blocks in `execute_block`
70+
/// (in tasks.rs in `substrate-archive/`).
7071
#[derive(Clone, Debug, Deserialize)]
7172
pub struct RuntimeConfig {
7273
/// How to execute the runtime code: interpreted (default) or JIT compiled.
@@ -85,7 +86,7 @@ pub struct RuntimeConfig {
8586
/// are included in the chain_spec and primarily for fixing problematic on-chain wasm.
8687
/// If both are in use, the `wasm_runtime_overrides` takes precedence.
8788
#[serde(skip)]
88-
code_substitutes: HashMap<String, Vec<u8>>,
89+
code_substitutes: BTreeMap<String, Vec<u8>>,
8990
/// Method of storing and retrieving transactions(extrinsics).
9091
#[serde(skip, default = "default_storage_mode")]
9192
pub storage_mode: TransactionStorageMode,
@@ -123,36 +124,41 @@ const fn default_storage_mode() -> TransactionStorageMode {
123124
impl<B> TryFrom<RuntimeConfig> for ClientConfig<B>
124125
where
125126
B: BlockT,
126-
B::Hash: FromStr,
127127
{
128128
type Error = BackendError;
129129
fn try_from(config: RuntimeConfig) -> Result<ClientConfig<B>, BackendError> {
130130
let wasm_runtime_substitutes = config
131131
.code_substitutes
132132
.into_iter()
133-
.map(|(hash, code)| {
134-
let hash = B::Hash::from_str(&hash).map_err(|_| {
135-
BackendError::Msg(format!("Failed to parse `{}` as block hash for code substitute.", hash))
133+
.map(|(n, code)| {
134+
let number = NumberFor::<B>::from_str(&n).map_err(|_| {
135+
BackendError::Msg(format!(
136+
"Failed to parse `{}` as block number for code substitutes. \
137+
In an old version the key for code substitute was a block hash. \
138+
Please update the chain spec to a version that is compatible with your node.",
139+
n
140+
))
136141
})?;
137-
Ok((hash, code))
142+
Ok((number, code))
138143
})
139-
.collect::<Result<HashMap<B::Hash, Vec<u8>>, BackendError>>()?;
144+
.collect::<Result<HashMap<_, _>, BackendError>>()?;
140145

141146
Ok(ClientConfig {
142147
offchain_worker_enabled: false,
143148
offchain_indexing_api: false,
144149
wasm_runtime_overrides: config.wasm_runtime_overrides,
145-
wasm_runtime_substitutes,
146150
// we do not support 'no_genesis', so this value is inconsiquential
147151
no_genesis: false,
152+
wasm_runtime_substitutes,
148153
})
149154
}
150155
}
151156

157+
/// Main entry to initialize the substrate-archive backend client, used to
158+
/// call into the runtime of the network being indexed (e.g to execute blocks).
152159
pub fn runtime_api<Block, Runtime, D: ReadOnlyDb + 'static>(
153160
config: RuntimeConfig,
154161
backend: Arc<ReadOnlyBackend<Block, D>>,
155-
host_functions: Option<Vec<&'static dyn Function>>,
156162
task_executor: impl SpawnNamed + 'static,
157163
) -> Result<TArchiveClient<Block, Runtime, D>, BackendError>
158164
where
@@ -165,11 +171,13 @@ where
165171
+ 'static,
166172
<Runtime::RuntimeApi as sp_api::ApiExt<Block>>::StateBackend: sp_api::StateBackend<BlakeTwo256>,
167173
{
168-
let host_functions =
169-
if let Some(funcs) = host_functions { funcs } else { sp_io::SubstrateHostFunctions::host_functions() };
170-
171-
let executor =
172-
WasmExecutor::new(config.exec_method.into(), config.wasm_pages, host_functions, config.block_workers, None);
174+
let executor = WasmExecutor::<sp_io::SubstrateHostFunctions>::new(
175+
config.exec_method.into(),
176+
config.wasm_pages,
177+
config.block_workers,
178+
None,
179+
128,
180+
);
173181
let executor = LocalCallExecutor::new(backend.clone(), executor, Box::new(task_executor), config.try_into()?)?;
174182
let client = Client::new(backend, executor, ExecutionExtensions::new(execution_strategies(), None, None))?;
175183
Ok(client)

substrate-archive-backend/src/frontend/client.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with substrate-archive. If not, see <http://www.gnu.org/licenses/>.
1616

17-
//! Custom implementation of a Client for Archival use
17+
//! Custom implementation of a Client for Archival use.
18+
//! This client resembles the client in `client/service/src/client` except that it uses a read-only rocksdb
19+
//! database implementation, and that the backend state trie aims at avoid caching as much as possible, unlike the normal substrate client.
20+
//! (Substrate Archive generally does not expect to access values multiple times during a run).
1821
//! Implements Runtime API's
1922
//! Read-Only Access
20-
//! The Archive Client and it's backend are decoupled
2123
//! It's recommended to use the backend (ReadOnlyBackend) for anything that requires getting blocks, querying
22-
//! storage, or similar operations. Client usage should be reserved for calling into the Runtime
24+
//! storage, or similar operations. Client usage should be reserved for calling into the Runtime.
2325
2426
use std::{marker::PhantomData, panic::UnwindSafe, sync::Arc};
2527

substrate-archive-backend/src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,21 @@
1515
// along with substrate-archive. If not, see <http://www.gnu.org/licenses/>.
1616

1717
//! Read Only Interface with Substrate Backend (kvdb-rocksdb)
18+
//! Structs and traits in this module generally follow those defined in substrate.
19+
//! They only differentiate insofar as the use of a read-only Secondary RocksDB Database.
20+
//! Therefore some methods (like block importing) are not useful to us and left as stubs (generally with a warn! log).
21+
//! We need to implement substrate database traits in order to satisfy the requirements for using a client.
22+
//! We need a client implementation in order to access functions in a FRAME runtime (like block execution)
23+
//! to allow for faster indexing.
24+
//! These traits are:
25+
//! [`Backend`](https://paritytech.github.io/substrate/master/sc_client_api/backend/trait.Backend.html)
26+
//! [`BlockBackend`](https://paritytech.github.io/substrate/master/sp_blockchain/trait.Backend.html)
27+
//! [`AuxStore`](https://paritytech.github.io/substrate/master/sc_client_api/backend/trait.AuxStore.html)
28+
//! [`OffchainStorage`](https://paritytech.github.io/substrate/master/sp_core/offchain/trait.OffchainStorage.html)
29+
//! [`BlockImportOperation`](https://paritytech.github.io/substrate/master/sc_client_db/struct.BlockImportOperation.html)
30+
//!
31+
//! the trait [`StateBackend`](https://paritytech.github.io/substrate/master/sc_client_api/backend/trait.StateBackend.html)
32+
//! is implemented on a trimmed-down [`TrieState`] type and used in the archive client.
1833
1934
#![forbid(unsafe_code)]
2035
#![deny(dead_code)]

substrate-archive-backend/src/read_only_backend/blockchain_backend.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with substrate-archive. If not, see <http://www.gnu.org/licenses/>.
1616

17-
//! Implements Blockchain Backend (and required associated traits) for ReadOnlyBackend type
17+
//! Implements Blockchain Backend (and required associated traits) for ReadOnlyBackend type.
1818
1919
use codec::{Decode, Encode};
2020

substrate-archive-backend/src/read_only_backend/misc_backend.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use sp_blockchain::{well_known_cache_keys::Id, Error as BlockchainError};
2626
use sp_core::offchain::OffchainStorage;
2727
use sp_runtime::{generic::BlockId, traits::Block as BlockT, Justification, Justifications};
2828
use sp_state_machine::{ChildStorageCollection, IndexOperation, StorageCollection};
29-
use sp_storage::Storage;
29+
use sp_storage::{StateVersion, Storage};
3030

3131
use crate::{database::ReadOnlyDb, read_only_backend::ReadOnlyBackend, util::columns};
3232

@@ -67,12 +67,17 @@ impl<Block: BlockT, D: ReadOnlyDb> BlockImportOperation<Block> for RealBlockImpo
6767
Ok(())
6868
}
6969

70-
fn set_genesis_state(&mut self, _storage: Storage, _commit: bool) -> sp_blockchain::Result<Block::Hash> {
70+
fn set_genesis_state(
71+
&mut self,
72+
_storage: Storage,
73+
_commit: bool,
74+
_: StateVersion,
75+
) -> sp_blockchain::Result<Block::Hash> {
7176
log::warn!("Cannot set state of a read only backend. Genesis not set");
7277
Ok(Default::default())
7378
}
7479

75-
fn reset_storage(&mut self, _reset: Storage) -> ChainResult<Block::Hash> {
80+
fn reset_storage(&mut self, _reset: Storage, _: StateVersion) -> ChainResult<Block::Hash> {
7681
log::warn!("Cannot modify storage of a read only backend. Storage not reset.");
7782
Ok(Default::default())
7883
}

0 commit comments

Comments
 (0)