mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 00:01:09 +00:00
Storage chains sync (#9171)
* Sync storage chains * Test * Apply suggestions from code review Co-authored-by: cheme <emericchevalier.pro@gmail.com> * Separate block body and indexed body * Update client/db/src/lib.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> Co-authored-by: cheme <emericchevalier.pro@gmail.com> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
This commit is contained in:
@@ -149,6 +149,7 @@ pub trait BlockImportOperation<Block: BlockT> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
header: Block::Header,
|
header: Block::Header,
|
||||||
body: Option<Vec<Block::Extrinsic>>,
|
body: Option<Vec<Block::Extrinsic>>,
|
||||||
|
indexed_body: Option<Vec<Vec<u8>>>,
|
||||||
justifications: Option<Justifications>,
|
justifications: Option<Justifications>,
|
||||||
state: NewBlockState,
|
state: NewBlockState,
|
||||||
) -> sp_blockchain::Result<()>;
|
) -> sp_blockchain::Result<()>;
|
||||||
|
|||||||
@@ -572,6 +572,7 @@ impl<Block: BlockT> backend::BlockImportOperation<Block> for BlockImportOperatio
|
|||||||
&mut self,
|
&mut self,
|
||||||
header: <Block as BlockT>::Header,
|
header: <Block as BlockT>::Header,
|
||||||
body: Option<Vec<<Block as BlockT>::Extrinsic>>,
|
body: Option<Vec<<Block as BlockT>::Extrinsic>>,
|
||||||
|
_indexed_body: Option<Vec<Vec<u8>>>,
|
||||||
justifications: Option<Justifications>,
|
justifications: Option<Justifications>,
|
||||||
state: NewBlockState,
|
state: NewBlockState,
|
||||||
) -> sp_blockchain::Result<()> {
|
) -> sp_blockchain::Result<()> {
|
||||||
|
|||||||
@@ -250,8 +250,14 @@ impl Into<sc_network::config::SyncMode> for SyncMode {
|
|||||||
fn into(self) -> sc_network::config::SyncMode {
|
fn into(self) -> sc_network::config::SyncMode {
|
||||||
match self {
|
match self {
|
||||||
SyncMode::Full => sc_network::config::SyncMode::Full,
|
SyncMode::Full => sc_network::config::SyncMode::Full,
|
||||||
SyncMode::Fast => sc_network::config::SyncMode::Fast { skip_proofs: false },
|
SyncMode::Fast => sc_network::config::SyncMode::Fast {
|
||||||
SyncMode::FastUnsafe => sc_network::config::SyncMode::Fast { skip_proofs: true },
|
skip_proofs: false,
|
||||||
|
storage_chain_mode: false,
|
||||||
|
},
|
||||||
|
SyncMode::FastUnsafe => sc_network::config::SyncMode::Fast {
|
||||||
|
skip_proofs: true,
|
||||||
|
storage_chain_mode: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -572,7 +572,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
let mut op = backend.begin_operation().unwrap();
|
let mut op = backend.begin_operation().unwrap();
|
||||||
backend.begin_state_operation(&mut op, block_id).unwrap();
|
backend.begin_state_operation(&mut op, block_id).unwrap();
|
||||||
op.set_block_data(header, None, None, NewBlockState::Best).unwrap();
|
op.set_block_data(header, None, None, None, NewBlockState::Best).unwrap();
|
||||||
op.update_changes_trie((changes_trie_update, ChangesTrieCacheAction::Clear)).unwrap();
|
op.update_changes_trie((changes_trie_update, ChangesTrieCacheAction::Clear)).unwrap();
|
||||||
backend.commit_operation(op).unwrap();
|
backend.commit_operation(op).unwrap();
|
||||||
|
|
||||||
@@ -916,7 +916,7 @@ mod tests {
|
|||||||
backend.begin_state_operation(&mut op, BlockId::Hash(block2)).unwrap();
|
backend.begin_state_operation(&mut op, BlockId::Hash(block2)).unwrap();
|
||||||
op.mark_finalized(BlockId::Hash(block1), None).unwrap();
|
op.mark_finalized(BlockId::Hash(block1), None).unwrap();
|
||||||
op.mark_finalized(BlockId::Hash(block2), None).unwrap();
|
op.mark_finalized(BlockId::Hash(block2), None).unwrap();
|
||||||
op.set_block_data(header3, None, None, NewBlockState::Final).unwrap();
|
op.set_block_data(header3, None, None, None, NewBlockState::Final).unwrap();
|
||||||
backend.commit_operation(op).unwrap();
|
backend.commit_operation(op).unwrap();
|
||||||
|
|
||||||
// insert more unfinalized headers
|
// insert more unfinalized headers
|
||||||
@@ -941,7 +941,7 @@ mod tests {
|
|||||||
op.mark_finalized(BlockId::Hash(block4), None).unwrap();
|
op.mark_finalized(BlockId::Hash(block4), None).unwrap();
|
||||||
op.mark_finalized(BlockId::Hash(block5), None).unwrap();
|
op.mark_finalized(BlockId::Hash(block5), None).unwrap();
|
||||||
op.mark_finalized(BlockId::Hash(block6), None).unwrap();
|
op.mark_finalized(BlockId::Hash(block6), None).unwrap();
|
||||||
op.set_block_data(header7, None, None, NewBlockState::Final).unwrap();
|
op.set_block_data(header7, None, None, None, NewBlockState::Final).unwrap();
|
||||||
backend.commit_operation(op).unwrap();
|
backend.commit_operation(op).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ use sp_arithmetic::traits::Saturating;
|
|||||||
use sp_runtime::{generic::{DigestItem, BlockId}, Justification, Justifications, Storage};
|
use sp_runtime::{generic::{DigestItem, BlockId}, Justification, Justifications, Storage};
|
||||||
use sp_runtime::traits::{
|
use sp_runtime::traits::{
|
||||||
Block as BlockT, Header as HeaderT, NumberFor, Zero, One, SaturatedConversion, HashFor,
|
Block as BlockT, Header as HeaderT, NumberFor, Zero, One, SaturatedConversion, HashFor,
|
||||||
|
Hash,
|
||||||
};
|
};
|
||||||
use sp_state_machine::{
|
use sp_state_machine::{
|
||||||
DBValue, ChangesTrieTransaction, ChangesTrieCacheAction, UsageInfo as StateUsageInfo,
|
DBValue, ChangesTrieTransaction, ChangesTrieCacheAction, UsageInfo as StateUsageInfo,
|
||||||
@@ -384,6 +385,7 @@ struct PendingBlock<Block: BlockT> {
|
|||||||
header: Block::Header,
|
header: Block::Header,
|
||||||
justifications: Option<Justifications>,
|
justifications: Option<Justifications>,
|
||||||
body: Option<Vec<Block::Extrinsic>>,
|
body: Option<Vec<Block::Extrinsic>>,
|
||||||
|
indexed_body: Option<Vec<Vec<u8>>>,
|
||||||
leaf_state: NewBlockState,
|
leaf_state: NewBlockState,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -824,6 +826,7 @@ impl<Block: BlockT> sc_client_api::backend::BlockImportOperation<Block> for Bloc
|
|||||||
&mut self,
|
&mut self,
|
||||||
header: Block::Header,
|
header: Block::Header,
|
||||||
body: Option<Vec<Block::Extrinsic>>,
|
body: Option<Vec<Block::Extrinsic>>,
|
||||||
|
indexed_body: Option<Vec<Vec<u8>>>,
|
||||||
justifications: Option<Justifications>,
|
justifications: Option<Justifications>,
|
||||||
leaf_state: NewBlockState,
|
leaf_state: NewBlockState,
|
||||||
) -> ClientResult<()> {
|
) -> ClientResult<()> {
|
||||||
@@ -834,6 +837,7 @@ impl<Block: BlockT> sc_client_api::backend::BlockImportOperation<Block> for Bloc
|
|||||||
self.pending_block = Some(PendingBlock {
|
self.pending_block = Some(PendingBlock {
|
||||||
header,
|
header,
|
||||||
body,
|
body,
|
||||||
|
indexed_body,
|
||||||
justifications,
|
justifications,
|
||||||
leaf_state,
|
leaf_state,
|
||||||
});
|
});
|
||||||
@@ -1068,7 +1072,7 @@ impl<Block: BlockT> Backend<Block> {
|
|||||||
|
|
||||||
/// Create new memory-backed client backend for tests.
|
/// Create new memory-backed client backend for tests.
|
||||||
#[cfg(any(test, feature = "test-helpers"))]
|
#[cfg(any(test, feature = "test-helpers"))]
|
||||||
fn new_test_with_tx_storage(
|
pub fn new_test_with_tx_storage(
|
||||||
keep_blocks: u32,
|
keep_blocks: u32,
|
||||||
canonicalization_delay: u64,
|
canonicalization_delay: u64,
|
||||||
transaction_storage: TransactionStorageMode,
|
transaction_storage: TransactionStorageMode,
|
||||||
@@ -1393,6 +1397,16 @@ impl<Block: BlockT> Backend<Block> {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Some(body) = pending_block.indexed_body {
|
||||||
|
match self.transaction_storage {
|
||||||
|
TransactionStorageMode::BlockBody => {
|
||||||
|
debug!(target: "db", "Commit: ignored indexed block body");
|
||||||
|
},
|
||||||
|
TransactionStorageMode::StorageChain => {
|
||||||
|
apply_indexed_body::<Block>(&mut transaction, body);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
if let Some(justifications) = pending_block.justifications {
|
if let Some(justifications) = pending_block.justifications {
|
||||||
transaction.set_from_vec(columns::JUSTIFICATIONS, &lookup_key, justifications.encode());
|
transaction.set_from_vec(columns::JUSTIFICATIONS, &lookup_key, justifications.encode());
|
||||||
}
|
}
|
||||||
@@ -1881,6 +1895,20 @@ fn apply_index_ops<Block: BlockT>(
|
|||||||
extrinsic_headers.encode()
|
extrinsic_headers.encode()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn apply_indexed_body<Block: BlockT>(
|
||||||
|
transaction: &mut Transaction<DbHash>,
|
||||||
|
body: Vec<Vec<u8>>,
|
||||||
|
) {
|
||||||
|
for extrinsic in body {
|
||||||
|
let hash = sp_runtime::traits::BlakeTwo256::hash(&extrinsic);
|
||||||
|
transaction.store(
|
||||||
|
columns::TRANSACTION,
|
||||||
|
DbHash::from_slice(hash.as_ref()),
|
||||||
|
extrinsic,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<Block> sc_client_api::backend::AuxStore for Backend<Block> where Block: BlockT {
|
impl<Block> sc_client_api::backend::AuxStore for Backend<Block> where Block: BlockT {
|
||||||
fn insert_aux<
|
fn insert_aux<
|
||||||
'a,
|
'a,
|
||||||
@@ -2439,7 +2467,7 @@ pub(crate) mod tests {
|
|||||||
};
|
};
|
||||||
let mut op = backend.begin_operation().unwrap();
|
let mut op = backend.begin_operation().unwrap();
|
||||||
backend.begin_state_operation(&mut op, block_id).unwrap();
|
backend.begin_state_operation(&mut op, block_id).unwrap();
|
||||||
op.set_block_data(header, Some(body), None, NewBlockState::Best).unwrap();
|
op.set_block_data(header, Some(body), None, None, NewBlockState::Best).unwrap();
|
||||||
if let Some(index) = transaction_index {
|
if let Some(index) = transaction_index {
|
||||||
op.update_transaction_index(index).unwrap();
|
op.update_transaction_index(index).unwrap();
|
||||||
}
|
}
|
||||||
@@ -2481,6 +2509,7 @@ pub(crate) mod tests {
|
|||||||
header,
|
header,
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
NewBlockState::Best,
|
NewBlockState::Best,
|
||||||
).unwrap();
|
).unwrap();
|
||||||
db.commit_operation(op).unwrap();
|
db.commit_operation(op).unwrap();
|
||||||
@@ -2537,6 +2566,7 @@ pub(crate) mod tests {
|
|||||||
header.clone(),
|
header.clone(),
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
NewBlockState::Best,
|
NewBlockState::Best,
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
@@ -2579,6 +2609,7 @@ pub(crate) mod tests {
|
|||||||
header,
|
header,
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
NewBlockState::Best,
|
NewBlockState::Best,
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
@@ -2622,6 +2653,7 @@ pub(crate) mod tests {
|
|||||||
header,
|
header,
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
NewBlockState::Best,
|
NewBlockState::Best,
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
@@ -2659,6 +2691,7 @@ pub(crate) mod tests {
|
|||||||
header,
|
header,
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
NewBlockState::Best,
|
NewBlockState::Best,
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
@@ -2695,6 +2728,7 @@ pub(crate) mod tests {
|
|||||||
header,
|
header,
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
NewBlockState::Best,
|
NewBlockState::Best,
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
@@ -2730,6 +2764,7 @@ pub(crate) mod tests {
|
|||||||
header,
|
header,
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
NewBlockState::Best,
|
NewBlockState::Best,
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
@@ -3067,6 +3102,7 @@ pub(crate) mod tests {
|
|||||||
header.clone(),
|
header.clone(),
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
NewBlockState::Best,
|
NewBlockState::Best,
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
@@ -3106,6 +3142,7 @@ pub(crate) mod tests {
|
|||||||
header,
|
header,
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
NewBlockState::Normal,
|
NewBlockState::Normal,
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
@@ -3118,7 +3155,7 @@ pub(crate) mod tests {
|
|||||||
let header = backend.blockchain().header(BlockId::Hash(hash1)).unwrap().unwrap();
|
let header = backend.blockchain().header(BlockId::Hash(hash1)).unwrap().unwrap();
|
||||||
let mut op = backend.begin_operation().unwrap();
|
let mut op = backend.begin_operation().unwrap();
|
||||||
backend.begin_state_operation(&mut op, BlockId::Hash(hash0)).unwrap();
|
backend.begin_state_operation(&mut op, BlockId::Hash(hash0)).unwrap();
|
||||||
op.set_block_data(header, None, None, NewBlockState::Best).unwrap();
|
op.set_block_data(header, None, None, None, NewBlockState::Best).unwrap();
|
||||||
backend.commit_operation(op).unwrap();
|
backend.commit_operation(op).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -293,6 +293,7 @@ impl<S, Block> BlockImportOperation<Block> for ImportOperation<Block, S>
|
|||||||
&mut self,
|
&mut self,
|
||||||
header: Block::Header,
|
header: Block::Header,
|
||||||
_body: Option<Vec<Block::Extrinsic>>,
|
_body: Option<Vec<Block::Extrinsic>>,
|
||||||
|
_indexed_body: Option<Vec<Vec<u8>>>,
|
||||||
_justifications: Option<Justifications>,
|
_justifications: Option<Justifications>,
|
||||||
state: NewBlockState,
|
state: NewBlockState,
|
||||||
) -> ClientResult<()> {
|
) -> ClientResult<()> {
|
||||||
|
|||||||
@@ -264,6 +264,7 @@ impl<B: BlockT> BlockRequestHandler<B> {
|
|||||||
) -> Result<BlockResponse, HandleRequestError> {
|
) -> Result<BlockResponse, HandleRequestError> {
|
||||||
let get_header = attributes.contains(BlockAttributes::HEADER);
|
let get_header = attributes.contains(BlockAttributes::HEADER);
|
||||||
let get_body = attributes.contains(BlockAttributes::BODY);
|
let get_body = attributes.contains(BlockAttributes::BODY);
|
||||||
|
let get_indexed_body = attributes.contains(BlockAttributes::INDEXED_BODY);
|
||||||
let get_justification = attributes.contains(BlockAttributes::JUSTIFICATION);
|
let get_justification = attributes.contains(BlockAttributes::JUSTIFICATION);
|
||||||
|
|
||||||
let mut blocks = Vec::new();
|
let mut blocks = Vec::new();
|
||||||
@@ -321,6 +322,18 @@ impl<B: BlockT> BlockRequestHandler<B> {
|
|||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let indexed_body = if get_indexed_body {
|
||||||
|
match self.client.block_indexed_body(&BlockId::Hash(hash))? {
|
||||||
|
Some(transactions) => transactions,
|
||||||
|
None => {
|
||||||
|
log::trace!(target: LOG_TARGET, "Missing indexed block data for block request.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
|
||||||
let block_data = crate::schema::v1::BlockData {
|
let block_data = crate::schema::v1::BlockData {
|
||||||
hash: hash.encode(),
|
hash: hash.encode(),
|
||||||
header: if get_header {
|
header: if get_header {
|
||||||
@@ -334,6 +347,7 @@ impl<B: BlockT> BlockRequestHandler<B> {
|
|||||||
justification,
|
justification,
|
||||||
is_empty_justification,
|
is_empty_justification,
|
||||||
justifications,
|
justifications,
|
||||||
|
indexed_body,
|
||||||
};
|
};
|
||||||
|
|
||||||
total_size += block_data.body.len();
|
total_size += block_data.body.len();
|
||||||
|
|||||||
@@ -390,7 +390,9 @@ pub enum SyncMode {
|
|||||||
/// Download blocks and the latest state.
|
/// Download blocks and the latest state.
|
||||||
Fast {
|
Fast {
|
||||||
/// Skip state proof download and verification.
|
/// Skip state proof download and verification.
|
||||||
skip_proofs: bool
|
skip_proofs: bool,
|
||||||
|
/// Download indexed transactions for recent blocks.
|
||||||
|
storage_chain_mode: bool,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -263,7 +263,6 @@ pub mod light_client_requests;
|
|||||||
pub mod state_request_handler;
|
pub mod state_request_handler;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod gossip;
|
|
||||||
pub mod network_state;
|
pub mod network_state;
|
||||||
pub mod transactions;
|
pub mod transactions;
|
||||||
|
|
||||||
|
|||||||
@@ -228,7 +228,13 @@ impl ProtocolConfig {
|
|||||||
} else {
|
} else {
|
||||||
match self.sync_mode {
|
match self.sync_mode {
|
||||||
config::SyncMode::Full => sync::SyncMode::Full,
|
config::SyncMode::Full => sync::SyncMode::Full,
|
||||||
config::SyncMode::Fast { skip_proofs } => sync::SyncMode::LightState { skip_proofs },
|
config::SyncMode::Fast {
|
||||||
|
skip_proofs,
|
||||||
|
storage_chain_mode,
|
||||||
|
} => sync::SyncMode::LightState {
|
||||||
|
skip_proofs,
|
||||||
|
storage_chain_mode
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -597,6 +603,11 @@ impl<B: BlockT> Protocol<B> {
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
indexed_body: if request.fields.contains(message::BlockAttributes::INDEXED_BODY) {
|
||||||
|
Some(block_data.indexed_body)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
receipt: if !block_data.message_queue.is_empty() {
|
receipt: if !block_data.message_queue.is_empty() {
|
||||||
Some(block_data.receipt)
|
Some(block_data.receipt)
|
||||||
} else {
|
} else {
|
||||||
@@ -965,6 +976,7 @@ impl<B: BlockT> Protocol<B> {
|
|||||||
hash: header.hash(),
|
hash: header.hash(),
|
||||||
header: Some(header),
|
header: Some(header),
|
||||||
body: None,
|
body: None,
|
||||||
|
indexed_body: None,
|
||||||
receipt: None,
|
receipt: None,
|
||||||
message_queue: None,
|
message_queue: None,
|
||||||
justification: None,
|
justification: None,
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ bitflags! {
|
|||||||
const MESSAGE_QUEUE = 0b00001000;
|
const MESSAGE_QUEUE = 0b00001000;
|
||||||
/// Include a justification for the block.
|
/// Include a justification for the block.
|
||||||
const JUSTIFICATION = 0b00010000;
|
const JUSTIFICATION = 0b00010000;
|
||||||
|
/// Include indexed transactions for a block.
|
||||||
|
const INDEXED_BODY = 0b00100000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,6 +250,8 @@ pub mod generic {
|
|||||||
pub header: Option<Header>,
|
pub header: Option<Header>,
|
||||||
/// Block body if requested.
|
/// Block body if requested.
|
||||||
pub body: Option<Vec<Extrinsic>>,
|
pub body: Option<Vec<Extrinsic>>,
|
||||||
|
/// Block body indexed transactions if requested.
|
||||||
|
pub indexed_body: Option<Vec<Vec<u8>>>,
|
||||||
/// Block receipt if requested.
|
/// Block receipt if requested.
|
||||||
pub receipt: Option<Vec<u8>>,
|
pub receipt: Option<Vec<u8>>,
|
||||||
/// Block message queue if requested.
|
/// Block message queue if requested.
|
||||||
|
|||||||
@@ -469,7 +469,8 @@ pub enum SyncMode {
|
|||||||
Full,
|
Full,
|
||||||
// Sync headers and the last finalied state
|
// Sync headers and the last finalied state
|
||||||
LightState {
|
LightState {
|
||||||
skip_proofs: bool
|
storage_chain_mode: bool,
|
||||||
|
skip_proofs: bool,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,8 +519,10 @@ impl<B: BlockT> ChainSync<B> {
|
|||||||
match self.mode {
|
match self.mode {
|
||||||
SyncMode::Full => BlockAttributes::HEADER | BlockAttributes::JUSTIFICATION | BlockAttributes::BODY,
|
SyncMode::Full => BlockAttributes::HEADER | BlockAttributes::JUSTIFICATION | BlockAttributes::BODY,
|
||||||
SyncMode::Light => BlockAttributes::HEADER | BlockAttributes::JUSTIFICATION,
|
SyncMode::Light => BlockAttributes::HEADER | BlockAttributes::JUSTIFICATION,
|
||||||
SyncMode::LightState { .. } =>
|
SyncMode::LightState { storage_chain_mode: false, .. } =>
|
||||||
BlockAttributes::HEADER | BlockAttributes::JUSTIFICATION | BlockAttributes::BODY,
|
BlockAttributes::HEADER | BlockAttributes::JUSTIFICATION | BlockAttributes::BODY,
|
||||||
|
SyncMode::LightState { storage_chain_mode: true, .. } =>
|
||||||
|
BlockAttributes::HEADER | BlockAttributes::JUSTIFICATION | BlockAttributes::INDEXED_BODY,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -914,25 +917,7 @@ impl<B: BlockT> ChainSync<B> {
|
|||||||
peer.state = PeerSyncState::Available;
|
peer.state = PeerSyncState::Available;
|
||||||
validate_blocks::<B>(&blocks, who, Some(request))?;
|
validate_blocks::<B>(&blocks, who, Some(request))?;
|
||||||
self.blocks.insert(start_block, blocks, who.clone());
|
self.blocks.insert(start_block, blocks, who.clone());
|
||||||
self.blocks
|
self.drain_blocks()
|
||||||
.drain(self.best_queued_number + One::one())
|
|
||||||
.into_iter()
|
|
||||||
.map(|block_data| {
|
|
||||||
let justifications = block_data.block.justifications.or(
|
|
||||||
legacy_justification_mapping(block_data.block.justification)
|
|
||||||
);
|
|
||||||
IncomingBlock {
|
|
||||||
hash: block_data.block.hash,
|
|
||||||
header: block_data.block.header,
|
|
||||||
body: block_data.block.body,
|
|
||||||
justifications,
|
|
||||||
origin: block_data.origin,
|
|
||||||
allow_missing_state: true,
|
|
||||||
import_existing: self.import_existing,
|
|
||||||
skip_execution: self.skip_execution(),
|
|
||||||
state: None,
|
|
||||||
}
|
|
||||||
}).collect()
|
|
||||||
}
|
}
|
||||||
PeerSyncState::DownloadingStale(_) => {
|
PeerSyncState::DownloadingStale(_) => {
|
||||||
peer.state = PeerSyncState::Available;
|
peer.state = PeerSyncState::Available;
|
||||||
@@ -949,6 +934,7 @@ impl<B: BlockT> ChainSync<B> {
|
|||||||
hash: b.hash,
|
hash: b.hash,
|
||||||
header: b.header,
|
header: b.header,
|
||||||
body: b.body,
|
body: b.body,
|
||||||
|
indexed_body: None,
|
||||||
justifications,
|
justifications,
|
||||||
origin: Some(who.clone()),
|
origin: Some(who.clone()),
|
||||||
allow_missing_state: true,
|
allow_missing_state: true,
|
||||||
@@ -1064,6 +1050,7 @@ impl<B: BlockT> ChainSync<B> {
|
|||||||
hash: b.hash,
|
hash: b.hash,
|
||||||
header: b.header,
|
header: b.header,
|
||||||
body: b.body,
|
body: b.body,
|
||||||
|
indexed_body: None,
|
||||||
justifications,
|
justifications,
|
||||||
origin: Some(who.clone()),
|
origin: Some(who.clone()),
|
||||||
allow_missing_state: true,
|
allow_missing_state: true,
|
||||||
@@ -1115,6 +1102,7 @@ impl<B: BlockT> ChainSync<B> {
|
|||||||
hash,
|
hash,
|
||||||
header: Some(header),
|
header: Some(header),
|
||||||
body: None,
|
body: None,
|
||||||
|
indexed_body: None,
|
||||||
justifications: None,
|
justifications: None,
|
||||||
origin: None,
|
origin: None,
|
||||||
allow_missing_state: true,
|
allow_missing_state: true,
|
||||||
@@ -1367,7 +1355,7 @@ impl<B: BlockT> ChainSync<B> {
|
|||||||
is_descendent_of(&**client, base, block)
|
is_descendent_of(&**client, base, block)
|
||||||
});
|
});
|
||||||
|
|
||||||
if let SyncMode::LightState { skip_proofs } = &self.mode {
|
if let SyncMode::LightState { skip_proofs, .. } = &self.mode {
|
||||||
if self.state_sync.is_none()
|
if self.state_sync.is_none()
|
||||||
&& !self.peers.is_empty()
|
&& !self.peers.is_empty()
|
||||||
&& self.queue_blocks.is_empty()
|
&& self.queue_blocks.is_empty()
|
||||||
@@ -1757,24 +1745,7 @@ impl<B: BlockT> ChainSync<B> {
|
|||||||
target.peers.remove(who);
|
target.peers.remove(who);
|
||||||
!target.peers.is_empty()
|
!target.peers.is_empty()
|
||||||
});
|
});
|
||||||
let blocks: Vec<_> = self.blocks
|
let blocks = self.drain_blocks();
|
||||||
.drain(self.best_queued_number + One::one())
|
|
||||||
.into_iter()
|
|
||||||
.map(|block_data| {
|
|
||||||
let justifications =
|
|
||||||
legacy_justification_mapping(block_data.block.justification);
|
|
||||||
IncomingBlock {
|
|
||||||
hash: block_data.block.hash,
|
|
||||||
header: block_data.block.header,
|
|
||||||
body: block_data.block.body,
|
|
||||||
justifications,
|
|
||||||
origin: block_data.origin,
|
|
||||||
allow_missing_state: true,
|
|
||||||
import_existing: false,
|
|
||||||
skip_execution: self.skip_execution(),
|
|
||||||
state: None,
|
|
||||||
}
|
|
||||||
}).collect();
|
|
||||||
if !blocks.is_empty() {
|
if !blocks.is_empty() {
|
||||||
Some(self.validate_and_queue_blocks(blocks))
|
Some(self.validate_and_queue_blocks(blocks))
|
||||||
} else {
|
} else {
|
||||||
@@ -1878,6 +1849,31 @@ impl<B: BlockT> ChainSync<B> {
|
|||||||
_priv: ()
|
_priv: ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drain the downloaded block set up to the first gap.
|
||||||
|
fn drain_blocks(&mut self) -> Vec<IncomingBlock<B>> {
|
||||||
|
self.blocks
|
||||||
|
.drain(self.best_queued_number + One::one())
|
||||||
|
.into_iter()
|
||||||
|
.map(|block_data| {
|
||||||
|
let justifications = block_data.block.justifications.or(
|
||||||
|
legacy_justification_mapping(block_data.block.justification)
|
||||||
|
);
|
||||||
|
IncomingBlock {
|
||||||
|
hash: block_data.block.hash,
|
||||||
|
header: block_data.block.header,
|
||||||
|
body: block_data.block.body,
|
||||||
|
indexed_body: block_data.block.indexed_body,
|
||||||
|
justifications,
|
||||||
|
origin: block_data.origin,
|
||||||
|
allow_missing_state: true,
|
||||||
|
import_existing: self.import_existing,
|
||||||
|
skip_execution: self.skip_execution(),
|
||||||
|
state: None,
|
||||||
|
}
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is purely during a backwards compatible transitionary period and should be removed
|
// This is purely during a backwards compatible transitionary period and should be removed
|
||||||
@@ -2383,6 +2379,7 @@ mod test {
|
|||||||
hash: b.hash(),
|
hash: b.hash(),
|
||||||
header: Some(b.header().clone()),
|
header: Some(b.header().clone()),
|
||||||
body: Some(b.deconstruct().1),
|
body: Some(b.deconstruct().1),
|
||||||
|
indexed_body: None,
|
||||||
receipt: None,
|
receipt: None,
|
||||||
message_queue: None,
|
message_queue: None,
|
||||||
justification: None,
|
justification: None,
|
||||||
|
|||||||
@@ -225,6 +225,7 @@ mod test {
|
|||||||
hash: H256::random(),
|
hash: H256::random(),
|
||||||
header: None,
|
header: None,
|
||||||
body: None,
|
body: None,
|
||||||
|
indexed_body: None,
|
||||||
message_queue: None,
|
message_queue: None,
|
||||||
receipt: None,
|
receipt: None,
|
||||||
justification: None,
|
justification: None,
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ message BlockData {
|
|||||||
// is because empty justifications, like all justifications, are paired with a non-empty
|
// is because empty justifications, like all justifications, are paired with a non-empty
|
||||||
// consensus engine ID.
|
// consensus engine ID.
|
||||||
bytes justifications = 8; // optional
|
bytes justifications = 8; // optional
|
||||||
|
// Indexed block body if requestd.
|
||||||
|
repeated bytes indexed_body = 9; // optional
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request storage data from a peer.
|
// Request storage data from a peer.
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ fn prepare_good_block() -> (TestClient, Hash, u64, PeerId, IncomingBlock<Block>)
|
|||||||
hash,
|
hash,
|
||||||
header,
|
header,
|
||||||
body: Some(Vec::new()),
|
body: Some(Vec::new()),
|
||||||
|
indexed_body: None,
|
||||||
justifications,
|
justifications,
|
||||||
origin: Some(peer_id.clone()),
|
origin: Some(peer_id.clone()),
|
||||||
allow_missing_state: false,
|
allow_missing_state: false,
|
||||||
|
|||||||
@@ -660,6 +660,8 @@ pub struct FullPeerConfig {
|
|||||||
pub is_authority: bool,
|
pub is_authority: bool,
|
||||||
/// Syncing mode
|
/// Syncing mode
|
||||||
pub sync_mode: SyncMode,
|
pub sync_mode: SyncMode,
|
||||||
|
/// Enable transaction indexing.
|
||||||
|
pub storage_chain: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TestNetFactory: Sized where <Self::BlockImport as BlockImport<Block>>::Transaction: Send {
|
pub trait TestNetFactory: Sized where <Self::BlockImport as BlockImport<Block>>::Transaction: Send {
|
||||||
@@ -715,9 +717,11 @@ pub trait TestNetFactory: Sized where <Self::BlockImport as BlockImport<Block>>:
|
|||||||
|
|
||||||
/// Add a full peer.
|
/// Add a full peer.
|
||||||
fn add_full_peer_with_config(&mut self, config: FullPeerConfig) {
|
fn add_full_peer_with_config(&mut self, config: FullPeerConfig) {
|
||||||
let mut test_client_builder = match config.keep_blocks {
|
let mut test_client_builder = match (config.keep_blocks, config.storage_chain) {
|
||||||
Some(keep_blocks) => TestClientBuilder::with_pruning_window(keep_blocks),
|
(Some(keep_blocks), true) => TestClientBuilder::with_tx_storage(keep_blocks),
|
||||||
None => TestClientBuilder::with_default_backend(),
|
(None, true) => TestClientBuilder::with_tx_storage(u32::MAX),
|
||||||
|
(Some(keep_blocks), false) => TestClientBuilder::with_pruning_window(keep_blocks),
|
||||||
|
(None, false) => TestClientBuilder::with_default_backend(),
|
||||||
};
|
};
|
||||||
if matches!(config.sync_mode, SyncMode::Fast{..}) {
|
if matches!(config.sync_mode, SyncMode::Fast{..}) {
|
||||||
test_client_builder = test_client_builder.set_no_genesis();
|
test_client_builder = test_client_builder.set_no_genesis();
|
||||||
|
|||||||
@@ -1095,7 +1095,7 @@ fn syncs_state() {
|
|||||||
let mut net = TestNet::new(0);
|
let mut net = TestNet::new(0);
|
||||||
net.add_full_peer_with_config(Default::default());
|
net.add_full_peer_with_config(Default::default());
|
||||||
net.add_full_peer_with_config(FullPeerConfig {
|
net.add_full_peer_with_config(FullPeerConfig {
|
||||||
sync_mode: SyncMode::Fast { skip_proofs: *skip_proofs },
|
sync_mode: SyncMode::Fast { skip_proofs: *skip_proofs, storage_chain_mode: false },
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
net.peer(0).push_blocks(64, false);
|
net.peer(0).push_blocks(64, false);
|
||||||
@@ -1127,3 +1127,39 @@ fn syncs_state() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn syncs_indexed_blocks() {
|
||||||
|
use sp_runtime::traits::Hash;
|
||||||
|
sp_tracing::try_init_simple();
|
||||||
|
let mut net = TestNet::new(0);
|
||||||
|
let mut n: u64 = 0;
|
||||||
|
net.add_full_peer_with_config(FullPeerConfig {
|
||||||
|
storage_chain: true,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
net.add_full_peer_with_config(FullPeerConfig {
|
||||||
|
storage_chain: true,
|
||||||
|
sync_mode: SyncMode::Fast { skip_proofs: false, storage_chain_mode: true },
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
net.peer(0).generate_blocks_at(
|
||||||
|
BlockId::number(0),
|
||||||
|
64,
|
||||||
|
BlockOrigin::Own, |mut builder| {
|
||||||
|
let ex = Extrinsic::Store(n.to_le_bytes().to_vec());
|
||||||
|
n += 1;
|
||||||
|
builder.push(ex).unwrap();
|
||||||
|
builder.build().unwrap().block
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
let indexed_key = sp_runtime::traits::BlakeTwo256::hash(&42u64.to_le_bytes());
|
||||||
|
assert!(net.peer(0).client().as_full().unwrap().indexed_transaction(&indexed_key).unwrap().is_some());
|
||||||
|
assert!(net.peer(1).client().as_full().unwrap().indexed_transaction(&indexed_key).unwrap().is_none());
|
||||||
|
|
||||||
|
net.block_until_sync();
|
||||||
|
assert!(net.peer(1).client().as_full().unwrap().indexed_transaction(&indexed_key).unwrap().is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ use crate::{
|
|||||||
start_rpc_servers, build_network_future, TransactionPoolAdapter, TaskManager, SpawnTaskHandle,
|
start_rpc_servers, build_network_future, TransactionPoolAdapter, TaskManager, SpawnTaskHandle,
|
||||||
metrics::MetricsService,
|
metrics::MetricsService,
|
||||||
client::{light, Client, ClientConfig},
|
client::{light, Client, ClientConfig},
|
||||||
config::{Configuration, KeystoreConfig, PrometheusConfig},
|
config::{Configuration, KeystoreConfig, PrometheusConfig, TransactionStorageMode},
|
||||||
};
|
};
|
||||||
use sc_client_api::{
|
use sc_client_api::{
|
||||||
light::RemoteBlockchain, ForkBlocks, BadBlocks, UsageProvider, ExecutorProvider,
|
light::RemoteBlockchain, ForkBlocks, BadBlocks, UsageProvider, ExecutorProvider,
|
||||||
@@ -40,7 +40,7 @@ use futures::{
|
|||||||
};
|
};
|
||||||
use sc_keystore::LocalKeystore;
|
use sc_keystore::LocalKeystore;
|
||||||
use log::info;
|
use log::info;
|
||||||
use sc_network::config::{Role, OnDemand};
|
use sc_network::config::{Role, OnDemand, SyncMode};
|
||||||
use sc_network::NetworkService;
|
use sc_network::NetworkService;
|
||||||
use sc_network::block_request_handler::{self, BlockRequestHandler};
|
use sc_network::block_request_handler::{self, BlockRequestHandler};
|
||||||
use sc_network::state_request_handler::{self, StateRequestHandler};
|
use sc_network::state_request_handler::{self, StateRequestHandler};
|
||||||
@@ -946,7 +946,7 @@ pub fn build_network<TBl, TExPool, TImpQu, TCl>(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let network_params = sc_network::config::Params {
|
let mut network_params = sc_network::config::Params {
|
||||||
role: config.role.clone(),
|
role: config.role.clone(),
|
||||||
executor: {
|
executor: {
|
||||||
let spawn_handle = Clone::clone(&spawn_handle);
|
let spawn_handle = Clone::clone(&spawn_handle);
|
||||||
@@ -973,6 +973,15 @@ pub fn build_network<TBl, TExPool, TImpQu, TCl>(
|
|||||||
light_client_request_protocol_config,
|
light_client_request_protocol_config,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Storage chains don't keep full block history and can't be synced in full mode.
|
||||||
|
// Force fast sync when storage chain mode is enabled.
|
||||||
|
if matches!(config.transaction_storage, TransactionStorageMode::StorageChain) {
|
||||||
|
network_params.network_config.sync_mode = SyncMode::Fast {
|
||||||
|
storage_chain_mode: true,
|
||||||
|
skip_proofs: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
let has_bootnodes = !network_params.network_config.boot_nodes.is_empty();
|
let has_bootnodes = !network_params.network_config.boot_nodes.is_empty();
|
||||||
let network_mut = sc_network::NetworkWorker::new(network_params)?;
|
let network_mut = sc_network::NetworkWorker::new(network_params)?;
|
||||||
let network = network_mut.service().clone();
|
let network = network_mut.service().clone();
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ fn import_block_to_queue<TBl, TImpQu>(
|
|||||||
hash,
|
hash,
|
||||||
header: Some(header),
|
header: Some(header),
|
||||||
body: Some(extrinsics),
|
body: Some(extrinsics),
|
||||||
|
indexed_body: None,
|
||||||
justifications: signed_block.justifications,
|
justifications: signed_block.justifications,
|
||||||
origin: None,
|
origin: None,
|
||||||
allow_missing_state: false,
|
allow_missing_state: false,
|
||||||
|
|||||||
@@ -355,6 +355,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
|||||||
genesis_block.deconstruct().0,
|
genesis_block.deconstruct().0,
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
block_state,
|
block_state,
|
||||||
)?;
|
)?;
|
||||||
backend.commit_operation(op)?;
|
backend.commit_operation(op)?;
|
||||||
@@ -657,6 +658,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
|||||||
justifications,
|
justifications,
|
||||||
post_digests,
|
post_digests,
|
||||||
body,
|
body,
|
||||||
|
indexed_body,
|
||||||
finalized,
|
finalized,
|
||||||
auxiliary,
|
auxiliary,
|
||||||
fork_choice,
|
fork_choice,
|
||||||
@@ -695,6 +697,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
|||||||
import_headers,
|
import_headers,
|
||||||
justifications,
|
justifications,
|
||||||
body,
|
body,
|
||||||
|
indexed_body,
|
||||||
storage_changes,
|
storage_changes,
|
||||||
new_cache,
|
new_cache,
|
||||||
finalized,
|
finalized,
|
||||||
@@ -734,6 +737,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
|||||||
import_headers: PrePostHeader<Block::Header>,
|
import_headers: PrePostHeader<Block::Header>,
|
||||||
justifications: Option<Justifications>,
|
justifications: Option<Justifications>,
|
||||||
body: Option<Vec<Block::Extrinsic>>,
|
body: Option<Vec<Block::Extrinsic>>,
|
||||||
|
indexed_body: Option<Vec<Vec<u8>>>,
|
||||||
storage_changes: Option<sp_consensus::StorageChanges<Block, backend::TransactionFor<B, Block>>>,
|
storage_changes: Option<sp_consensus::StorageChanges<Block, backend::TransactionFor<B, Block>>>,
|
||||||
new_cache: HashMap<CacheKeyId, Vec<u8>>,
|
new_cache: HashMap<CacheKeyId, Vec<u8>>,
|
||||||
finalized: bool,
|
finalized: bool,
|
||||||
@@ -871,6 +875,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
|||||||
operation.op.set_block_data(
|
operation.op.set_block_data(
|
||||||
import_headers.post().clone(),
|
import_headers.post().clone(),
|
||||||
body,
|
body,
|
||||||
|
indexed_body,
|
||||||
justifications,
|
justifications,
|
||||||
leaf_state,
|
leaf_state,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ fn local_state_is_created_when_genesis_state_is_available() {
|
|||||||
Arc::new(DummyBlockchain::new(DummyStorage::new())),
|
Arc::new(DummyBlockchain::new(DummyStorage::new())),
|
||||||
);
|
);
|
||||||
let mut op = backend.begin_operation().unwrap();
|
let mut op = backend.begin_operation().unwrap();
|
||||||
op.set_block_data(header0, None, None, NewBlockState::Final).unwrap();
|
op.set_block_data(header0, None, None, None, NewBlockState::Final).unwrap();
|
||||||
op.set_genesis_state(Default::default(), true).unwrap();
|
op.set_genesis_state(Default::default(), true).unwrap();
|
||||||
backend.commit_operation(op).unwrap();
|
backend.commit_operation(op).unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -196,6 +196,8 @@ pub struct BlockImportParams<Block: BlockT, Transaction> {
|
|||||||
pub post_digests: Vec<DigestItemFor<Block>>,
|
pub post_digests: Vec<DigestItemFor<Block>>,
|
||||||
/// The body of the block.
|
/// The body of the block.
|
||||||
pub body: Option<Vec<Block::Extrinsic>>,
|
pub body: Option<Vec<Block::Extrinsic>>,
|
||||||
|
/// Indexed transaction body of the block.
|
||||||
|
pub indexed_body: Option<Vec<Vec<u8>>>,
|
||||||
/// Specify how the new state is computed.
|
/// Specify how the new state is computed.
|
||||||
pub state_action: StateAction<Block, Transaction>,
|
pub state_action: StateAction<Block, Transaction>,
|
||||||
/// Is this block finalized already?
|
/// Is this block finalized already?
|
||||||
@@ -233,6 +235,7 @@ impl<Block: BlockT, Transaction> BlockImportParams<Block, Transaction> {
|
|||||||
justifications: None,
|
justifications: None,
|
||||||
post_digests: Vec::new(),
|
post_digests: Vec::new(),
|
||||||
body: None,
|
body: None,
|
||||||
|
indexed_body: None,
|
||||||
state_action: StateAction::Execute,
|
state_action: StateAction::Execute,
|
||||||
finalized: false,
|
finalized: false,
|
||||||
intermediates: HashMap::new(),
|
intermediates: HashMap::new(),
|
||||||
@@ -286,6 +289,7 @@ impl<Block: BlockT, Transaction> BlockImportParams<Block, Transaction> {
|
|||||||
justifications: self.justifications,
|
justifications: self.justifications,
|
||||||
post_digests: self.post_digests,
|
post_digests: self.post_digests,
|
||||||
body: self.body,
|
body: self.body,
|
||||||
|
indexed_body: self.indexed_body,
|
||||||
state_action,
|
state_action,
|
||||||
finalized: self.finalized,
|
finalized: self.finalized,
|
||||||
auxiliary: self.auxiliary,
|
auxiliary: self.auxiliary,
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ pub struct IncomingBlock<B: BlockT> {
|
|||||||
pub header: Option<<B as BlockT>::Header>,
|
pub header: Option<<B as BlockT>::Header>,
|
||||||
/// Block body if requested.
|
/// Block body if requested.
|
||||||
pub body: Option<Vec<<B as BlockT>::Extrinsic>>,
|
pub body: Option<Vec<<B as BlockT>::Extrinsic>>,
|
||||||
|
/// Indexed block body if requested.
|
||||||
|
pub indexed_body: Option<Vec<Vec<u8>>>,
|
||||||
/// Justification(s) if requested.
|
/// Justification(s) if requested.
|
||||||
pub justifications: Option<Justifications>,
|
pub justifications: Option<Justifications>,
|
||||||
/// The peer, we received this from
|
/// The peer, we received this from
|
||||||
@@ -269,6 +271,7 @@ pub(crate) async fn import_single_block_metered<B: BlockT, V: Verifier<B>, Trans
|
|||||||
cache.extend(keys.into_iter());
|
cache.extend(keys.into_iter());
|
||||||
}
|
}
|
||||||
import_block.import_existing = block.import_existing;
|
import_block.import_existing = block.import_existing;
|
||||||
|
import_block.indexed_body = block.indexed_body;
|
||||||
let mut import_block = import_block.clear_storage_changes_and_mutate();
|
let mut import_block = import_block.clear_storage_changes_and_mutate();
|
||||||
if let Some(state) = block.state {
|
if let Some(state) = block.state {
|
||||||
import_block.state_action = StateAction::ApplyChanges(crate::StorageChanges::Import(state));
|
import_block.state_action = StateAction::ApplyChanges(crate::StorageChanges::Import(state));
|
||||||
|
|||||||
@@ -560,6 +560,7 @@ mod tests {
|
|||||||
hash,
|
hash,
|
||||||
header: Some(header),
|
header: Some(header),
|
||||||
body: None,
|
body: None,
|
||||||
|
indexed_body: None,
|
||||||
justifications: None,
|
justifications: None,
|
||||||
origin: None,
|
origin: None,
|
||||||
allow_missing_state: false,
|
allow_missing_state: false,
|
||||||
|
|||||||
@@ -102,6 +102,16 @@ impl<Block: BlockT, Executor, G: GenesisInit> TestClientBuilder<Block, Executor,
|
|||||||
let backend = Arc::new(Backend::new_test(keep_blocks, 0));
|
let backend = Arc::new(Backend::new_test(keep_blocks, 0));
|
||||||
Self::with_backend(backend)
|
Self::with_backend(backend)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create new `TestClientBuilder` with default backend and storage chain mode
|
||||||
|
pub fn with_tx_storage(keep_blocks: u32) -> Self {
|
||||||
|
let backend = Arc::new(Backend::new_test_with_tx_storage(
|
||||||
|
keep_blocks,
|
||||||
|
0,
|
||||||
|
sc_client_db::TransactionStorageMode::StorageChain,
|
||||||
|
));
|
||||||
|
Self::with_backend(backend)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Block: BlockT, Executor, Backend, G: GenesisInit> TestClientBuilder<Block, Executor, Backend, G> {
|
impl<Block: BlockT, Executor, Backend, G: GenesisInit> TestClientBuilder<Block, Executor, Backend, G> {
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ pub enum Extrinsic {
|
|||||||
ChangesTrieConfigUpdate(Option<ChangesTrieConfiguration>),
|
ChangesTrieConfigUpdate(Option<ChangesTrieConfiguration>),
|
||||||
OffchainIndexSet(Vec<u8>, Vec<u8>),
|
OffchainIndexSet(Vec<u8>, Vec<u8>),
|
||||||
OffchainIndexClear(Vec<u8>),
|
OffchainIndexClear(Vec<u8>),
|
||||||
|
Store(Vec<u8>),
|
||||||
}
|
}
|
||||||
|
|
||||||
parity_util_mem::malloc_size_of_is_0!(Extrinsic); // non-opaque extrinsic does not need this
|
parity_util_mem::malloc_size_of_is_0!(Extrinsic); // non-opaque extrinsic does not need this
|
||||||
@@ -199,6 +200,7 @@ impl BlindCheckable for Extrinsic {
|
|||||||
Ok(Extrinsic::OffchainIndexSet(key, value)),
|
Ok(Extrinsic::OffchainIndexSet(key, value)),
|
||||||
Extrinsic::OffchainIndexClear(key) =>
|
Extrinsic::OffchainIndexClear(key) =>
|
||||||
Ok(Extrinsic::OffchainIndexClear(key)),
|
Ok(Extrinsic::OffchainIndexClear(key)),
|
||||||
|
Extrinsic::Store(data) => Ok(Extrinsic::Store(data)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -272,6 +272,8 @@ fn execute_transaction_backend(utx: &Extrinsic, extrinsic_index: u32) -> ApplyEx
|
|||||||
sp_io::offchain_index::clear(&key);
|
sp_io::offchain_index::clear(&key);
|
||||||
Ok(Ok(()))
|
Ok(Ok(()))
|
||||||
}
|
}
|
||||||
|
Extrinsic::Store(data) =>
|
||||||
|
execute_store(data.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,6 +303,13 @@ fn execute_transfer_backend(tx: &Transfer) -> ApplyExtrinsicResult {
|
|||||||
Ok(Ok(()))
|
Ok(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn execute_store(data: Vec<u8>) -> ApplyExtrinsicResult {
|
||||||
|
let content_hash = sp_io::hashing::blake2_256(&data);
|
||||||
|
let extrinsic_index: u32 = storage::unhashed::get(well_known_keys::EXTRINSIC_INDEX).unwrap();
|
||||||
|
sp_io::transaction_index::index(extrinsic_index, data.len() as u32, content_hash);
|
||||||
|
Ok(Ok(()))
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_new_authorities_backend(new_authorities: &[AuthorityId]) -> ApplyExtrinsicResult {
|
fn execute_new_authorities_backend(new_authorities: &[AuthorityId]) -> ApplyExtrinsicResult {
|
||||||
NewAuthorities::put(new_authorities.to_vec());
|
NewAuthorities::put(new_authorities.to_vec());
|
||||||
Ok(Ok(()))
|
Ok(Ok(()))
|
||||||
|
|||||||
Reference in New Issue
Block a user