Implement hardcoded sync in the light client#8075
Conversation
|
It looks like @tomaka signed our Contributor License Agreement. 👍 Many thanks, Parity Technologies CLA Bot |
| let cht_num = cht::block_to_cht_number(decoded_header.number() - 1) | ||
| .expect("specs provided a hardcoded block with height 0"); | ||
| if cht_num >= hardcoded_sync.chts.len() as u64 { | ||
| panic!("specs didn't provide enough CHT roots for its hardcoded block"); |
There was a problem hiding this comment.
rule for panics of any kind is "prove or remove" -- We may rather want to print a warning and fall back to hardcoded-less sync. Or move these checks to the deserialization phase where we can exit with an error more gracefully.
| /// | ||
| /// If the block is an epoch transition, provide the transition along with | ||
| /// the header. | ||
| #[inline] |
There was a problem hiding this comment.
does that actually help? generally I figure LLVM will figure it out.
| let header = if let Some(header) = self.block_header(BlockId::Number(h_num)) { | ||
| header | ||
| } else { | ||
| panic!("Header of block #{} not found in DB", h_num); |
|
|
||
| let decoded = header.decode(); | ||
|
|
||
| let entry: Entry = ::rlp::decode(&self.db.get(self.col, era_key(h_num).as_bytes()).unwrap().unwrap()); |
There was a problem hiding this comment.
and we really never use unwrap.
| let entry: Entry = ::rlp::decode(&self.db.get(self.col, era_key(h_num).as_bytes()).unwrap().unwrap()); | ||
| let total_difficulty = entry.candidates.iter() | ||
| .find(|c| c.hash == decoded.hash()) | ||
| .expect("no candidate matching block found in DB") |
There was a problem hiding this comment.
should rather prove based on the fact that an inconsistent but correctly-loaded database shouldn't be possible.
| chts.push(cht); | ||
| } | ||
|
|
||
| unreachable!("we are after an infinite loop") |
There was a problem hiding this comment.
could be a loop with a break-value, either way it could follow the codebase style of proposition; proof; qed
| let client = service.client(); | ||
| // Note: uncomment this code if you want to regenerate the JSON of the hardcoded sync feature | ||
| // in the chain specifications. | ||
| /*if let Some(hs) = client.read_hardcoded_sync() { |
There was a problem hiding this comment.
we could make this a subcommand of some kind
There was a problem hiding this comment.
generally not a fan of the commented-out code. the CLI is a PITA to work with though :\
|
needs an opt-out flag also (off by default is fine, just that it should be there). |
|
looks good other than grumbles |
|
Should I make |
|
|
|
Sorry for the bad PR quality. I think it should be good now! |
|
needs merge, can you ping me for review? I'm not looking that closely at the Parity repo these days. |
|
@rphmeier Conflicts solved! |
| let on_demand = Arc::new(::light::on_demand::OnDemand::new(cache.clone())); | ||
|
|
||
| let sync_handle = Arc::new(RwLock::new(Weak::new())); | ||
| let fetch = ::light_helpers::EpochFetch { |
There was a problem hiding this comment.
on_demand, sync, network etc. are not necessary to start here -- a NoOpEpochFetch (I think it already exists for tests) will be enough.
|
LGTM except for grumble |
|
r? |
| "header": "f90219a061d694007fbaca6e23e73e29c8c6a60099abc740ab7e27ae3cd1b9c6a47efef7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347945a0b54d5dc17e0aadc383d2db43b0a0d3e029c4ca0a2f1bdabc1a72737de1c22a76cacc8fc162366904f759a99db7d6d19efee3090a0ac5f5b236e8977928a2ce43c7569ea5a74919643cb0b06d7540407b1ea1298f0a04356ddc5d77c83923a6541260308be167386e0969a608a017770c9e38091cfcab90100a00010002001009080011010141088000004000080081100000a002023000002204204801204084000c000010008000000000880080020c0000440200460000290005010c01c80800080004800100406003380000400402040000028084002a80087000008090a00200100544020019580022000000306100a0080100084020006809000e80000010000254810002000000a240050014200002002c10809202030006422022000203012000241089300080400000009001021020200012410348500028290230408100302000000058c0000020c08c20480081040020260004008481000080000800010010060020000e00020002140100a8988000004400201870b9af4a66df8038350a8018379d54483799eba845ab0426d984554482e45544846414e532e4f52472d3231323134313232a05eeccc80302d8fecca48a47be03654b5a41b5e5f296f271f910ebae631124f518890074810024c6c2b", | ||
| "totalDifficulty": "3144406426008470895785", | ||
| "CHTs": [ | ||
| "0x0eb474b7721727204978e92e27d31cddff56471911e424a4c8271c35f9c982cc", |
There was a problem hiding this comment.
Is this anyhow possible without adding 2500 CHTs to the chain spec?
There was a problem hiding this comment.
Hmmm, what would the alternative be? We're hardcoding headers in the client after all, we have to put them somewhere.
There was a problem hiding this comment.
the alternative is to allow the client to be deployed w/o history or CHT roots and have the history fetched afterwards
Adds a
hardcodedSyncfield to the chain specifications.When set, contains the RLP of a header, a total difficulty, and a list of CHT root hashes. If there is no light client database, the light client will immediately jump to the given block.
After this change, the light client synchronizes in 10 to 15 seconds even at the first launch on the main network.
For now only the specs of the main network have been updated.