Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
729e524
WIP Statement store
arkpar Mar 14, 2023
7591d22
Merge branch 'master' of github.com:paritytech/substrate into a-state…
arkpar Mar 15, 2023
ff1edaa
Sync with networking changes in master
arkpar Mar 15, 2023
8407e40
WIP statement pallet
arkpar Mar 15, 2023
21c9aaf
Statement validation
arkpar Mar 16, 2023
c706097
pallet tests
arkpar Mar 16, 2023
e066abe
Validation queue
arkpar Mar 17, 2023
bfbbc5b
Store maintenance
arkpar Mar 20, 2023
d36a867
Merge branch 'master' of github.com:paritytech/substrate into a-state…
arkpar Mar 21, 2023
d610e62
Basic statement refactoring + tests + docs
arkpar Mar 21, 2023
0b73266
Store metrics
arkpar Mar 22, 2023
66b9c98
Store tests
arkpar Mar 22, 2023
c8f0467
Store maintenance test
arkpar Mar 23, 2023
9bc6773
cargo fmt
arkpar Mar 23, 2023
8263aa4
Build fix
arkpar Mar 23, 2023
7779458
OCW Api
arkpar Mar 23, 2023
f01160e
Offchain worker
arkpar Mar 23, 2023
7431f55
Enable host functions
arkpar Mar 23, 2023
5cc24b2
fmt
arkpar Mar 23, 2023
dea2dea
Merge branch 'master' of github.com:paritytech/substrate into a-state…
arkpar Mar 24, 2023
4febbea
Minor tweaks
arkpar Mar 24, 2023
b06e356
Fixed a warning
arkpar Mar 24, 2023
c6f2b53
Removed tracing
arkpar Mar 24, 2023
50b583d
Manual expiration
arkpar Mar 24, 2023
e141eb7
Reworked constraint management
arkpar Mar 28, 2023
c5555e9
Updated pallet constraint calculation
arkpar Mar 28, 2023
1171ba0
Added small test
arkpar Mar 28, 2023
399cbbd
Merge branch 'master' of github.com:paritytech/substrate into a-state…
arkpar Mar 30, 2023
365e5e8
Merge branch 'master' of github.com:paritytech/substrate into a-state…
arkpar Apr 1, 2023
3d571ca
Added remove function to the APIs
arkpar Apr 1, 2023
85a31c9
Copy-paste spec into readme
arkpar Apr 1, 2023
b07775f
Comments
arkpar Apr 1, 2023
659b494
Made the store optional
arkpar Apr 2, 2023
25f3771
Removed network protocol controller
arkpar Apr 2, 2023
27e73cc
fmt
arkpar Apr 3, 2023
39f0145
Merge branch 'master' of github.com:paritytech/substrate into a-state…
arkpar Apr 3, 2023
51b16ff
Merge branch 'master' of github.com:paritytech/substrate into a-state…
arkpar Apr 3, 2023
0e84775
Clippy fixes
arkpar Apr 3, 2023
312a07e
fmt
arkpar Apr 3, 2023
9c21172
fmt
arkpar Apr 3, 2023
0d95b2e
More clippy fixes
arkpar Apr 3, 2023
61f6e5f
More clippy fixes
arkpar Apr 3, 2023
d93493a
More clippy fixes
arkpar Apr 3, 2023
f06ac25
Update client/statement-store/README.md
arkpar Apr 5, 2023
3c2373d
Apply suggestions from code review
arkpar Apr 5, 2023
a13e2c0
Removed sstore from node-template
arkpar Apr 5, 2023
ac499ab
Sort out data path
arkpar Apr 5, 2023
e562b65
Added offline check
arkpar Apr 5, 2023
06f3376
Removed dispatch_statement
arkpar Apr 5, 2023
167c4ad
Renamed into_generic
arkpar Apr 5, 2023
4c840c0
Fixed commit placement
arkpar Apr 5, 2023
03906c8
Use HashSet for tracking peers/statements
arkpar Apr 5, 2023
f33942c
Merge branch 'master' of github.com:paritytech/substrate into a-state…
arkpar Apr 5, 2023
206488d
fmt
arkpar Apr 5, 2023
2625783
Use ExtendedHostFunctions
arkpar Apr 5, 2023
a7f652a
Fixed benches
arkpar Apr 5, 2023
0bf748e
Tweaks
arkpar Apr 5, 2023
8c883a7
Apply suggestions from code review
arkpar Apr 17, 2023
c05e3d7
Merge branch 'master' of github.com:paritytech/substrate into a-state…
arkpar Apr 17, 2023
6c15ce9
Fixed priority mixup
arkpar Apr 17, 2023
f383ab6
Rename
arkpar Apr 17, 2023
a978b2a
newtypes for priorities
arkpar Apr 18, 2023
83f343f
Added MAX_TOPICS
arkpar Apr 18, 2023
94b10a7
Fixed key filtering logic
arkpar Apr 18, 2023
1c22fef
Remove empty entrie
arkpar Apr 18, 2023
f08810b
Removed prefix from signing
arkpar Apr 18, 2023
7849cc8
More documentation
arkpar Apr 18, 2023
64ac7f5
fmt
arkpar Apr 18, 2023
f05f5a3
Merge branch 'master' of github.com:paritytech/substrate into a-state…
arkpar Apr 19, 2023
21dd020
Moved store setup from sc-service to node
arkpar Apr 19, 2023
d72290c
Handle maintenance task in sc-statement-store
arkpar Apr 19, 2023
16e469e
Use statement iterator
arkpar Apr 19, 2023
8d18b5e
Renamed runtime API mod
arkpar Apr 19, 2023
9d3add2
fmt
arkpar Apr 19, 2023
cd7c9dc
Remove dump_encoded
arkpar Apr 19, 2023
d29ebc7
Merge branch 'master' of github.com:paritytech/substrate into a-state…
arkpar Apr 24, 2023
38d893d
fmt
arkpar Apr 24, 2023
fdb43c5
Apply suggestions from code review
arkpar Apr 24, 2023
74e4945
Apply suggestions from code review
arkpar Apr 24, 2023
4f1ac76
Fixed build after applying review suggestions
arkpar Apr 24, 2023
2f2d4f8
License exceptions
arkpar Apr 25, 2023
75ee1bf
fmt
arkpar Apr 25, 2023
b501198
Store options
arkpar Apr 25, 2023
692f58a
Moved pallet consts to config trait
arkpar Apr 25, 2023
704d53a
Removed global priority
arkpar Apr 25, 2023
71b39cf
Validate fields when decoding
arkpar Apr 25, 2023
a798b08
Limit validation channel size
arkpar Apr 25, 2023
7af3b5a
Made a comment into module doc
arkpar Apr 25, 2023
47a8e6b
Removed submit_encoded
arkpar Apr 25, 2023
4fb2aee
Merge branch 'master' of github.com:paritytech/substrate into a-state…
arkpar Apr 25, 2023
df2df2a
Merge branch 'master' of github.com:paritytech/substrate into a-state…
arkpar Apr 25, 2023
f81511d
Merge branch 'master' of github.com:paritytech/substrate into a-state…
arkpar May 3, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
OCW Api
  • Loading branch information
