Skip to content
Merged
4 changes: 4 additions & 0 deletions chainspecs/plain_spec_finney.json
Original file line number Diff line number Diff line change
Expand Up @@ -105142,5 +105142,9 @@
}
}
}
},
"grandpaWarpSyncCheckpoint": {
"finalizedBlockHeader": "0xc03558186a0676467b1b2e4880c4f1dbde6acbd1e8399e48b408242b732f59eee2391d028b8094d0b3533319529c1b9f924aaf4810dec9be8001b12644b4771f54d63224cf4c23d6547a671f3391c592173e03d6403a949db43a8ac9b80196e994742f1914066175726120ba4be008000000000461757261090a0150dabc064c6e5cc3a0cedcf261c01fafbab51e2bc2cb4406ba2c6c642e086ff52a8c2993efeca89c5de543a908f1e71b5f1c2be45e1701021cc57f840d82a2f702bafed45bea146e871cfa990fba657a349eb816e77f76e211c3d7bfb1926baa2234be319e058fc1dd864c3e9e2722e0e6748eb9b0bc5885b60142cfbabcbb2c748caf0abca3bcc146d5223cf123759ba35a71ce0d020eedee53724c0e1572203aeea1cdcf2cfe4947c8b39af0cf97ae2d548e693ffee2b09e3d246075ef6672749840e6b1f55dedad1c2b385b0978902bbed1007e5d4490767ffb022eb83411255effe234def96ddbea1c4d4d67850b6c57808967d5b066358ed263a5471ff232689eaa5d627b821b760b23269f509921ad5da8c32ed5722bbccccf2e66e36f55ecf82af34921ec7e61e72ffac388fc16dd39470fbfe6fa2a43d379e42a837d5944716244c29353b6bca0edeb8dd114f27e0e14471bedc9e8060c7b801f57f3448cedbe6e90299446c8d03babe22b7e0e2b7689431170dd64da52eb96a0d06f7ff4150a46300dd97e3a11c084c54f7ca0fddc20acfa0c45dd70396a0eed2c3c09a839631d0fabea178ee72ce38c1324bfcb5c1bfad509eb4e25356477cee7db4606e241dc7f7694ab47b7c824e3c9e83bd6516a4a5c083f952b4db3d4d4e17c5d668ffb5da465590dc5684ee630be3e01b808e106b3547e212578348443f19b145286b1b6fe737cbdd2d5a380d78c8b62170c88ffd8ebb73d6351b4466ca70c1d02436f394a241292fe933de1322dc6d5d036ff0a20fd6f27d0bbfe190b11235c426ffb42e3c41abfd1f77fbc29083b3c80d49d32a70ea5c46ad1618554444e3740112f3d548b6316e3ec4b5da6cd1f9704708a4f31c1da267d4b9a040190db230446524e4b990c01503c0694d473b0203bd9842aabbac7ab7d73205a3ccf97096bc5361ea75dcdd0a4010000000000000045ddfeed53c360c0ad3a10fcf8b09b63f032a81152c73f8971fc71660c22b5cf01000000000000000c06118ac33cdf11a313778fd600e45b12af35c4e96fdfd1f24b622a47f5a6040100000000000000f55a9261d2d5cc475537c27d18158d3a0cae213fa87e305a345df2771a31e12501000000000000004077cc7f31e19faa539e089f8282e03f33318290a32fbad369dac950986dcd430100000000000000c40dd57ef4b2c4408548665620cbfd420f09cdaa2cb6056f77b5b769eddeaed00100000000000000ba5fb07ded8410d39649f8e30a3fb4ffa623c9232b30c14f1f42afb36f4bfb3b0100000000000000e96069b13bef0322f8e3e9bac94e303dafe1a6372736cc57a9f32d0b5231809501000000000000005201d27eb236bf32fa024f5c1c094513f084192e756a7511a3649db3b76ba2c30100000000000000600d1e6db2964a84b13569c2a437d8eab4888768b57b73bebca36cc214e836b80100000000000000477b9292e050855f808d743cbaccb52e9c00a5a96d8f0b091f87d1660d96609d0100000000000000370e2fadd6e17124db38edaf10045a039d136b52c125151f8aaa090a1554cd3801000000000000001d351649339513b4061077a469fee1f49f79a130bdc2cf54cdea3b3894c59cbc0100000000000000b8bc8e248f8a1e7c4f3c0954206f57a5a60d0a48418cc54f162b27289f2b3987010000000000000033f0e8e844911223d3c859f3283ca737bf33437d965ed34e350ddb3e5f49ae220100000000000000c92f57a27012a9c9fac61d3185c845c50622f0ac136fce99e62e2920c89dfbdd01000000000000001ac50d47914fdb8a1827b57f623b8aac857ad84a08d77c1ae606d7d24ec46945010000000000000046d41f69d5df314822236500c3d57687ce9b9db3f44f45a4ff91f02e27b3bc2d01000000000000001ab5cd4e35349c94a0516e3d4850cdfb174d23290fdf35e86dfca84d57a3a5c4010000000000000055b0f4f90805b1518d2de726d8767465440f54a5602c92fb0481a9c5eb0b17f80100000000000000000000000466726f6e0902011921a2d414f0a049fd2ec0a5a1fadd6037c94fa953a68b4288a7cd69f29ebcbc0caad2ce0f923890fdc0a3a6cf91026362615de9544092d615fb74acfb1d8dfa8f7b9d61e0baa3e37cf79e5f2e0348c19060423d677b8e7b17c3565173f1adfe3c0966626c2cd982cc30922d17c32bf3e1ddd0b8b785903dd703c6d99ba7f958da056175726101016262a0512462424da899a7a8eeb54deee118b4fa85b0bd931b4f847238baf61c9fe4ca23c2e2b4cfd23e8bcaed3d9fec8cd401d0dac8a3d517fb449946c28084",
"grandpaAuthoritySet": "0x0500000000000000503c0694d473b0203bd9842aabbac7ab7d73205a3ccf97096bc5361ea75dcdd0a4010000000000000045ddfeed53c360c0ad3a10fcf8b09b63f032a81152c73f8971fc71660c22b5cf01000000000000000c06118ac33cdf11a313778fd600e45b12af35c4e96fdfd1f24b622a47f5a6040100000000000000f55a9261d2d5cc475537c27d18158d3a0cae213fa87e305a345df2771a31e12501000000000000004077cc7f31e19faa539e089f8282e03f33318290a32fbad369dac950986dcd430100000000000000c40dd57ef4b2c4408548665620cbfd420f09cdaa2cb6056f77b5b769eddeaed00100000000000000ba5fb07ded8410d39649f8e30a3fb4ffa623c9232b30c14f1f42afb36f4bfb3b0100000000000000e96069b13bef0322f8e3e9bac94e303dafe1a6372736cc57a9f32d0b5231809501000000000000005201d27eb236bf32fa024f5c1c094513f084192e756a7511a3649db3b76ba2c30100000000000000600d1e6db2964a84b13569c2a437d8eab4888768b57b73bebca36cc214e836b801000000000000002c9f738dc1d390c4d9fdb8cdf030441f403ec3ce2d55049d96d6650604f9a07a010000000000000020f5d60bf0f880aa1624fb77895d6ba9c55e6e712c5072b7892595481acb054301000000000000003d362b97f2dbd334ee880489b8bf098478e2b4f25c7fe1db30ae0770d55748750100000000000000f3e7b8a7cb4e4916c6af512c74954c7f71708bfb6172e3ac898cbd87e94d8669010000000000000042c228a2ae6b5f9a587d5bd9fae23371c61bfc5030f2f75bd353828ee774ae9d0100000000000000aef7e3f9920dcfdcf8d84b4df5142cbcf82540a6720bbda8d08b6845b7f81ac301000000000000001bbdc4187afeaf58b851fd56b06ca49b522ccdeed5e727ee10415c03eeb12fd101000000000000005e1ac1aefc93081ca4973e8ea6a90eed26e6bab14e7f1bf4cbc400283533eda70100000000000000a26547efb9369cda4ac126d036e0ecdb08cc01feb095367cd120e3fbda85b2750100000000000000480a24a810ae53434a1db22b3ccb1644bb9c17295c742f96b53534de697926930100000000000000"
}
}
4 changes: 4 additions & 0 deletions chainspecs/raw_spec_finney.json
Original file line number Diff line number Diff line change
Expand Up @@ -47742,5 +47742,9 @@
},
"childrenDefault": {}
}
},
"grandpaWarpSyncCheckpoint": {
"finalizedBlockHeader": "0xc03558186a0676467b1b2e4880c4f1dbde6acbd1e8399e48b408242b732f59eee2391d028b8094d0b3533319529c1b9f924aaf4810dec9be8001b12644b4771f54d63224cf4c23d6547a671f3391c592173e03d6403a949db43a8ac9b80196e994742f1914066175726120ba4be008000000000461757261090a0150dabc064c6e5cc3a0cedcf261c01fafbab51e2bc2cb4406ba2c6c642e086ff52a8c2993efeca89c5de543a908f1e71b5f1c2be45e1701021cc57f840d82a2f702bafed45bea146e871cfa990fba657a349eb816e77f76e211c3d7bfb1926baa2234be319e058fc1dd864c3e9e2722e0e6748eb9b0bc5885b60142cfbabcbb2c748caf0abca3bcc146d5223cf123759ba35a71ce0d020eedee53724c0e1572203aeea1cdcf2cfe4947c8b39af0cf97ae2d548e693ffee2b09e3d246075ef6672749840e6b1f55dedad1c2b385b0978902bbed1007e5d4490767ffb022eb83411255effe234def96ddbea1c4d4d67850b6c57808967d5b066358ed263a5471ff232689eaa5d627b821b760b23269f509921ad5da8c32ed5722bbccccf2e66e36f55ecf82af34921ec7e61e72ffac388fc16dd39470fbfe6fa2a43d379e42a837d5944716244c29353b6bca0edeb8dd114f27e0e14471bedc9e8060c7b801f57f3448cedbe6e90299446c8d03babe22b7e0e2b7689431170dd64da52eb96a0d06f7ff4150a46300dd97e3a11c084c54f7ca0fddc20acfa0c45dd70396a0eed2c3c09a839631d0fabea178ee72ce38c1324bfcb5c1bfad509eb4e25356477cee7db4606e241dc7f7694ab47b7c824e3c9e83bd6516a4a5c083f952b4db3d4d4e17c5d668ffb5da465590dc5684ee630be3e01b808e106b3547e212578348443f19b145286b1b6fe737cbdd2d5a380d78c8b62170c88ffd8ebb73d6351b4466ca70c1d02436f394a241292fe933de1322dc6d5d036ff0a20fd6f27d0bbfe190b11235c426ffb42e3c41abfd1f77fbc29083b3c80d49d32a70ea5c46ad1618554444e3740112f3d548b6316e3ec4b5da6cd1f9704708a4f31c1da267d4b9a040190db230446524e4b990c01503c0694d473b0203bd9842aabbac7ab7d73205a3ccf97096bc5361ea75dcdd0a4010000000000000045ddfeed53c360c0ad3a10fcf8b09b63f032a81152c73f8971fc71660c22b5cf01000000000000000c06118ac33cdf11a313778fd600e45b12af35c4e96fdfd1f24b622a47f5a6040100000000000000f55a9261d2d5cc475537c27d18158d3a0cae213fa87e305a345df2771a31e12501000000000000004077cc7f31e19faa539e089f8282e03f33318290a32fbad369dac950986dcd430100000000000000c40dd57ef4b2c4408548665620cbfd420f09cdaa2cb6056f77b5b769eddeaed00100000000000000ba5fb07ded8410d39649f8e30a3fb4ffa623c9232b30c14f1f42afb36f4bfb3b0100000000000000e96069b13bef0322f8e3e9bac94e303dafe1a6372736cc57a9f32d0b5231809501000000000000005201d27eb236bf32fa024f5c1c094513f084192e756a7511a3649db3b76ba2c30100000000000000600d1e6db2964a84b13569c2a437d8eab4888768b57b73bebca36cc214e836b80100000000000000477b9292e050855f808d743cbaccb52e9c00a5a96d8f0b091f87d1660d96609d0100000000000000370e2fadd6e17124db38edaf10045a039d136b52c125151f8aaa090a1554cd3801000000000000001d351649339513b4061077a469fee1f49f79a130bdc2cf54cdea3b3894c59cbc0100000000000000b8bc8e248f8a1e7c4f3c0954206f57a5a60d0a48418cc54f162b27289f2b3987010000000000000033f0e8e844911223d3c859f3283ca737bf33437d965ed34e350ddb3e5f49ae220100000000000000c92f57a27012a9c9fac61d3185c845c50622f0ac136fce99e62e2920c89dfbdd01000000000000001ac50d47914fdb8a1827b57f623b8aac857ad84a08d77c1ae606d7d24ec46945010000000000000046d41f69d5df314822236500c3d57687ce9b9db3f44f45a4ff91f02e27b3bc2d01000000000000001ab5cd4e35349c94a0516e3d4850cdfb174d23290fdf35e86dfca84d57a3a5c4010000000000000055b0f4f90805b1518d2de726d8767465440f54a5602c92fb0481a9c5eb0b17f80100000000000000000000000466726f6e0902011921a2d414f0a049fd2ec0a5a1fadd6037c94fa953a68b4288a7cd69f29ebcbc0caad2ce0f923890fdc0a3a6cf91026362615de9544092d615fb74acfb1d8dfa8f7b9d61e0baa3e37cf79e5f2e0348c19060423d677b8e7b17c3565173f1adfe3c0966626c2cd982cc30922d17c32bf3e1ddd0b8b785903dd703c6d99ba7f958da056175726101016262a0512462424da899a7a8eeb54deee118b4fa85b0bd931b4f847238baf61c9fe4ca23c2e2b4cfd23e8bcaed3d9fec8cd401d0dac8a3d517fb449946c28084",
"grandpaAuthoritySet": "0x0500000000000000503c0694d473b0203bd9842aabbac7ab7d73205a3ccf97096bc5361ea75dcdd0a4010000000000000045ddfeed53c360c0ad3a10fcf8b09b63f032a81152c73f8971fc71660c22b5cf01000000000000000c06118ac33cdf11a313778fd600e45b12af35c4e96fdfd1f24b622a47f5a6040100000000000000f55a9261d2d5cc475537c27d18158d3a0cae213fa87e305a345df2771a31e12501000000000000004077cc7f31e19faa539e089f8282e03f33318290a32fbad369dac950986dcd430100000000000000c40dd57ef4b2c4408548665620cbfd420f09cdaa2cb6056f77b5b769eddeaed00100000000000000ba5fb07ded8410d39649f8e30a3fb4ffa623c9232b30c14f1f42afb36f4bfb3b0100000000000000e96069b13bef0322f8e3e9bac94e303dafe1a6372736cc57a9f32d0b5231809501000000000000005201d27eb236bf32fa024f5c1c094513f084192e756a7511a3649db3b76ba2c30100000000000000600d1e6db2964a84b13569c2a437d8eab4888768b57b73bebca36cc214e836b801000000000000002c9f738dc1d390c4d9fdb8cdf030441f403ec3ce2d55049d96d6650604f9a07a010000000000000020f5d60bf0f880aa1624fb77895d6ba9c55e6e712c5072b7892595481acb054301000000000000003d362b97f2dbd334ee880489b8bf098478e2b4f25c7fe1db30ae0770d55748750100000000000000f3e7b8a7cb4e4916c6af512c74954c7f71708bfb6172e3ac898cbd87e94d8669010000000000000042c228a2ae6b5f9a587d5bd9fae23371c61bfc5030f2f75bd353828ee774ae9d0100000000000000aef7e3f9920dcfdcf8d84b4df5142cbcf82540a6720bbda8d08b6845b7f81ac301000000000000001bbdc4187afeaf58b851fd56b06ca49b522ccdeed5e727ee10415c03eeb12fd101000000000000005e1ac1aefc93081ca4973e8ea6a90eed26e6bab14e7f1bf4cbc400283533eda70100000000000000a26547efb9369cda4ac126d036e0ecdb08cc01feb095367cd120e3fbda85b2750100000000000000480a24a810ae53434a1db22b3ccb1644bb9c17295c742f96b53534de697926930100000000000000"
}
}
12 changes: 12 additions & 0 deletions node/src/chain_spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,20 @@ pub struct Extensions {
pub fork_blocks: sc_client_api::ForkBlocks<Block>,
/// Known bad block hashes.
pub bad_blocks: sc_client_api::BadBlocks<Block>,
/// A trusted finalized checkpoint for bootstrapping warp sync.
pub grandpa_warp_sync_checkpoint: GrandpaWarpSyncCheckpointExtension,
}

