Skip to content

feat(katana): getStorageProof endpoint #2809

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
674 changes: 353 additions & 321 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -277,3 +277,8 @@ starknet-crypto = "0.7.1"
starknet-types-core = { version = "0.1.7", features = [ "arbitrary", "hash" ] }

bitvec = "1.0.1"

# macro
proc-macro2 = "1.0"
quote = "1.0"
syn = { version = "2.0", default-features = false }
39 changes: 15 additions & 24 deletions crates/katana/core/src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use katana_primitives::state::{compute_state_diff_hash, StateUpdates};
use katana_primitives::transaction::{TxHash, TxWithHash};
use katana_primitives::Felt;
use katana_provider::traits::block::{BlockHashProvider, BlockWriter};
use katana_provider::traits::trie::{ClassTrieWriter, ContractTrieWriter};
use katana_provider::traits::trie::TrieWriter;
use katana_trie::compute_merkle_root;
use parking_lot::RwLock;
use starknet::macros::short_string;
Expand Down Expand Up @@ -158,29 +158,23 @@ impl<EF: ExecutorFactory> Backend<EF> {
}

#[derive(Debug, Clone)]
pub struct UncommittedBlock<'a, P>
where
P: ClassTrieWriter + ContractTrieWriter,
{
pub struct UncommittedBlock<'a, P: TrieWriter> {
header: PartialHeader,
transactions: Vec<TxWithHash>,
receipts: &'a [ReceiptWithTxHash],
state_updates: &'a StateUpdates,
trie_provider: P,
provider: P,
}

