Statement store (#13701)

* WIP Statement store

* Sync with networking changes in master

* WIP statement pallet

* Statement validation

* pallet tests

* Validation queue

* Store maintenance

* Basic statement refactoring + tests + docs

* Store metrics

* Store tests

* Store maintenance test

* cargo fmt

* Build fix

* OCW Api

* Offchain worker

* Enable host functions

* fmt

* Minor tweaks

* Fixed a warning

* Removed tracing

* Manual expiration

* Reworked constraint management

* Updated pallet constraint calculation

* Added small test

* Added remove function to the APIs

* Copy-paste spec into readme

* Comments

* Made the store optional

* Removed network protocol controller

* fmt

* Clippy fixes

* fmt

* fmt

* More clippy fixes

* More clippy fixes

* More clippy fixes

* Update client/statement-store/README.md

Co-authored-by: cheme <emericchevalier.pro@gmail.com>

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <git@kchr.de>

* Removed sstore from node-template

* Sort out data path

* Added offline check

* Removed dispatch_statement

* Renamed into_generic

* Fixed commit placement

* Use HashSet for tracking peers/statements

* fmt

* Use ExtendedHostFunctions

* Fixed benches

* Tweaks

* Apply suggestions from code review

Co-authored-by: cheme <emericchevalier.pro@gmail.com>

* Fixed priority mixup

* Rename

* newtypes for priorities

* Added MAX_TOPICS

* Fixed key filtering logic

* Remove empty entrie

* Removed prefix from signing

* More documentation

* fmt

* Moved store setup from sc-service to node

* Handle maintenance task in sc-statement-store

* Use statement iterator

* Renamed runtime API mod

* fmt

* Remove dump_encoded

* fmt

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <git@kchr.de>

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <git@kchr.de>

* Fixed build after applying review suggestions

* License exceptions

* fmt

* Store options

* Moved pallet consts to config trait

* Removed global priority

* Validate fields when decoding

* Limit validation channel size

* Made a comment into module doc

* Removed submit_encoded

---------

Co-authored-by: cheme <emericchevalier.pro@gmail.com>
Co-authored-by: Bastian Köcher <git@kchr.de>
This commit is contained in:
Arkadiy Paronyan
2023-05-04 12:24:32 +02:00
committed by GitHub
parent 5a1074712a
commit bfafbf7bac
48 changed files with 3911 additions and 26 deletions
+2
View File
@@ -66,9 +66,11 @@ sc-chain-spec = { version = "4.0.0-dev", path = "../../../client/chain-spec" }
sc-consensus = { version = "0.10.0-dev", path = "../../../client/consensus/common" }
sc-transaction-pool = { version = "4.0.0-dev", path = "../../../client/transaction-pool" }
sc-transaction-pool-api = { version = "4.0.0-dev", path = "../../../client/transaction-pool/api" }
sc-statement-store = { version = "4.0.0-dev", path = "../../../client/statement-store" }
sc-network = { version = "0.10.0-dev", path = "../../../client/network" }
sc-network-common = { version = "0.10.0-dev", path = "../../../client/network/common" }
sc-network-sync = { version = "0.10.0-dev", path = "../../../client/network/sync" }
sc-network-statement = { version = "0.10.0-dev", path = "../../../client/network/statement" }
sc-consensus-slots = { version = "0.10.0-dev", path = "../../../client/consensus/slots" }
sc-consensus-babe = { version = "0.10.0-dev", path = "../../../client/consensus/babe" }
grandpa = { version = "0.10.0-dev", package = "sc-consensus-grandpa", path = "../../../client/consensus/grandpa" }
@@ -104,7 +104,8 @@ fn new_node(tokio_handle: Handle) -> node_cli::service::NewFullBase {
max_runtime_instances: 8,
runtime_cache_size: 2,
announce_block: true,
base_path: Some(base_path),
data_path: base_path.path().into(),
base_path,
informant_output_format: Default::default(),
wasm_runtime_overrides: None,
};
@@ -98,7 +98,8 @@ fn new_node(tokio_handle: Handle) -> node_cli::service::NewFullBase {
max_runtime_instances: 8,
runtime_cache_size: 2,
announce_block: true,
base_path: Some(base_path),
data_path: base_path.path().into(),
base_path,
informant_output_format: Default::default(),
wasm_runtime_overrides: None,
};
+46 -3
View File
@@ -35,6 +35,7 @@ use sc_network::{event::Event, NetworkEventStream, NetworkService};
use sc_network_common::sync::warp::WarpSyncParams;
use sc_network_sync::SyncingService;
use sc_service::{config::Configuration, error::Error as ServiceError, RpcHandlers, TaskManager};
use sc_statement_store::Store as StatementStore;
use sc_telemetry::{Telemetry, TelemetryWorker};
use sp_api::ProvideRuntimeApi;
use sp_core::crypto::Pair;
@@ -148,6 +149,7 @@ pub fn new_partial(
),
grandpa::SharedVoterState,
Option<Telemetry>,
Arc<StatementStore>,
),
>,
ServiceError,
@@ -227,6 +229,15 @@ pub fn new_partial(
let import_setup = (block_import, grandpa_link, babe_link);
let statement_store = sc_statement_store::Store::new_shared(
&config.data_path,
Default::default(),
client.clone(),
config.prometheus_registry(),
&task_manager.spawn_handle(),
)
.map_err(|e| ServiceError::Other(format!("Statement store error: {:?}", e)))?;
let (rpc_extensions_builder, rpc_setup) = {
let (_, grandpa_link, _) = &import_setup;
@@ -247,6 +258,7 @@ pub fn new_partial(
let chain_spec = config.chain_spec.cloned_box();
let rpc_backend = backend.clone();
let rpc_statement_store = statement_store.clone();
let rpc_extensions_builder = move |deny_unsafe, subscription_executor| {
let deps = node_rpc::FullDeps {
client: client.clone(),
@@ -265,6 +277,7 @@ pub fn new_partial(
subscription_executor,
finality_provider: finality_proof_provider.clone(),
},
statement_store: rpc_statement_store.clone(),
};
node_rpc::create_full(deps, rpc_backend.clone()).map_err(Into::into)
@@ -281,7 +294,7 @@ pub fn new_partial(
select_chain,
import_queue,
transaction_pool,
other: (rpc_extensions_builder, import_setup, rpc_setup, telemetry),
other: (rpc_extensions_builder, import_setup, rpc_setup, telemetry, statement_store),
})
}
@@ -325,7 +338,7 @@ pub fn new_full_base(
keystore_container,
select_chain,
transaction_pool,
other: (rpc_builder, import_setup, rpc_setup, mut telemetry),
other: (rpc_builder, import_setup, rpc_setup, mut telemetry, statement_store),
} = new_partial(&config)?;
let shared_voter_state = rpc_setup;
@@ -335,6 +348,16 @@ pub fn new_full_base(
&config.chain_spec,
);
let statement_handler_proto = sc_network_statement::StatementHandlerPrototype::new(
client
.block_hash(0u32.into())
.ok()
.flatten()
.expect("Genesis block exists; qed"),
config.chain_spec.fork_id(),
);
config.network.extra_sets.push(statement_handler_proto.set_config());
config
.network
.extra_sets
@@ -526,7 +549,7 @@ pub fn new_full_base(
sync: Arc::new(sync_service.clone()),
telemetry: telemetry.as_ref().map(|x| x.handle()),
voting_rule: grandpa::VotingRulesBuilder::default().build(),
prometheus_registry,
prometheus_registry: prometheus_registry.clone(),
shared_voter_state,
};
@@ -539,6 +562,26 @@ pub fn new_full_base(
);
}
// Spawn statement protocol worker
let statement_protocol_executor = {
let spawn_handle = task_manager.spawn_handle();
Box::new(move |fut| {
spawn_handle.spawn("network-statement-validator", Some("networking"), fut);
})
};
let statement_handler = statement_handler_proto.build(
network.clone(),
sync_service.clone(),
statement_store.clone(),
prometheus_registry.as_ref(),
statement_protocol_executor,
)?;
task_manager.spawn_handle().spawn(
"network-statement-handler",
Some("networking"),
statement_handler.run(),
);
network_starter.start_network();
Ok(NewFullBase {
task_manager,
+1
View File
@@ -24,6 +24,7 @@ sp-keystore = { version = "0.13.0", path = "../../../primitives/keystore" }
sp-state-machine = { version = "0.13.0", path = "../../../primitives/state-machine" }
sp-tracing = { version = "6.0.0", path = "../../../primitives/tracing" }
sp-trie = { version = "7.0.0", path = "../../../primitives/trie" }
sp-statement-store = { version = "4.0.0-dev", path = "../../../primitives/statement-store" }
[dev-dependencies]
criterion = "0.4.0"
+4 -1
View File
@@ -25,7 +25,10 @@ pub use sc_executor::NativeElseWasmExecutor;
pub struct ExecutorDispatch;
impl sc_executor::NativeExecutionDispatch for ExecutorDispatch {
type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;
type ExtendHostFunctions = (
frame_benchmarking::benchmarking::HostFunctions,
sp_statement_store::runtime_api::HostFunctions,
);
fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {
kitchensink_runtime::api::dispatch(method, data)
+1
View File
@@ -35,5 +35,6 @@ sp-consensus = { version = "0.10.0-dev", path = "../../../primitives/consensus/c
sp-consensus-babe = { version = "0.10.0-dev", path = "../../../primitives/consensus/babe" }
sp-keystore = { version = "0.13.0", path = "../../../primitives/keystore" }
sp-runtime = { version = "7.0.0", path = "../../../primitives/runtime" }
sp-statement-store = { version = "4.0.0-dev", path = "../../../primitives/statement-store" }
substrate-frame-rpc-system = { version = "4.0.0-dev", path = "../../../utils/frame/rpc/system" }
substrate-state-trie-migration-rpc = { version = "4.0.0-dev", path = "../../../utils/frame/rpc/state-trie-migration-rpc/" }
+19 -2
View File
@@ -88,6 +88,8 @@ pub struct FullDeps<C, P, SC, B> {
pub babe: BabeDeps,
/// GRANDPA specific dependencies.
pub grandpa: GrandpaDeps<B>,
/// Shared statement store reference.
pub statement_store: Arc<dyn sp_statement_store::StatementStore>,
}
/// Instantiate all Full RPC extensions.
@@ -118,14 +120,26 @@ where
use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
use sc_consensus_babe_rpc::{Babe, BabeApiServer};
use sc_consensus_grandpa_rpc::{Grandpa, GrandpaApiServer};
use sc_rpc::dev::{Dev, DevApiServer};
use sc_rpc::{
dev::{Dev, DevApiServer},
statement::StatementApiServer,
};
use sc_rpc_spec_v2::chain_spec::{ChainSpec, ChainSpecApiServer};
use sc_sync_state_rpc::{SyncState, SyncStateApiServer};
use substrate_frame_rpc_system::{System, SystemApiServer};
use substrate_state_trie_migration_rpc::{StateMigration, StateMigrationApiServer};
let mut io = RpcModule::new(());
let FullDeps { client, pool, select_chain, chain_spec, deny_unsafe, babe, grandpa } = deps;
let FullDeps {
client,
pool,
select_chain,
chain_spec,
deny_unsafe,
babe,
grandpa,
statement_store,
} = deps;
let BabeDeps { keystore, babe_worker_handle } = babe;
let GrandpaDeps {
@@ -169,6 +183,9 @@ where
io.merge(StateMigration::new(client.clone(), backend, deny_unsafe).into_rpc())?;
io.merge(Dev::new(client, deny_unsafe).into_rpc())?;
let statement_store =
sc_rpc::statement::StatementStore::new(statement_store, deny_unsafe).into_rpc();
io.merge(statement_store)?;
Ok(io)
}
+5
View File
@@ -39,6 +39,7 @@ sp-runtime = { version = "7.0.0", default-features = false, path = "../../../pri
sp-staking = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/staking" }
sp-session = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/session" }
sp-transaction-pool = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/transaction-pool" }
sp-statement-store = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/statement-store" }
sp-version = { version = "5.0.0", default-features = false, path = "../../../primitives/version" }
sp-io = { version = "7.0.0", default-features = false, path = "../../../primitives/io" }
@@ -105,6 +106,7 @@ pallet-staking = { version = "4.0.0-dev", default-features = false, path = "../.
pallet-staking-reward-curve = { version = "4.0.0-dev", default-features = false, path = "../../../frame/staking/reward-curve" }
pallet-staking-runtime-api = { version = "4.0.0-dev", default-features = false, path = "../../../frame/staking/runtime-api" }
pallet-state-trie-migration = { version = "4.0.0-dev", default-features = false, path = "../../../frame/state-trie-migration" }
pallet-statement = { version = "4.0.0-dev", default-features = false, path = "../../../frame/statement" }
pallet-scheduler = { version = "4.0.0-dev", default-features = false, path = "../../../frame/scheduler" }
pallet-society = { version = "4.0.0-dev", default-features = false, path = "../../../frame/society" }
pallet-sudo = { version = "4.0.0-dev", default-features = false, path = "../../../frame/sudo" }
@@ -187,6 +189,7 @@ std = [
"pallet-staking/std",
"pallet-staking-runtime-api/std",
"pallet-state-trie-migration/std",
"pallet-statement/std",
"pallet-salary/std",
"sp-session/std",
"pallet-sudo/std",
@@ -204,6 +207,7 @@ std = [
"pallet-treasury/std",
"pallet-asset-rate/std",
"sp-transaction-pool/std",
"sp-statement-store/std",
"pallet-utility/std",
"sp-version/std",
"pallet-society/std",
@@ -330,6 +334,7 @@ try-runtime = [
"pallet-session/try-runtime",
"pallet-staking/try-runtime",
"pallet-state-trie-migration/try-runtime",
"pallet-statement/try-runtime",
"pallet-scheduler/try-runtime",
"pallet-society/try-runtime",
"pallet-sudo/try-runtime",
+30
View File
@@ -1755,6 +1755,26 @@ impl frame_benchmarking_pallet_pov::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
}
parameter_types! {
pub StatementCost: Balance = 1 * DOLLARS;
pub StatementByteCost: Balance = 100 * MILLICENTS;
pub const MinAllowedStatements: u32 = 4;
pub const MaxAllowedStatements: u32 = 10;
pub const MinAllowedBytes: u32 = 1024;
pub const MaxAllowedBytes: u32 = 4096;
}
impl pallet_statement::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type StatementCost = StatementCost;
type ByteCost = StatementByteCost;
type MinAllowedStatements = MinAllowedStatements;
type MaxAllowedStatements = MaxAllowedStatements;
type MinAllowedBytes = MinAllowedBytes;
type MaxAllowedBytes = MaxAllowedBytes;
}
construct_runtime!(
pub struct Runtime where
Block = Block,
@@ -1826,6 +1846,7 @@ construct_runtime!(
FastUnstake: pallet_fast_unstake,
MessageQueue: pallet_message_queue,
Pov: frame_benchmarking_pallet_pov,
Statement: pallet_statement,
}
);
@@ -2011,6 +2032,15 @@ impl_runtime_apis! {
}
}
impl sp_statement_store::runtime_api::ValidateStatement<Block> for Runtime {
fn validate_statement(
source: sp_statement_store::runtime_api::StatementSource,
statement: sp_statement_store::Statement,
) -> Result<sp_statement_store::runtime_api::ValidStatement, sp_statement_store::runtime_api::InvalidStatement> {
Statement::validate_statement(source, statement)
}
}
impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
fn offchain_worker(header: &<Block as BlockT>::Header) {
Executive::offchain_worker(header)