/// A trusted GRANDPA authority checkpoint used to verify warp proofs.
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GrandpaWarpSyncCheckpoint {
pub finalized_block_header: String,
pub grandpa_authority_set: String,
}

pub type GrandpaWarpSyncCheckpointExtension = Option<GrandpaWarpSyncCheckpoint>;

/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.
pub type ChainSpec = sc_service::GenericChainSpec<Extensions>;

Expand Down
7 changes: 7 additions & 0 deletions node/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ pub struct Cli {
/// For `build-patched-spec`, the implicit default is `skip` unless this flag is explicitly set.
#[arg(long, value_enum, default_value_t = HistoryBackfill::Keep)]
pub history_backfill: HistoryBackfill,

/// Expose `grandpa_genWarpSyncCheckpoint` for generating a trusted warp-sync checkpoint.
///
/// The response is compact but requires retained GRANDPA transition history. Public endpoints
/// should apply their normal RPC rate limits.
#[arg(long, default_value_t = false)]
pub enable_warp_sync_checkpoint_rpc: bool,
}

#[allow(clippy::large_enum_variant)]
Expand Down
2 changes: 2 additions & 0 deletions node/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ fn start_babe_service(
cli.sealing,
None,
skip_history_backfill,
cli.enable_warp_sync_checkpoint_rpc,
)
.await
}) {
Expand Down Expand Up @@ -346,6 +347,7 @@ fn start_aura_service(
cli.sealing,
Some(custom_service_signal_clone),
skip_history_backfill,
cli.enable_warp_sync_checkpoint_rpc,
)
.await
}) {
Expand Down
72 changes: 55 additions & 17 deletions node/src/service.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.

mod grandpa_warp_sync;
mod warp_sync_checkpoint;

use crate::consensus::ConsensusMechanism;
use futures::{FutureExt, StreamExt as _, channel::mpsc};
Expand Down Expand Up @@ -50,6 +51,32 @@ pub type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;
pub type GrandpaBlockImport =
sc_consensus_grandpa::GrandpaBlockImport<FullBackend, Block, FullClient, FullSelectChain>;
type GrandpaLinkHalf = sc_consensus_grandpa::LinkHalf<Block, FullClient, FullSelectChain>;

fn warp_sync_provider(
genesis_hash: H256,
chain_type: sc_chain_spec::ChainType,
backend: Arc<FullBackend>,
authority_set: sc_consensus_grandpa::SharedAuthoritySet<H256, NumberFor<Block>>,
trusted_checkpoint: Option<sc_consensus_grandpa::AuthoritySetHardFork<Block>>,
) -> WarpSyncConfig<Block> {
let warp_sync_config = grandpa_warp_sync::config(genesis_hash, chain_type);
log::warn!("{}", warp_sync_config.log_message());
let initial_set_id = warp_sync_config.one_time_initial_set_id(trusted_checkpoint.is_some());
let inner = sc_consensus_grandpa::warp_proof::NetworkProvider::new(
backend,
authority_set,
warp_sync_config.into_hard_forks(trusted_checkpoint),
);
let provider: Arc<dyn WarpSyncProvider<Block>> = match initial_set_id {
Some(initial_set_id) => Arc::new(grandpa_warp_sync::InitialSetIdProvider::new(
inner,
initial_set_id,
)),
None => Arc::new(inner),
};

WarpSyncConfig::WithProvider(provider)
}
#[allow(clippy::upper_case_acronyms)]
pub type BIQ<'a> = Box<
dyn FnOnce(
Expand Down Expand Up @@ -264,6 +291,7 @@ pub async fn new_full<NB, CM>(
sealing: Option<Sealing>,
custom_service_signal: Option<Arc<AtomicBool>>,
skip_history_backfill: bool,
enable_warp_sync_checkpoint_rpc: bool,
) -> Result<TaskManager, ServiceError>
where
NumberFor<Block>: BlockNumberOps,
Expand Down Expand Up @@ -322,24 +350,24 @@ where
None
} else {
net_config.add_notification_protocol(grandpa_protocol_config);
let warp_sync_config =
grandpa_warp_sync::config(genesis_hash, config.chain_spec.chain_type());
log::warn!("{}", warp_sync_config.log_message());
let initial_set_id = warp_sync_config.one_time_initial_set_id();
let inner = sc_consensus_grandpa::warp_proof::NetworkProvider::new(
let trusted_checkpoint =
warp_sync_checkpoint::trusted_checkpoint(config.chain_spec.as_ref())?;
if let Some(checkpoint) = trusted_checkpoint.as_ref() {
log::info!(
target: LOG_TARGET,
"Using trusted GRANDPA authority checkpoint at #{} ({:?}), set ID {}",
checkpoint.block.1,
checkpoint.block.0,
checkpoint.set_id,
);
}
Some(warp_sync_provider(
genesis_hash,
config.chain_spec.chain_type(),
backend.clone(),
grandpa_link.shared_authority_set().clone(),
warp_sync_config.into_hard_forks(),
);
let warp_sync: Arc<dyn WarpSyncProvider<Block>> = match initial_set_id {
Some(initial_set_id) => Arc::new(grandpa_warp_sync::InitialSetIdProvider::new(
inner,
initial_set_id,
)),
None => Arc::new(inner),
};

Some(WarpSyncConfig::WithProvider(warp_sync))
trusted_checkpoint,
))
};

let (network, system_rpc_tx, tx_handler_controller, sync_service) =
Expand Down Expand Up @@ -462,11 +490,18 @@ where
async move { CM::pending_create_inherent_data_providers(slot_duration, keystore) }
};