arkpar committed Mar 23, 2023
commit 7779458a4c50bf3057fe35aeff46b6975c65c69a
5 changes: 4 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions bin/node-template/node/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,11 @@ pub fn new_partial(
compatibility_mode: Default::default(),
})?;

let statement_store = Arc::new(sc_statement_store::Store::new(
let statement_store = sc_statement_store::Store::new_shared(
config.database.path().unwrap(),
client.clone(),
config.prometheus_registry(),
)?);
)?;

Ok(sc_service::PartialComponents {
client,
Expand Down
4 changes: 2 additions & 2 deletions bin/node/cli/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,11 @@ pub fn new_partial(
(rpc_extensions_builder, shared_voter_state2)
};

let statement_store = Arc::new(sc_statement_store::Store::new(
let statement_store = sc_statement_store::Store::new_shared(
config.database.path().unwrap(),
client.clone(),
config.prometheus_registry(),
)?);
)?;

Ok(sc_service::PartialComponents {
client,
Expand Down
1 change: 1 addition & 0 deletions client/api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ sp-externalities = { version = "0.13.0", path = "../../primitives/externalities"
sp-keystore = { version = "0.13.0", default-features = false, path = "../../primitives/keystore" }
sp-runtime = { version = "7.0.0", default-features = false, path = "../../primitives/runtime" }
sp-state-machine = { version = "0.13.0", path = "../../primitives/state-machine" }
sp-statement-store = { version = "4.0.0-dev", path = "../../primitives/statement-store" }
sp-storage = { version = "7.0.0", path = "../../primitives/storage" }

[dev-dependencies]
Expand Down
16 changes: 15 additions & 1 deletion client/api/src/execution_extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,15 @@ pub struct ExecutionExtensions<Block: BlockT> {
strategies: ExecutionStrategies,
keystore: Option<KeystorePtr>,
offchain_db: Option<Box<dyn DbExternalitiesFactory>>,
// FIXME: these two are only RwLock because of https://github.com/paritytech/substrate/issues/4587
// FIXME: these three are only RwLock because of https://github.com/paritytech/substrate/issues/4587
// remove when fixed.
// To break retain cycle between `Client` and `TransactionPool` we require this
// extension to be a `Weak` reference.
// That's also the reason why it's being registered lazily instead of
// during initialization.
transaction_pool: RwLock<Option<Weak<dyn OffchainSubmitTransaction<Block>>>>,
extensions_factory: RwLock<Box<dyn ExtensionsFactory<Block>>>,
statement_store: RwLock<Option<Weak<dyn sp_statement_store::StatementStore>>>,
}

impl<Block: BlockT> Default for ExecutionExtensions<Block> {
Expand All @@ -183,6 +184,7 @@ impl<Block: BlockT> Default for ExecutionExtensions<Block> {
offchain_db: None,
transaction_pool: RwLock::new(None),
extensions_factory: RwLock::new(Box::new(())),
statement_store: RwLock::new(None),
}
}
}
Expand All @@ -195,13 +197,15 @@ impl<Block: BlockT> ExecutionExtensions<Block> {
offchain_db: Option<Box<dyn DbExternalitiesFactory>>,
) -> Self {
let transaction_pool = RwLock::new(None);
let statement_store = RwLock::new(None);
let extensions_factory = Box::new(());
Self {
strategies,
keystore,
offchain_db,
extensions_factory: RwLock::new(extensions_factory),
transaction_pool,
statement_store,
}
}

Expand All @@ -223,6 +227,11 @@ impl<Block: BlockT> ExecutionExtensions<Block> {
*self.transaction_pool.write() = Some(Arc::downgrade(pool) as _);
}

/// Register statement store extension.
pub fn register_statement_store(&self, store: Arc<dyn sp_statement_store::StatementStore>) {
*self.statement_store.write() = Some(Arc::downgrade(&store) as _);
}

/// Based on the execution context and capabilities it produces
/// the extensions object to support desired set of APIs.
pub fn extensions(
Expand Down Expand Up @@ -253,6 +262,11 @@ impl<Block: BlockT> ExecutionExtensions<Block> {
}
}

if capabilities.contains(offchain::Capabilities::STATEMENT_STORE) {
if let Some(store) = self.statement_store.read().as_ref().and_then(|x| x.upgrade()) {
extensions.register(sp_statement_store::runtime_api::StatementStoreExt(store));
}
}
if capabilities.contains(offchain::Capabilities::OFFCHAIN_DB_READ) ||
capabilities.contains(offchain::Capabilities::OFFCHAIN_DB_WRITE)
{
Expand Down
4 changes: 1 addition & 3 deletions client/statement-store/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,9 @@ sp-blockchain = { version = "4.0.0-dev", path = "../../primitives/blockchain" }
sp-core = { version = "7.0.0", path = "../../primitives/core" }
sp-runtime = { version = "7.0.0", path = "../../primitives/runtime" }
sp-tracing = { version = "6.0.0", path = "../../primitives/tracing" }
sc-client-api = { version = "4.0.0-dev", path = "../api" }

[dev-dependencies]
tempfile = "3.1.0"
env_logger = "0.9"
#substrate-test-runtime = { version = "2.0.0", path = "../../test-utils/runtime" }
#substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" }
#substrate-test-runtime-transaction-pool = { version = "2.0.0", path = "../../test-utils/runtime/transaction-pool" }

19 changes: 18 additions & 1 deletion client/statement-store/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,24 @@ impl Index {

impl Store {
/// Create a new shared store instance. There should only be one per process.
pub fn new<Block, Client>(
pub fn new_shared<Block, Client>(
path: &std::path::Path,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe some comment on what this path is used for.

client: Arc<Client>,
prometheus: Option<&PrometheusRegistry>,
) -> Result<Arc<Store>>
where
Block: BlockT,
Block::Hash: From<BlockHash>,
Client: ProvideRuntimeApi<Block> + HeaderBackend<Block> + sc_client_api::ExecutorProvider<Block> + Send + Sync + 'static,
Client::Api: ValidateStatement<Block>,
{
let store = Arc::new(Self::new(path, client.clone(), prometheus)?);
client.execution_extensions().register_statement_store(store.clone());
Ok(store)
}

/// Create a new instance.
fn new<Block, Client>(
path: &std::path::Path,
client: Arc<Client>,
prometheus: Option<&PrometheusRegistry>,
Expand Down
12 changes: 2 additions & 10 deletions primitives/core/src/offchain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,16 +278,8 @@ bitflags::bitflags! {
const NODE_AUTHORIZATION = 0b0000_1000_0000;
/// Access time related functionality
const TIME = 0b0001_0000_0000;
}
}

impl Capabilities {
/// Return capabilities for rich offchain calls.
///
/// Those calls should be allowed to sign and submit transactions
/// and access offchain workers database (but read only!).
pub fn rich_offchain_call() -> Self {
Capabilities::TRANSACTION_POOL | Capabilities::KEYSTORE | Capabilities::OFFCHAIN_DB_READ
/// Access the statement store.
const STATEMENT_STORE = 0b0010_0000_0000;
}
}

Expand Down
5 changes: 3 additions & 2 deletions primitives/statement-store/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ sp-core = { version = "7.0.0", default-features = false, path = "../core" }
sp-runtime = { version = "7.0.0", default-features = false, path = "../runtime" }
sp-std = { version = "5.0.0", default-features = false, path = "../std" }
sp-api = { version = "4.0.0-dev", default-features = false, path = "../api" }
sp-io = { version = "7.0.0", default-features = false, path = "../io" }
sp-application-crypto = { version = "7.0.0", default-features = false, path = "../application-crypto" }
sp-runtime-interface = { version = "7.0.0", default-features = false, path = "../runtime-interface" }
sp-externalities = { version = "0.13.0", default-features = false, path = "../externalities" }
thiserror = {version = "1.0", optional = true }
log = { version = "0.4.17", optional = true }

Expand All @@ -31,9 +32,9 @@ std = [
"scale-info/std",
"sp-core/std",
"sp-runtime/std",
"sp-runtime-interface/std",
"sp-std/std",
"sp-api/std",
"sp-io/std",
"sp-application-crypto/std",
"thiserror",
"log",
Expand Down
10 changes: 6 additions & 4 deletions primitives/statement-store/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use codec::{Decode, Encode};
use scale_info::TypeInfo;
use sp_application_crypto::RuntimeAppPublic;
use sp_runtime_interface::pass_by::PassByCodec;
#[cfg(feature = "std")]
use sp_core::Pair;
use sp_std::vec::Vec;
Expand Down Expand Up @@ -76,7 +77,7 @@ pub fn hash_encoded(data: &[u8]) -> [u8; 32] {
}

/// Statement proof.
#[derive(Encode, Decode, TypeInfo, sp_runtime::RuntimeDebug, Clone, PartialEq, Eq)]
#[derive(Encode, Decode, TypeInfo, sp_core::RuntimeDebug, Clone, PartialEq, Eq)]
pub enum Proof {
/// Sr25519 Signature.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would force the index with #[codec(index=0)] for all these encoded enum.
It is not strictly needed, but I d rather have it explicit. But I look at other part of the code and it does not seems like current practice. So just a suggestion.

Sr25519 {
Expand Down Expand Up @@ -110,7 +111,7 @@ pub enum Proof {
},
}

#[derive(Encode, Decode, TypeInfo, sp_runtime::RuntimeDebug, Clone, PartialEq, Eq)]
#[derive(Encode, Decode, TypeInfo, sp_core::RuntimeDebug, Clone, PartialEq, Eq)]
/// Statement attributes. Each statement is a list of 0 or more fields. Fields may only appear in
/// the order declared here.
#[repr(u8)]
Expand All @@ -131,7 +132,7 @@ pub enum Field {
Data(Vec<u8>) = 6,
}

#[derive(TypeInfo, sp_runtime::RuntimeDebug, Clone, PartialEq, Eq, Default)]
#[derive(TypeInfo, sp_core::RuntimeDebug, PassByCodec, Clone, PartialEq, Eq, Default)]
/// Statement structure.
pub struct Statement {
proof: Option<Proof>,
Expand Down Expand Up @@ -296,7 +297,8 @@ impl Statement {
let signature = sp_core::ecdsa::Signature(*signature);
let public = sp_core::ecdsa::Public(*signer);
if signature.verify(to_sign.as_slice(), &public) {
SignatureVerificationResult::Valid(sp_io::hashing::blake2_256(signer))
let sender_hash = <sp_runtime::traits::BlakeTwo256 as sp_core::Hasher>::hash(signer);
SignatureVerificationResult::Valid(sender_hash.into())
} else {
SignatureVerificationResult::Invalid
}
Expand Down
95 changes: 94 additions & 1 deletion primitives/statement-store/src/runtime_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@

//! Runtime support for the statement store.

use crate::Statement;
use crate::{Topic, Statement, Hash};
use codec::{Decode, Encode};
use scale_info::TypeInfo;
use sp_runtime::RuntimeDebug;
use sp_runtime_interface::{runtime_interface, pass_by::PassByEnum};
use sp_externalities::ExternalitiesExt;
use sp_std::vec::Vec;

/// Information concerning a valid statement.
#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)]
Expand Down Expand Up @@ -75,3 +78,93 @@ sp_api::decl_runtime_apis! {
) -> Result<ValidStatement, InvalidStatement>;
}
}

#[cfg(feature = "std")]
sp_externalities::decl_extension! {
/// The offchain database extension that will be registered at the Substrate externalities.
pub struct StatementStoreExt(std::sync::Arc<dyn crate::StatementStore>);
}

#[cfg(feature = "std")]
/// Host extensions for the runtime.
impl StatementStoreExt {
/// Create new instance of externalities extensions.
pub fn new(store: std::sync::Arc<dyn crate::StatementStore>) -> Self {
Self(store)
}
}

#[derive(Debug, Eq, PartialEq, Clone, Copy, Encode, Decode, PassByEnum)]
/// Submission result.
pub enum SubmitResult {
/// Accepted as new.
OkNew,
/// Known statement
OkKnown,
/// Statement failed validation.
Bad,
/// The store is not available.
NotAvailable,
}

/// Host interface
#[runtime_interface]
pub trait Io {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub trait Io {
pub trait StatementStore {

The name is used as part of the host functions and Io is not expressive enough.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't it also use the name of the containing module?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

/// Submit a new new statement. The statement will be broadcast to the network.
/// This is meant to be used by the offchain worker.
fn submit_statement(&mut self, statement: Statement) -> SubmitResult {
if let Some(StatementStoreExt(store)) = self.extension::<StatementStoreExt>() {
match store.submit(statement, StatementSource::Chain) {
crate::SubmitResult::New(_) => SubmitResult::OkNew,
crate::SubmitResult::Known => SubmitResult::OkKnown,
// This should not happen for `StatementSource::Chain`. An existing statement will be
// overwritten.
crate::SubmitResult::KnownExpired => SubmitResult::Bad,
crate::SubmitResult::Bad(_) => SubmitResult::Bad,
crate::SubmitResult::InternalError(_) => SubmitResult::Bad,
}
} else {
SubmitResult::NotAvailable
}
}

/// Return all statements.
fn dump(&mut self) -> Vec<(Hash, Statement)> {
if let Some(StatementStoreExt(store)) = self.extension::<StatementStoreExt>() {
store.dump().unwrap_or_default()
} else {
Vec::default()
}
}

/// Return the data of all known statements which include all topics and have no `DecryptionKey`
/// field.
fn broadcasts(&mut self, match_all_topics: &[Topic]) -> Vec<Vec<u8>> {
if let Some(StatementStoreExt(store)) = self.extension::<StatementStoreExt>() {
store.broadcasts(match_all_topics).unwrap_or_default()
} else {
Vec::default()
}
}

/// Return the data of all known statements whose decryption key is identified as `dest` (this
/// will generally be the public key or a hash thereof for symmetric ciphers, or a hash of the
/// private key for symmetric ciphers).
fn posted(&mut self, match_all_topics: &[Topic], dest: [u8; 32]) -> Vec<Vec<u8>> {
if let Some(StatementStoreExt(store)) = self.extension::<StatementStoreExt>() {
store.posted(match_all_topics, dest).unwrap_or_default()
} else {
Vec::default()
}
}

/// Return the decrypted data of all known statements whose decryption key is identified as
/// `dest`. The key must be available to the client.
fn posted_clear(&mut self, match_all_topics: &[Topic], dest: [u8; 32]) -> Vec<Vec<u8>> {
if let Some(StatementStoreExt(store)) = self.extension::<StatementStoreExt>() {
store.posted_clear(match_all_topics, dest).unwrap_or_default()
} else {
Vec::default()
}
}
}