impl<'a, P> UncommittedBlock<'a, P>
where
P: ClassTrieWriter + ContractTrieWriter,
{
impl<'a, P: TrieWriter> UncommittedBlock<'a, P> {
pub fn new(
header: PartialHeader,
transactions: Vec<TxWithHash>,
receipts: &'a [ReceiptWithTxHash],
state_updates: &'a StateUpdates,
trie_provider: P,
) -> Self {
Self { header, transactions, receipts, state_updates, trie_provider }
Self { header, transactions, receipts, state_updates, provider: trie_provider }
}

pub fn commit(self) -> SealedBlock {
Expand Down Expand Up @@ -258,19 +252,16 @@ where

// state_commitment = hPos("STARKNET_STATE_V0", contract_trie_root, class_trie_root)
fn compute_new_state_root(&self) -> Felt {
let class_trie_root = ClassTrieWriter::insert_updates(
&self.trie_provider,
self.header.number,
&self.state_updates.declared_classes,
)
.unwrap();

let contract_trie_root = ContractTrieWriter::insert_updates(
&self.trie_provider,
self.header.number,
self.state_updates,
)
.unwrap();
println!("ohayo im committing now");
let class_trie_root = self
.provider
.trie_insert_declared_classes(self.header.number, &self.state_updates.declared_classes)
.expect("failed to update class trie");

let contract_trie_root = self
.provider
.trie_insert_contract_updates(self.header.number, self.state_updates)
.expect("failed to update contract trie");

hash::Poseidon::hash_array(&[
short_string!("STARKNET_STATE_V0"),
Expand Down
12 changes: 4 additions & 8 deletions crates/katana/core/src/backend/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ use katana_provider::traits::block::{BlockProvider, BlockWriter};
use katana_provider::traits::contract::{ContractClassWriter, ContractClassWriterExt};
use katana_provider::traits::env::BlockEnvProvider;
use katana_provider::traits::stage::StageCheckpointProvider;
use katana_provider::traits::state::{StateFactoryProvider, StateRootProvider, StateWriter};
use katana_provider::traits::state::{StateFactoryProvider, StateWriter};
use katana_provider::traits::state_update::StateUpdateProvider;
use katana_provider::traits::transaction::{
ReceiptProvider, TransactionProvider, TransactionStatusProvider, TransactionTraceProvider,
TransactionsProviderExt,
};
use katana_provider::traits::trie::{ClassTrieWriter, ContractTrieWriter};
use katana_provider::traits::trie::TrieWriter;
use katana_provider::BlockchainProvider;
use num_traits::ToPrimitive;
use starknet::core::types::{BlockStatus, MaybePendingBlockWithTxHashes};
Expand All @@ -40,14 +40,12 @@ pub trait Database:
+ TransactionsProviderExt
+ ReceiptProvider
+ StateUpdateProvider
+ StateRootProvider
+ StateWriter
+ ContractClassWriter
+ ContractClassWriterExt
+ StateFactoryProvider
+ BlockEnvProvider
+ ClassTrieWriter
+ ContractTrieWriter
+ TrieWriter
+ StageCheckpointProvider
+ 'static
+ Send
Expand All @@ -65,14 +63,12 @@ impl<T> Database for T where
+ TransactionsProviderExt
+ ReceiptProvider
+ StateUpdateProvider
+ StateRootProvider
+ StateWriter
+ ContractClassWriter
+ ContractClassWriterExt
+ StateFactoryProvider
+ BlockEnvProvider
+ ClassTrieWriter
+ ContractTrieWriter
+ TrieWriter
+ StageCheckpointProvider
+ 'static
+ Send
Expand Down
1 change: 1 addition & 0 deletions crates/katana/executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ version.workspace = true
[dependencies]
katana-primitives.workspace = true
katana-provider.workspace = true
katana-trie.workspace = true

parking_lot = { workspace = true, optional = true }
starknet = { workspace = true, optional = true }
Expand Down
35 changes: 34 additions & 1 deletion crates/katana/executor/src/abstraction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
use katana_primitives::transaction::TxWithHash;
use katana_primitives::Felt;
use katana_provider::traits::contract::ContractClassProvider;
use katana_provider::traits::state::StateProvider;
use katana_provider::traits::state::{StateProofProvider, StateProvider, StateRootProvider};
use katana_provider::ProviderResult;
use katana_trie::MultiProof;

pub type ExecutorResult<T> = Result<T, error::ExecutorError>;

Expand Down Expand Up @@ -204,3 +205,35 @@
self.0.storage(address, storage_key)
}
}

impl<'a> StateProofProvider for StateProviderDb<'a> {
fn class_multiproof(&self, classes: Vec<ClassHash>) -> ProviderResult<MultiProof> {
self.0.class_multiproof(classes)
}

Check warning on line 212 in crates/katana/executor/src/abstraction/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/executor/src/abstraction/mod.rs#L210-L212

Added lines #L210 - L212 were not covered by tests

fn contract_multiproof(&self, addresses: Vec<ContractAddress>) -> ProviderResult<MultiProof> {
self.0.contract_multiproof(addresses)
}

Check warning on line 216 in crates/katana/executor/src/abstraction/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/executor/src/abstraction/mod.rs#L214-L216

Added lines #L214 - L216 were not covered by tests

fn storage_multiproof(
&self,
address: ContractAddress,
key: Vec<StorageKey>,
) -> ProviderResult<MultiProof> {
self.0.storage_multiproof(address, key)
}

Check warning on line 224 in crates/katana/executor/src/abstraction/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/executor/src/abstraction/mod.rs#L218-L224

Added lines #L218 - L224 were not covered by tests
}

impl<'a> StateRootProvider for StateProviderDb<'a> {
fn classes_root(&self) -> ProviderResult<Felt> {
self.0.classes_root()
}

Check warning on line 230 in crates/katana/executor/src/abstraction/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/executor/src/abstraction/mod.rs#L228-L230

Added lines #L228 - L230 were not covered by tests

fn contracts_root(&self) -> ProviderResult<Felt> {
self.0.contracts_root()
}

Check warning on line 234 in crates/katana/executor/src/abstraction/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/executor/src/abstraction/mod.rs#L232-L234

Added lines #L232 - L234 were not covered by tests

fn state_root(&self) -> ProviderResult<Felt> {
self.0.state_root()
}

Check warning on line 238 in crates/katana/executor/src/abstraction/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/executor/src/abstraction/mod.rs#L236-L238

Added lines #L236 - L238 were not covered by tests
}
40 changes: 39 additions & 1 deletion crates/katana/executor/src/implementation/blockifier/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use katana_primitives::Felt;
use katana_provider::error::ProviderError;
use katana_provider::traits::contract::ContractClassProvider;
use katana_provider::traits::state::StateProvider;
use katana_provider::traits::state::{StateProofProvider, StateProvider, StateRootProvider};
use katana_provider::ProviderResult;
use parking_lot::Mutex;

Expand Down Expand Up @@ -238,6 +238,44 @@
}
}

impl<S: StateDb> StateProofProvider for CachedState<S> {
fn class_multiproof(
&self,
classes: Vec<class::ClassHash>,
) -> ProviderResult<katana_trie::MultiProof> {
let _ = classes;
unimplemented!("not supported in executor's state")

Check warning on line 247 in crates/katana/executor/src/implementation/blockifier/state.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/executor/src/implementation/blockifier/state.rs#L242-L247

Added lines #L242 - L247 were not covered by tests
}

fn contract_multiproof(
&self,
addresses: Vec<katana_primitives::ContractAddress>,
) -> ProviderResult<katana_trie::MultiProof> {
let _ = addresses;
unimplemented!("not supported in executor's state")

Check warning on line 255 in crates/katana/executor/src/implementation/blockifier/state.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/executor/src/implementation/blockifier/state.rs#L250-L255

Added lines #L250 - L255 were not covered by tests
}

fn storage_multiproof(
&self,
address: katana_primitives::ContractAddress,
key: Vec<katana_primitives::contract::StorageKey>,
) -> ProviderResult<katana_trie::MultiProof> {
let _ = address;
let _ = key;
unimplemented!("not supported in executor's state")

Check warning on line 265 in crates/katana/executor/src/implementation/blockifier/state.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/executor/src/implementation/blockifier/state.rs#L258-L265

Added lines #L258 - L265 were not covered by tests
}
}

impl<S: StateDb> StateRootProvider for CachedState<S> {
fn classes_root(&self) -> ProviderResult<Felt> {
unimplemented!("not supported in executor's state")

Check warning on line 271 in crates/katana/executor/src/implementation/blockifier/state.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/executor/src/implementation/blockifier/state.rs#L270-L271

Added lines #L270 - L271 were not covered by tests
}

fn contracts_root(&self) -> ProviderResult<Felt> {
unimplemented!("not supported in executor's state")

Check warning on line 275 in crates/katana/executor/src/implementation/blockifier/state.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/executor/src/implementation/blockifier/state.rs#L274-L275

Added lines #L274 - L275 were not covered by tests
}
}

#[cfg(test)]
mod tests {

Expand Down
37 changes: 36 additions & 1 deletion crates/katana/executor/src/implementation/noop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use katana_primitives::transaction::{ExecutableTxWithHash, TxWithHash};
use katana_primitives::Felt;
use katana_provider::traits::contract::ContractClassProvider;
use katana_provider::traits::state::StateProvider;
use katana_provider::traits::state::{StateProofProvider, StateProvider, StateRootProvider};
use katana_provider::ProviderResult;

use crate::abstraction::{
Expand Down Expand Up @@ -170,3 +170,38 @@
Ok(None)
}
}

impl StateProofProvider for NoopStateProvider {
fn class_multiproof(&self, classes: Vec<ClassHash>) -> ProviderResult<katana_trie::MultiProof> {
let _ = classes;
Ok(katana_trie::MultiProof(Default::default()))
}

Check warning on line 178 in crates/katana/executor/src/implementation/noop.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/executor/src/implementation/noop.rs#L175-L178

Added lines #L175 - L178 were not covered by tests

fn contract_multiproof(
&self,
addresses: Vec<ContractAddress>,
) -> ProviderResult<katana_trie::MultiProof> {
let _ = addresses;
Ok(katana_trie::MultiProof(Default::default()))
}

Check warning on line 186 in crates/katana/executor/src/implementation/noop.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/executor/src/implementation/noop.rs#L180-L186

Added lines #L180 - L186 were not covered by tests

fn storage_multiproof(
&self,
address: ContractAddress,
key: Vec<StorageKey>,
) -> ProviderResult<katana_trie::MultiProof> {
let _ = address;
let _ = key;
Ok(katana_trie::MultiProof(Default::default()))
}

Check warning on line 196 in crates/katana/executor/src/implementation/noop.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/executor/src/implementation/noop.rs#L188-L196

Added lines #L188 - L196 were not covered by tests
}

impl StateRootProvider for NoopStateProvider {
fn classes_root(&self) -> ProviderResult<Felt> {
Ok(Felt::ZERO)
}

Check warning on line 202 in crates/katana/executor/src/implementation/noop.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/executor/src/implementation/noop.rs#L200-L202

Added lines #L200 - L202 were not covered by tests

fn contracts_root(&self) -> ProviderResult<Felt> {
Ok(Felt::ZERO)
}

Check warning on line 206 in crates/katana/executor/src/implementation/noop.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/executor/src/implementation/noop.rs#L204-L206

Added lines #L204 - L206 were not covered by tests
}
1 change: 1 addition & 0 deletions crates/katana/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ pub mod utils;
pub use contract::ContractAddress;
pub use starknet::macros::felt;
pub use starknet_types_core::felt::{Felt, FromStrError};
pub use starknet_types_core::hash;
16 changes: 15 additions & 1 deletion crates/katana/rpc/rpc-api/src/starknet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
use jsonrpsee::core::RpcResult;
use jsonrpsee::proc_macros::rpc;
use katana_primitives::block::{BlockIdOrTag, BlockNumber};
use katana_primitives::class::ClassHash;
use katana_primitives::transaction::TxHash;
use katana_primitives::Felt;
use katana_primitives::{ContractAddress, Felt};
use katana_rpc_types::block::{
BlockHashAndNumber, BlockTxCount, MaybePendingBlockWithReceipts, MaybePendingBlockWithTxHashes,
MaybePendingBlockWithTxs,
Expand All @@ -18,6 +19,7 @@ use katana_rpc_types::transaction::{
BroadcastedDeclareTx, BroadcastedDeployAccountTx, BroadcastedInvokeTx, BroadcastedTx,
DeclareTxResult, DeployAccountTxResult, InvokeTxResult, Tx,
};
use katana_rpc_types::trie::{ContractStorageKeys, GetStorageProofResponse};
use katana_rpc_types::{
FeeEstimate, FeltAsHex, FunctionCall, SimulationFlag, SimulationFlagForEstimateFee,
SyncingStatus,
Expand Down Expand Up @@ -183,6 +185,18 @@ pub trait StarknetApi {
block_id: BlockIdOrTag,
contract_address: Felt,
) -> RpcResult<FeltAsHex>;

/// Get merkle paths in one of the state tries: global state, classes, individual contract. A
/// single request can query for any mix of the three types of storage proofs (classes,
/// contracts, and storage).
#[method(name = "getStorageProof")]
async fn get_storage_proof(
&self,
block_id: BlockIdOrTag,
class_hashes: Option<Vec<ClassHash>>,
contract_addresses: Option<Vec<ContractAddress>>,
contracts_storage_keys: Option<Vec<ContractStorageKeys>>,
) -> RpcResult<GetStorageProofResponse>;
}

/// Write API.
Expand Down
19 changes: 13 additions & 6 deletions crates/katana/rpc/rpc-types-builder/src/state_update.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use katana_primitives::block::BlockHashOrNumber;
use katana_primitives::Felt;
use katana_provider::traits::block::{BlockHashProvider, BlockNumberProvider};
use katana_provider::traits::state::StateRootProvider;
use katana_provider::traits::state::{StateFactoryProvider, StateRootProvider};
use katana_provider::traits::state_update::StateUpdateProvider;
use katana_provider::ProviderResult;
use katana_rpc_types::state_update::{StateDiff, StateUpdate};
Expand All @@ -21,7 +21,7 @@

impl<P> StateUpdateBuilder<P>
where
P: BlockHashProvider + BlockNumberProvider + StateRootProvider + StateUpdateProvider,
P: BlockHashProvider + BlockNumberProvider + StateFactoryProvider + StateUpdateProvider,
{
/// Builds a state update for the given block.
pub fn build(self) -> ProviderResult<Option<StateUpdate>> {
Expand All @@ -30,16 +30,23 @@
return Ok(None);
};

let new_root = StateRootProvider::state_root(&self.provider, self.block_id)?
.expect("should exist if block exists");
let new_root = self
.provider
.historical(self.block_id)?
.expect("should exist if block exists")
.state_root()?;

Check warning on line 37 in crates/katana/rpc/rpc-types-builder/src/state_update.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/rpc/rpc-types-builder/src/state_update.rs#L33-L37

Added lines #L33 - L37 were not covered by tests

let old_root = {
let block_num = BlockNumberProvider::block_number_by_hash(&self.provider, block_hash)?
.expect("should exist if block exists");

match block_num {
0 => Felt::ZERO,
_ => StateRootProvider::state_root(&self.provider, (block_num - 1).into())?
.expect("should exist if not genesis"),
_ => self
.provider
.historical((block_num - 1).into())?
.expect("should exist if block exists")
.state_root()?,

Check warning on line 49 in crates/katana/rpc/rpc-types-builder/src/state_update.rs

View check run for this annotation

Codecov / codecov/patch

crates/katana/rpc/rpc-types-builder/src/state_update.rs#L45-L49

Added lines #L45 - L49 were not covered by tests
}
};

Expand Down
1 change: 1 addition & 0 deletions crates/katana/rpc/rpc-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ katana-executor.workspace = true
katana-pool.workspace = true
katana-primitives.workspace = true
katana-provider.workspace = true
katana-trie.workspace = true

anyhow.workspace = true
derive_more.workspace = true
Expand Down
1 change: 1 addition & 0 deletions crates/katana/rpc/rpc-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub mod receipt;
pub mod state_update;
pub mod trace;
pub mod transaction;
pub mod trie;
mod utils;

use std::ops::Deref;
Expand Down
Loading
Loading