add node hash rpc

This commit is contained in:
Peter Zhang 2025-11-19 21:51:14 +08:00
parent ba0ed29869
commit 023c777123
8 changed files with 42 additions and 0 deletions

1
Cargo.lock generated
View File

@ -7747,6 +7747,7 @@ name = "storage-async"
version = "0.1.0"
dependencies = [
"anyhow",
"append_merkle",
"backtrace",
"eth2_ssz",
"shared_types",

View File

@ -309,6 +309,8 @@ impl<E: HashElement, A: Algorithm<E>> AppendMerkleTree<E, A> {
/// Panics if the leaf is already set and different or the index is out of range.
/// TODO: Batch computing intermediate nodes.
pub fn fill_leaf(&mut self, index: usize, leaf: E) {
// print node leaf at 12288 index
if leaf.is_null() {
// fill leaf with null is not allowed.
} else if self.node(0, index).is_null() {
@ -425,6 +427,10 @@ impl<E: HashElement, A: Algorithm<E>> AppendMerkleTree<E, A> {
self.root_to_tx_seq_map.contains_key(root)
}
pub fn get_node_hash_by_index(&self, index: usize) -> Result<Option<E>> {
Ok(Some(self.node(0, index)))
}
pub fn leaf_at(&self, position: usize) -> Result<Option<E>> {
if position >= self.leaves() {
bail!("Out of bound: position={} end={}", position, self.leaves());

View File

@ -82,6 +82,12 @@ pub trait Rpc {
flow_root: Option<DataRoot>,
) -> RpcResult<FlowProof>;
#[method(name = "getHashAtNodeIndex")]
async fn get_hash_at_node_index(
&self,
node_index: u64,
) -> RpcResult<Option<H256>>;
#[method(name = "getFlowContext")]
async fn get_flow_context(&self) -> RpcResult<(H256, u64)>;
}

View File

@ -225,6 +225,19 @@ impl RpcServer for RpcServerImpl {
Ok(proof.right_proof)
}
async fn get_hash_at_node_index(
&self,
node_index: u64,
) -> RpcResult<Option<H256>> {
debug!(%node_index, "zgs_getHashAtNodeIndex");
let hash = self
.ctx
.log_store
.get_node_hash_by_index(node_index)
.await?;
Ok(hash.0)
}
async fn get_flow_context(&self) -> RpcResult<(H256, u64)> {
Ok(self.ctx.log_store.get_context().await?)
}

View File

@ -8,6 +8,7 @@ anyhow = { version = "1.0.58", features = ["backtrace"] }
shared_types = { path = "../shared_types" }
storage = { path = "../storage" }
task_executor = { path = "../../common/task_executor" }
append_merkle = { path = "../../common/append_merkle" }
tokio = { version = "1.19.2", features = ["sync"] }
tracing = "0.1.35"
eth2_ssz = "0.4.0"

View File

@ -10,6 +10,7 @@ use std::sync::Arc;
use storage::{error, error::Result, log_store::Store as LogStore, H256};
use task_executor::TaskExecutor;
use tokio::sync::oneshot;
use append_merkle::OptionalHash;
pub use storage::config::ShardConfig;
use storage::log_store::config::ConfigurableExt;
@ -57,6 +58,7 @@ impl Store {
delegate!(fn prune_tx(tx_seq: u64) -> Result<()>);
delegate!(fn finalize_tx_with_hash(tx_seq: u64, tx_hash: H256) -> Result<bool>);
delegate!(fn get_proof_at_root(root: Option<DataRoot>, index: u64, length: u64) -> Result<FlowRangeProof>);
delegate!(fn get_node_hash_by_index(index: u64) -> Result<OptionalHash>);
delegate!(fn get_context() -> Result<(DataRoot, u64)>);
pub async fn get_tx_seq_by_data_root(

View File

@ -564,6 +564,14 @@ impl LogStoreRead for LogManager {
self.tx_store.get_tx_by_seq_number(seq)
}
fn get_node_hash_by_index(&self, index:u64) -> crate::error::Result<OptionalHash> {
let merkle = self.merkle.read();
let opt = merkle
.pora_chunks_merkle
.get_node_hash_by_index(index as usize)?;
opt.ok_or_else(|| anyhow!("node hash not found at index {}", index))
}
fn get_tx_seq_by_data_root(
&self,
data_root: &DataRoot,
@ -1115,7 +1123,9 @@ impl LogManager {
.pora_chunks_merkle
.update_last(merkle.last_chunk_merkle.root());
}
let chunk_roots = self.flow_store.append_entries(flow_entry_array)?;
debug!("fill leaf for pora_chunks_merkle");
for (chunk_index, chunk_root) in chunk_roots {
if chunk_index < merkle.pora_chunks_merkle.leaves() as u64 {
merkle

View File

@ -1,5 +1,6 @@
use crate::config::ShardConfig;
use append_merkle::OptionalHash;
use ethereum_types::H256;
use flow_store::PadPair;
use shared_types::{
@ -30,6 +31,8 @@ pub trait LogStoreRead: LogStoreChunkRead {
/// Get a transaction by its global log sequence number.
fn get_tx_by_seq_number(&self, seq: u64) -> Result<Option<Transaction>>;
fn get_node_hash_by_index(&self, index:u64) -> Result<OptionalHash>;
/// Get a transaction by the data root of its data.
/// If all txs are not finalized, return the first one if need available is false.
/// Otherwise, return the first finalized tx.