let rpc_methods = consensus_mechanism.rpc_methods(
let mut rpc_methods = consensus_mechanism.rpc_methods(
client.clone(),
keystore_container.keystore(),
select_chain.clone(),
)?;
if enable_warp_sync_checkpoint_rpc {
rpc_methods.push(warp_sync_checkpoint::rpc_methods(
config.chain_spec.cloned_box(),
client.clone(),
grandpa_link.shared_authority_set().clone(),
)?);
}
Box::new(move |subscription_task_executor| {
let eth_deps = crate::rpc::EthDeps {
client: client.clone(),
Expand Down Expand Up @@ -669,6 +704,7 @@ pub async fn build_full<CM: ConsensusMechanism>(
sealing: Option<Sealing>,
custom_service_signal: Option<Arc<AtomicBool>>,
skip_history_backfill: bool,
enable_warp_sync_checkpoint_rpc: bool,
) -> Result<TaskManager, ServiceError> {
match config.network.network_backend {
sc_network::config::NetworkBackendType::Libp2p => {
Expand All @@ -678,6 +714,7 @@ pub async fn build_full<CM: ConsensusMechanism>(
sealing,
custom_service_signal,
skip_history_backfill,
enable_warp_sync_checkpoint_rpc,
)
.await
}
Expand All @@ -688,6 +725,7 @@ pub async fn build_full<CM: ConsensusMechanism>(
sealing,
custom_service_signal,
skip_history_backfill,
enable_warp_sync_checkpoint_rpc,
)
.await
}
Expand Down
Loading
Loading