serai/substrate/node/src/service.rs

418 lines
14 KiB
Rust
Raw Normal View History

use std::{boxed::Box, sync::Arc};
use futures_util::stream::StreamExt;
use sp_timestamp::InherentDataProvider as TimestampInherent;
use sp_consensus_babe::{SlotDuration, inherents::InherentDataProvider as BabeInherent};
Initial Tendermint implementation (#145) * Machine without timeouts * Time code * Move substrate/consensus/tendermint to substrate/tendermint * Delete the old paper doc * Refactor out external parts to generics Also creates a dedicated file for the message log. * Refactor <V, B> to type V, type B * Successfully compiling * Calculate timeouts * Fix test * Finish timeouts * Misc cleanup * Define a signature scheme trait * Implement serialization via parity's scale codec Ideally, this would be generic. Unfortunately, the generic API serde doesn't natively support borsh, nor SCALE, and while there is a serde SCALE crate, it's old. While it may be complete, it's not worth working with. While we could still grab bincode, and a variety of other formats, it wasn't worth it to go custom and for Serai, we'll be using SCALE almost everywhere anyways. * Implement usage of the signature scheme * Make the infinite test non-infinite * Provide a dedicated signature in Precommit of just the block hash Greatly simplifies verifying when syncing. * Dedicated Commit object Restores sig aggregation API. * Tidy README * Document tendermint * Sign the ID directly instead of its SCALE encoding For a hash, which is fixed-size, these should be the same yet this helps move past the dependency on SCALE. It also, for any type where the two values are different, smooths integration. * Litany of bug fixes Also attempts to make the code more readable while updating/correcting documentation. * Remove async recursion Greatly increases safety as well by ensuring only one message is processed at once. * Correct timing issues 1) Commit didn't include the round, leaving the clock in question. 2) Machines started with a local time, instead of a proper start time. 3) Machines immediately started the next block instead of waiting for the block time. * Replace MultiSignature with sr25519::Signature * Minor SignatureScheme API changes * Map TM SignatureScheme to Substrate's sr25519 * Initial work on an import queue * Properly use check_block * Rename import to import_queue * Implement tendermint_machine::Block for Substrate Blocks Unfortunately, this immediately makes Tendermint machine capable of deployment as crate since it uses a git reference. In the future, a Cargo.toml patch section for serai/substrate should be investigated. This is being done regardless as it's the quickest way forward and this is for Serai. * Dummy Weights * Move documentation to the top of the file * Move logic into TendermintImport itself Multiple traits exist to verify/handle blocks. I'm unsure exactly when each will be called in the pipeline, so the easiest solution is to have every step run every check. That would be extremely computationally expensive if we ran EVERY check, yet we rely on Substrate for execution (and according checks), which are limited to just the actual import function. Since we're calling this code from many places, it makes sense for it to be consolidated under TendermintImport. * BlockImport, JustificationImport, Verifier, and import_queue function * Update consensus/lib.rs from PoW to Tendermint Not possible to be used as the previous consensus could. It will not produce blocks nor does it currenly even instantiate a machine. This is just he next step. * Update Cargo.tomls for substrate packages * Tendermint SelectChain This is incompatible with Substrate's expectations, yet should be valid for ours * Move the node over to the new SelectChain * Minor tweaks * Update SelectChain documentation * Remove substrate/node lib.rs This shouldn't be used as a library AFAIK. While runtime should be, and arguably should even be published, I have yet to see node in the same way. Helps tighten API boundaries. * Remove unused macro_use * Replace panicking todos with stubs and // TODO Enables progress. * Reduce chain_spec and use more accurate naming * Implement block proposal logic * Modularize to get_proposal * Trigger block importing Doesn't wait for the response yet, which it needs to. * Get the result of block importing * Split import_queue into a series of files * Provide a way to create the machine The BasicQueue returned obscures the TendermintImport struct. Accordingly, a Future scoped with access is returned upwards, which when awaited will create the machine. This makes creating the machine optional while maintaining scope boundaries. Is sufficient to create a 1-node net which produces and finalizes blocks. * Don't import justifications multiple times Also don't broadcast blocks which were solely proposed. * Correct justication import pipeline Removes JustificationImport as it should never be used. * Announce blocks By claiming File, they're not sent ovber the P2P network before they have a justification, as desired. Unfortunately, they never were. This works around that. * Add an assert to verify proposed children aren't best * Consolidate C and I generics into a TendermintClient trait alias * Expand sanity checks Substrate doesn't expect nor officially support children with less work than their parents. It's a trick used here. Accordingly, ensure the trick's validity. * When resetting, use the end time of the round which was committed to The machine reset to the end time of the current round. For a delayed network connection, a machine may move ahead in rounds and only later realize a prior round succeeded. Despite acknowledging that round's success, it would maintain its delay when moving to the next block, bricking it. Done by tracking the end time for each round as they occur. * Move Commit from including the round to including the round's end_time The round was usable to build the current clock in an accumulated fashion, relative to the previous round. The end time is the absolute metric of it, which can be used to calculate the round number (with all previous end times). Substrate now builds off the best block, not genesis, using the end time included in the justification to start its machine in a synchronized state. Knowing the end time of a round, or the round in which block was committed to, is necessary for nodes to sync up with Tendermint. Encoding it in the commit ensures it's long lasting and makes it readily available, without the load of an entire transaction. * Add a TODO on Tendermint * Misc bug fixes * More misc bug fixes * Clean up lock acquisition * Merge weights and signing scheme into validators, documenting needed changes * Add pallet sessions to runtime, create pallet-tendermint * Update node to use pallet sessions * Update support URL * Partial work on correcting pallet calls * Redo Tendermint folder structure * TendermintApi, compilation fixes * Fix the stub round robin At some point, the modulus was removed causing it to exceed the validators list and stop proposing. * Use the validators list from the session pallet * Basic Gossip Validator * Correct Substrate Tendermint start block The Tendermint machine uses the passed in number as the block's being worked on number. Substrate passed in the already finalized block's number. Also updates misc comments. * Clean generics in Tendermint with a monolith with associated types * Remove the Future triggering the machine for an async fn Enables passing data in, such as the network. * Move TendermintMachine from start_num, time to last_num, time Provides an explicitly clear API clearer to program around. Also adds additional time code to handle an edge case. * Connect the Tendermint machine to a GossipEngine * Connect broadcast * Remove machine from TendermintImport It's not used there at all. * Merge Verifier into block_import.rs These two files were largely the same, just hooking into sync structs with almost identical imports. As this project shapes up, removing dead weight is appreciated. * Create a dedicated file for being a Tendermint authority * Deleted comment code related to PoW * Move serai_runtime specific code from tendermint/client to node Renames serai-consensus to sc_tendermint * Consolidate file structure in sc_tendermint * Replace best_* with finalized_* We test their equivalency yet still better to use finalized_* in general. * Consolidate references to sr25519 in sc_tendermint * Add documentation to public structs/functions in sc_tendermint * Add another missing comment * Make sign asynchronous Some relation to https://github.com/serai-dex/serai/issues/95. * Move sc_tendermint to async sign * Implement proper checking of inherents * Take in a Keystore and validator ID * Remove unnecessary PhantomDatas * Update node to latest sc_tendermint * Configure node for a multi-node testnet * Fix handling of the GossipEngine * Use a rounded genesis to obtain sufficient synchrony within the Docker env * Correct Serai d-f names in Docker * Remove an attempt at caching I don't believe would ever hit * Add an already in chain check to block import While the inner should do this for us, we call verify_order on our end *before* inner to ensure sequential import. Accordingly, we need to provide our own check. Removes errors of "non-sequential import" when trying to re-import an existing block. * Update the consensus documentation It was incredibly out of date. * Add a _ to the validator arg in slash * Make the dev profile a local testnet profile Restores a dev profile which only has one validator, locally running. * Reduce Arcs in TendermintMachine, split Signer from SignatureScheme * Update sc_tendermint per previous commit * Restore cache * Remove error case which shouldn't be an error * Stop returning errors on already existing blocks entirely * Correct Dave, Eve, and Ferdie to not run as validators * Rename dev to devnet --dev still works thanks to the |. Acheieves a personal preference of mine with some historical meaning. * Add message expiry to the Tendermint gossip * Localize the LibP2P protocol to the blockchain Follows convention by doing so. Theoretically enables running multiple blockchains over a single LibP2P connection. * Add a version to sp-runtime in tendermint-machine * Add missing trait * Bump Substrate dependency Fixes #147. * Implement Schnorr half-aggregation from https://eprint.iacr.org/2021/350.pdf Relevant to https://github.com/serai-dex/serai/issues/99. * cargo update (tendermint) * Move from polling loops to a pure IO model for sc_tendermint's gossip * Correct protocol name handling * Use futures mpsc instead of tokio * Timeout futures * Move from a yielding loop to select in tendermint-machine * Update Substrate to the new TendermintHandle * Use futures pin instead of tokio * Only recheck blocks with non-fatal inherent transaction errors * Update to the latest substrate * Separate the block processing time from the latency * Add notes to the runtime * Don't spam slash Also adds a slash condition of failing to propose. * Support running TendermintMachine when not a validator This supports validators who leave the current set, without crashing their nodes, along with nodes trying to become validators (who will now seamlessly transition in). * Properly define and pass around the block size * Correct the Duration timing The proposer will build it, send it, then process it (on the first round). Accordingly, it's / 3, not / 2, as / 2 only accounted for the latter events. * Correct time-adjustment code on round skip * Have the machine respond to advances made by an external sync loop * Clean up time code in tendermint-machine * BlockData and RoundData structs * Rename Round to RoundNumber * Move BlockData to a new file * Move Round to an Option due to the pseudo-uninitialized state we create Before the addition of RoundData, we always created the round, and on .round(0), simply created it again. With RoundData, and the changes to the time code, we used round 0, time 0, the latter being incorrect yet not an issue due to lack of misuse. Now, if we do misuse it, it'll panic. * Clear the Queue instead of draining and filtering There shouldn't ever be a message which passes the filter under the current design. * BlockData::new * Move more code into block.rs Introduces type-aliases to obtain Data/Message/SignedMessage solely from a Network object. Fixes a bug regarding stepping when you're not an active validator. * Have verify_precommit_signature return if it verified the signature Also fixes a bug where invalid precommit signatures were left standing and therefore contributing to commits. * Remove the precommit signature hash It cached signatures per-block. Precommit signatures are bound to each round. This would lead to forming invalid commits when a commit should be formed. Under debug, the machine would catch that and panic. On release, it'd have everyone who wasn't a validator fail to continue syncing. * Slight doc changes Also flattens the message handling function by replacing an if containing all following code in the function with an early return for the else case. * Always produce notifications for finalized blocks via origin overrides * Correct weird formatting * Update to the latest tendermint-machine * Manually step the Tendermint machine when we synced a block over the network * Ignore finality notifications for old blocks * Remove a TODO resolved in 8c51bc011d03c8d54ded05011e7f4d1a01e9f873 * Add a TODO comment to slash Enables searching for the case-sensitive phrase and finding it. * cargo fmt * Use a tmp DB for Serai in Docker * Remove panic on slash As we move towards protonet, this can happen (if a node goes offline), yet it happening brings down the entire net right now. * Add log::error on slash * created shared volume between containers * Complete the sh scripts * Pass in the genesis time to Substrate * Correct block announcements They were announced, yet not marked best. * Correct pupulate_end_time It was used as inclusive yet didn't work inclusively. * Correct gossip channel jumping when a block is synced via Substrate * Use a looser check in import_future This triggered so it needs to be accordingly relaxed. * Correct race conditions between add_block and step Also corrects a <= to <. * Update cargo deny * rename genesis-service to genesis * Update Cargo.lock * Correct runtime Cargo.toml whitespace * Correct typo * Document recheck * Misc lints * Fix prev commit * Resolve low-hanging review comments * Mark genesis/entry-dev.sh as executable * Prevent a commit from including the same signature multiple times Yanks tendermint-machine 0.1.0 accordingly. * Update to latest nightly clippy * Improve documentation * Use clearer variable names * Add log statements * Pair more log statements * Clean TendermintAuthority::authority as possible Merges it into new. It has way too many arguments, yet there's no clear path at consolidation there, unfortunately. Additionally provides better scoping within itself. * Fix #158 Doesn't use lock_import_and_run for reasons commented (lack of async). * Rename guard to lock * Have the devnet use the current time as the genesis Possible since it's only a single node, not requiring synchronization. * Fix gossiping I really don't know what side effect this avoids and I can't say I care at this point. * Misc lints Co-authored-by: vrx00 <vrx00@proton.me> Co-authored-by: TheArchitect108 <TheArchitect108@protonmail.com>
2022-12-03 23:38:02 +00:00
use sp_io::SubstrateHostFunctions;
use sc_executor::{sp_wasm_interface::ExtendedHostFunctions, WasmExecutor};
use sc_network_common::sync::warp::WarpSyncParams;
use sc_network::{Event, NetworkEventStream};
Initial Tendermint implementation (#145) * Machine without timeouts * Time code * Move substrate/consensus/tendermint to substrate/tendermint * Delete the old paper doc * Refactor out external parts to generics Also creates a dedicated file for the message log. * Refactor <V, B> to type V, type B * Successfully compiling * Calculate timeouts * Fix test * Finish timeouts * Misc cleanup * Define a signature scheme trait * Implement serialization via parity's scale codec Ideally, this would be generic. Unfortunately, the generic API serde doesn't natively support borsh, nor SCALE, and while there is a serde SCALE crate, it's old. While it may be complete, it's not worth working with. While we could still grab bincode, and a variety of other formats, it wasn't worth it to go custom and for Serai, we'll be using SCALE almost everywhere anyways. * Implement usage of the signature scheme * Make the infinite test non-infinite * Provide a dedicated signature in Precommit of just the block hash Greatly simplifies verifying when syncing. * Dedicated Commit object Restores sig aggregation API. * Tidy README * Document tendermint * Sign the ID directly instead of its SCALE encoding For a hash, which is fixed-size, these should be the same yet this helps move past the dependency on SCALE. It also, for any type where the two values are different, smooths integration. * Litany of bug fixes Also attempts to make the code more readable while updating/correcting documentation. * Remove async recursion Greatly increases safety as well by ensuring only one message is processed at once. * Correct timing issues 1) Commit didn't include the round, leaving the clock in question. 2) Machines started with a local time, instead of a proper start time. 3) Machines immediately started the next block instead of waiting for the block time. * Replace MultiSignature with sr25519::Signature * Minor SignatureScheme API changes * Map TM SignatureScheme to Substrate's sr25519 * Initial work on an import queue * Properly use check_block * Rename import to import_queue * Implement tendermint_machine::Block for Substrate Blocks Unfortunately, this immediately makes Tendermint machine capable of deployment as crate since it uses a git reference. In the future, a Cargo.toml patch section for serai/substrate should be investigated. This is being done regardless as it's the quickest way forward and this is for Serai. * Dummy Weights * Move documentation to the top of the file * Move logic into TendermintImport itself Multiple traits exist to verify/handle blocks. I'm unsure exactly when each will be called in the pipeline, so the easiest solution is to have every step run every check. That would be extremely computationally expensive if we ran EVERY check, yet we rely on Substrate for execution (and according checks), which are limited to just the actual import function. Since we're calling this code from many places, it makes sense for it to be consolidated under TendermintImport. * BlockImport, JustificationImport, Verifier, and import_queue function * Update consensus/lib.rs from PoW to Tendermint Not possible to be used as the previous consensus could. It will not produce blocks nor does it currenly even instantiate a machine. This is just he next step. * Update Cargo.tomls for substrate packages * Tendermint SelectChain This is incompatible with Substrate's expectations, yet should be valid for ours * Move the node over to the new SelectChain * Minor tweaks * Update SelectChain documentation * Remove substrate/node lib.rs This shouldn't be used as a library AFAIK. While runtime should be, and arguably should even be published, I have yet to see node in the same way. Helps tighten API boundaries. * Remove unused macro_use * Replace panicking todos with stubs and // TODO Enables progress. * Reduce chain_spec and use more accurate naming * Implement block proposal logic * Modularize to get_proposal * Trigger block importing Doesn't wait for the response yet, which it needs to. * Get the result of block importing * Split import_queue into a series of files * Provide a way to create the machine The BasicQueue returned obscures the TendermintImport struct. Accordingly, a Future scoped with access is returned upwards, which when awaited will create the machine. This makes creating the machine optional while maintaining scope boundaries. Is sufficient to create a 1-node net which produces and finalizes blocks. * Don't import justifications multiple times Also don't broadcast blocks which were solely proposed. * Correct justication import pipeline Removes JustificationImport as it should never be used. * Announce blocks By claiming File, they're not sent ovber the P2P network before they have a justification, as desired. Unfortunately, they never were. This works around that. * Add an assert to verify proposed children aren't best * Consolidate C and I generics into a TendermintClient trait alias * Expand sanity checks Substrate doesn't expect nor officially support children with less work than their parents. It's a trick used here. Accordingly, ensure the trick's validity. * When resetting, use the end time of the round which was committed to The machine reset to the end time of the current round. For a delayed network connection, a machine may move ahead in rounds and only later realize a prior round succeeded. Despite acknowledging that round's success, it would maintain its delay when moving to the next block, bricking it. Done by tracking the end time for each round as they occur. * Move Commit from including the round to including the round's end_time The round was usable to build the current clock in an accumulated fashion, relative to the previous round. The end time is the absolute metric of it, which can be used to calculate the round number (with all previous end times). Substrate now builds off the best block, not genesis, using the end time included in the justification to start its machine in a synchronized state. Knowing the end time of a round, or the round in which block was committed to, is necessary for nodes to sync up with Tendermint. Encoding it in the commit ensures it's long lasting and makes it readily available, without the load of an entire transaction. * Add a TODO on Tendermint * Misc bug fixes * More misc bug fixes * Clean up lock acquisition * Merge weights and signing scheme into validators, documenting needed changes * Add pallet sessions to runtime, create pallet-tendermint * Update node to use pallet sessions * Update support URL * Partial work on correcting pallet calls * Redo Tendermint folder structure * TendermintApi, compilation fixes * Fix the stub round robin At some point, the modulus was removed causing it to exceed the validators list and stop proposing. * Use the validators list from the session pallet * Basic Gossip Validator * Correct Substrate Tendermint start block The Tendermint machine uses the passed in number as the block's being worked on number. Substrate passed in the already finalized block's number. Also updates misc comments. * Clean generics in Tendermint with a monolith with associated types * Remove the Future triggering the machine for an async fn Enables passing data in, such as the network. * Move TendermintMachine from start_num, time to last_num, time Provides an explicitly clear API clearer to program around. Also adds additional time code to handle an edge case. * Connect the Tendermint machine to a GossipEngine * Connect broadcast * Remove machine from TendermintImport It's not used there at all. * Merge Verifier into block_import.rs These two files were largely the same, just hooking into sync structs with almost identical imports. As this project shapes up, removing dead weight is appreciated. * Create a dedicated file for being a Tendermint authority * Deleted comment code related to PoW * Move serai_runtime specific code from tendermint/client to node Renames serai-consensus to sc_tendermint * Consolidate file structure in sc_tendermint * Replace best_* with finalized_* We test their equivalency yet still better to use finalized_* in general. * Consolidate references to sr25519 in sc_tendermint * Add documentation to public structs/functions in sc_tendermint * Add another missing comment * Make sign asynchronous Some relation to https://github.com/serai-dex/serai/issues/95. * Move sc_tendermint to async sign * Implement proper checking of inherents * Take in a Keystore and validator ID * Remove unnecessary PhantomDatas * Update node to latest sc_tendermint * Configure node for a multi-node testnet * Fix handling of the GossipEngine * Use a rounded genesis to obtain sufficient synchrony within the Docker env * Correct Serai d-f names in Docker * Remove an attempt at caching I don't believe would ever hit * Add an already in chain check to block import While the inner should do this for us, we call verify_order on our end *before* inner to ensure sequential import. Accordingly, we need to provide our own check. Removes errors of "non-sequential import" when trying to re-import an existing block. * Update the consensus documentation It was incredibly out of date. * Add a _ to the validator arg in slash * Make the dev profile a local testnet profile Restores a dev profile which only has one validator, locally running. * Reduce Arcs in TendermintMachine, split Signer from SignatureScheme * Update sc_tendermint per previous commit * Restore cache * Remove error case which shouldn't be an error * Stop returning errors on already existing blocks entirely * Correct Dave, Eve, and Ferdie to not run as validators * Rename dev to devnet --dev still works thanks to the |. Acheieves a personal preference of mine with some historical meaning. * Add message expiry to the Tendermint gossip * Localize the LibP2P protocol to the blockchain Follows convention by doing so. Theoretically enables running multiple blockchains over a single LibP2P connection. * Add a version to sp-runtime in tendermint-machine * Add missing trait * Bump Substrate dependency Fixes #147. * Implement Schnorr half-aggregation from https://eprint.iacr.org/2021/350.pdf Relevant to https://github.com/serai-dex/serai/issues/99. * cargo update (tendermint) * Move from polling loops to a pure IO model for sc_tendermint's gossip * Correct protocol name handling * Use futures mpsc instead of tokio * Timeout futures * Move from a yielding loop to select in tendermint-machine * Update Substrate to the new TendermintHandle * Use futures pin instead of tokio * Only recheck blocks with non-fatal inherent transaction errors * Update to the latest substrate * Separate the block processing time from the latency * Add notes to the runtime * Don't spam slash Also adds a slash condition of failing to propose. * Support running TendermintMachine when not a validator This supports validators who leave the current set, without crashing their nodes, along with nodes trying to become validators (who will now seamlessly transition in). * Properly define and pass around the block size * Correct the Duration timing The proposer will build it, send it, then process it (on the first round). Accordingly, it's / 3, not / 2, as / 2 only accounted for the latter events. * Correct time-adjustment code on round skip * Have the machine respond to advances made by an external sync loop * Clean up time code in tendermint-machine * BlockData and RoundData structs * Rename Round to RoundNumber * Move BlockData to a new file * Move Round to an Option due to the pseudo-uninitialized state we create Before the addition of RoundData, we always created the round, and on .round(0), simply created it again. With RoundData, and the changes to the time code, we used round 0, time 0, the latter being incorrect yet not an issue due to lack of misuse. Now, if we do misuse it, it'll panic. * Clear the Queue instead of draining and filtering There shouldn't ever be a message which passes the filter under the current design. * BlockData::new * Move more code into block.rs Introduces type-aliases to obtain Data/Message/SignedMessage solely from a Network object. Fixes a bug regarding stepping when you're not an active validator. * Have verify_precommit_signature return if it verified the signature Also fixes a bug where invalid precommit signatures were left standing and therefore contributing to commits. * Remove the precommit signature hash It cached signatures per-block. Precommit signatures are bound to each round. This would lead to forming invalid commits when a commit should be formed. Under debug, the machine would catch that and panic. On release, it'd have everyone who wasn't a validator fail to continue syncing. * Slight doc changes Also flattens the message handling function by replacing an if containing all following code in the function with an early return for the else case. * Always produce notifications for finalized blocks via origin overrides * Correct weird formatting * Update to the latest tendermint-machine * Manually step the Tendermint machine when we synced a block over the network * Ignore finality notifications for old blocks * Remove a TODO resolved in 8c51bc011d03c8d54ded05011e7f4d1a01e9f873 * Add a TODO comment to slash Enables searching for the case-sensitive phrase and finding it. * cargo fmt * Use a tmp DB for Serai in Docker * Remove panic on slash As we move towards protonet, this can happen (if a node goes offline), yet it happening brings down the entire net right now. * Add log::error on slash * created shared volume between containers * Complete the sh scripts * Pass in the genesis time to Substrate * Correct block announcements They were announced, yet not marked best. * Correct pupulate_end_time It was used as inclusive yet didn't work inclusively. * Correct gossip channel jumping when a block is synced via Substrate * Use a looser check in import_future This triggered so it needs to be accordingly relaxed. * Correct race conditions between add_block and step Also corrects a <= to <. * Update cargo deny * rename genesis-service to genesis * Update Cargo.lock * Correct runtime Cargo.toml whitespace * Correct typo * Document recheck * Misc lints * Fix prev commit * Resolve low-hanging review comments * Mark genesis/entry-dev.sh as executable * Prevent a commit from including the same signature multiple times Yanks tendermint-machine 0.1.0 accordingly. * Update to latest nightly clippy * Improve documentation * Use clearer variable names * Add log statements * Pair more log statements * Clean TendermintAuthority::authority as possible Merges it into new. It has way too many arguments, yet there's no clear path at consolidation there, unfortunately. Additionally provides better scoping within itself. * Fix #158 Doesn't use lock_import_and_run for reasons commented (lack of async). * Rename guard to lock * Have the devnet use the current time as the genesis Possible since it's only a single node, not requiring synchronization. * Fix gossiping I really don't know what side effect this avoids and I can't say I care at this point. * Misc lints Co-authored-by: vrx00 <vrx00@proton.me> Co-authored-by: TheArchitect108 <TheArchitect108@protonmail.com>
2022-12-03 23:38:02 +00:00
use sc_service::{error::Error as ServiceError, Configuration, TaskManager, TFullClient};
2023-07-19 02:30:55 +00:00
use sc_transaction_pool_api::OffchainTransactionPoolFactory;
use sc_client_api::{BlockBackend, Backend};
use sc_telemetry::{Telemetry, TelemetryWorker};
use serai_runtime::{Block, RuntimeApi};
use sc_consensus_babe::{self, SlotProportion};
use sc_consensus_grandpa as grandpa;
#[cfg(not(feature = "runtime-benchmarks"))]
pub type Executor = WasmExecutor<ExtendedHostFunctions<SubstrateHostFunctions, ()>>;
#[cfg(feature = "runtime-benchmarks")]
pub type Executor = WasmExecutor<
ExtendedHostFunctions<SubstrateHostFunctions, frame_benchmarking::benchmarking::HostFunctions>,
>;
Initial Tendermint implementation (#145) * Machine without timeouts * Time code * Move substrate/consensus/tendermint to substrate/tendermint * Delete the old paper doc * Refactor out external parts to generics Also creates a dedicated file for the message log. * Refactor <V, B> to type V, type B * Successfully compiling * Calculate timeouts * Fix test * Finish timeouts * Misc cleanup * Define a signature scheme trait * Implement serialization via parity's scale codec Ideally, this would be generic. Unfortunately, the generic API serde doesn't natively support borsh, nor SCALE, and while there is a serde SCALE crate, it's old. While it may be complete, it's not worth working with. While we could still grab bincode, and a variety of other formats, it wasn't worth it to go custom and for Serai, we'll be using SCALE almost everywhere anyways. * Implement usage of the signature scheme * Make the infinite test non-infinite * Provide a dedicated signature in Precommit of just the block hash Greatly simplifies verifying when syncing. * Dedicated Commit object Restores sig aggregation API. * Tidy README * Document tendermint * Sign the ID directly instead of its SCALE encoding For a hash, which is fixed-size, these should be the same yet this helps move past the dependency on SCALE. It also, for any type where the two values are different, smooths integration. * Litany of bug fixes Also attempts to make the code more readable while updating/correcting documentation. * Remove async recursion Greatly increases safety as well by ensuring only one message is processed at once. * Correct timing issues 1) Commit didn't include the round, leaving the clock in question. 2) Machines started with a local time, instead of a proper start time. 3) Machines immediately started the next block instead of waiting for the block time. * Replace MultiSignature with sr25519::Signature * Minor SignatureScheme API changes * Map TM SignatureScheme to Substrate's sr25519 * Initial work on an import queue * Properly use check_block * Rename import to import_queue * Implement tendermint_machine::Block for Substrate Blocks Unfortunately, this immediately makes Tendermint machine capable of deployment as crate since it uses a git reference. In the future, a Cargo.toml patch section for serai/substrate should be investigated. This is being done regardless as it's the quickest way forward and this is for Serai. * Dummy Weights * Move documentation to the top of the file * Move logic into TendermintImport itself Multiple traits exist to verify/handle blocks. I'm unsure exactly when each will be called in the pipeline, so the easiest solution is to have every step run every check. That would be extremely computationally expensive if we ran EVERY check, yet we rely on Substrate for execution (and according checks), which are limited to just the actual import function. Since we're calling this code from many places, it makes sense for it to be consolidated under TendermintImport. * BlockImport, JustificationImport, Verifier, and import_queue function * Update consensus/lib.rs from PoW to Tendermint Not possible to be used as the previous consensus could. It will not produce blocks nor does it currenly even instantiate a machine. This is just he next step. * Update Cargo.tomls for substrate packages * Tendermint SelectChain This is incompatible with Substrate's expectations, yet should be valid for ours * Move the node over to the new SelectChain * Minor tweaks * Update SelectChain documentation * Remove substrate/node lib.rs This shouldn't be used as a library AFAIK. While runtime should be, and arguably should even be published, I have yet to see node in the same way. Helps tighten API boundaries. * Remove unused macro_use * Replace panicking todos with stubs and // TODO Enables progress. * Reduce chain_spec and use more accurate naming * Implement block proposal logic * Modularize to get_proposal * Trigger block importing Doesn't wait for the response yet, which it needs to. * Get the result of block importing * Split import_queue into a series of files * Provide a way to create the machine The BasicQueue returned obscures the TendermintImport struct. Accordingly, a Future scoped with access is returned upwards, which when awaited will create the machine. This makes creating the machine optional while maintaining scope boundaries. Is sufficient to create a 1-node net which produces and finalizes blocks. * Don't import justifications multiple times Also don't broadcast blocks which were solely proposed. * Correct justication import pipeline Removes JustificationImport as it should never be used. * Announce blocks By claiming File, they're not sent ovber the P2P network before they have a justification, as desired. Unfortunately, they never were. This works around that. * Add an assert to verify proposed children aren't best * Consolidate C and I generics into a TendermintClient trait alias * Expand sanity checks Substrate doesn't expect nor officially support children with less work than their parents. It's a trick used here. Accordingly, ensure the trick's validity. * When resetting, use the end time of the round which was committed to The machine reset to the end time of the current round. For a delayed network connection, a machine may move ahead in rounds and only later realize a prior round succeeded. Despite acknowledging that round's success, it would maintain its delay when moving to the next block, bricking it. Done by tracking the end time for each round as they occur. * Move Commit from including the round to including the round's end_time The round was usable to build the current clock in an accumulated fashion, relative to the previous round. The end time is the absolute metric of it, which can be used to calculate the round number (with all previous end times). Substrate now builds off the best block, not genesis, using the end time included in the justification to start its machine in a synchronized state. Knowing the end time of a round, or the round in which block was committed to, is necessary for nodes to sync up with Tendermint. Encoding it in the commit ensures it's long lasting and makes it readily available, without the load of an entire transaction. * Add a TODO on Tendermint * Misc bug fixes * More misc bug fixes * Clean up lock acquisition * Merge weights and signing scheme into validators, documenting needed changes * Add pallet sessions to runtime, create pallet-tendermint * Update node to use pallet sessions * Update support URL * Partial work on correcting pallet calls * Redo Tendermint folder structure * TendermintApi, compilation fixes * Fix the stub round robin At some point, the modulus was removed causing it to exceed the validators list and stop proposing. * Use the validators list from the session pallet * Basic Gossip Validator * Correct Substrate Tendermint start block The Tendermint machine uses the passed in number as the block's being worked on number. Substrate passed in the already finalized block's number. Also updates misc comments. * Clean generics in Tendermint with a monolith with associated types * Remove the Future triggering the machine for an async fn Enables passing data in, such as the network. * Move TendermintMachine from start_num, time to last_num, time Provides an explicitly clear API clearer to program around. Also adds additional time code to handle an edge case. * Connect the Tendermint machine to a GossipEngine * Connect broadcast * Remove machine from TendermintImport It's not used there at all. * Merge Verifier into block_import.rs These two files were largely the same, just hooking into sync structs with almost identical imports. As this project shapes up, removing dead weight is appreciated. * Create a dedicated file for being a Tendermint authority * Deleted comment code related to PoW * Move serai_runtime specific code from tendermint/client to node Renames serai-consensus to sc_tendermint * Consolidate file structure in sc_tendermint * Replace best_* with finalized_* We test their equivalency yet still better to use finalized_* in general. * Consolidate references to sr25519 in sc_tendermint * Add documentation to public structs/functions in sc_tendermint * Add another missing comment * Make sign asynchronous Some relation to https://github.com/serai-dex/serai/issues/95. * Move sc_tendermint to async sign * Implement proper checking of inherents * Take in a Keystore and validator ID * Remove unnecessary PhantomDatas * Update node to latest sc_tendermint * Configure node for a multi-node testnet * Fix handling of the GossipEngine * Use a rounded genesis to obtain sufficient synchrony within the Docker env * Correct Serai d-f names in Docker * Remove an attempt at caching I don't believe would ever hit * Add an already in chain check to block import While the inner should do this for us, we call verify_order on our end *before* inner to ensure sequential import. Accordingly, we need to provide our own check. Removes errors of "non-sequential import" when trying to re-import an existing block. * Update the consensus documentation It was incredibly out of date. * Add a _ to the validator arg in slash * Make the dev profile a local testnet profile Restores a dev profile which only has one validator, locally running. * Reduce Arcs in TendermintMachine, split Signer from SignatureScheme * Update sc_tendermint per previous commit * Restore cache * Remove error case which shouldn't be an error * Stop returning errors on already existing blocks entirely * Correct Dave, Eve, and Ferdie to not run as validators * Rename dev to devnet --dev still works thanks to the |. Acheieves a personal preference of mine with some historical meaning. * Add message expiry to the Tendermint gossip * Localize the LibP2P protocol to the blockchain Follows convention by doing so. Theoretically enables running multiple blockchains over a single LibP2P connection. * Add a version to sp-runtime in tendermint-machine * Add missing trait * Bump Substrate dependency Fixes #147. * Implement Schnorr half-aggregation from https://eprint.iacr.org/2021/350.pdf Relevant to https://github.com/serai-dex/serai/issues/99. * cargo update (tendermint) * Move from polling loops to a pure IO model for sc_tendermint's gossip * Correct protocol name handling * Use futures mpsc instead of tokio * Timeout futures * Move from a yielding loop to select in tendermint-machine * Update Substrate to the new TendermintHandle * Use futures pin instead of tokio * Only recheck blocks with non-fatal inherent transaction errors * Update to the latest substrate * Separate the block processing time from the latency * Add notes to the runtime * Don't spam slash Also adds a slash condition of failing to propose. * Support running TendermintMachine when not a validator This supports validators who leave the current set, without crashing their nodes, along with nodes trying to become validators (who will now seamlessly transition in). * Properly define and pass around the block size * Correct the Duration timing The proposer will build it, send it, then process it (on the first round). Accordingly, it's / 3, not / 2, as / 2 only accounted for the latter events. * Correct time-adjustment code on round skip * Have the machine respond to advances made by an external sync loop * Clean up time code in tendermint-machine * BlockData and RoundData structs * Rename Round to RoundNumber * Move BlockData to a new file * Move Round to an Option due to the pseudo-uninitialized state we create Before the addition of RoundData, we always created the round, and on .round(0), simply created it again. With RoundData, and the changes to the time code, we used round 0, time 0, the latter being incorrect yet not an issue due to lack of misuse. Now, if we do misuse it, it'll panic. * Clear the Queue instead of draining and filtering There shouldn't ever be a message which passes the filter under the current design. * BlockData::new * Move more code into block.rs Introduces type-aliases to obtain Data/Message/SignedMessage solely from a Network object. Fixes a bug regarding stepping when you're not an active validator. * Have verify_precommit_signature return if it verified the signature Also fixes a bug where invalid precommit signatures were left standing and therefore contributing to commits. * Remove the precommit signature hash It cached signatures per-block. Precommit signatures are bound to each round. This would lead to forming invalid commits when a commit should be formed. Under debug, the machine would catch that and panic. On release, it'd have everyone who wasn't a validator fail to continue syncing. * Slight doc changes Also flattens the message handling function by replacing an if containing all following code in the function with an early return for the else case. * Always produce notifications for finalized blocks via origin overrides * Correct weird formatting * Update to the latest tendermint-machine * Manually step the Tendermint machine when we synced a block over the network * Ignore finality notifications for old blocks * Remove a TODO resolved in 8c51bc011d03c8d54ded05011e7f4d1a01e9f873 * Add a TODO comment to slash Enables searching for the case-sensitive phrase and finding it. * cargo fmt * Use a tmp DB for Serai in Docker * Remove panic on slash As we move towards protonet, this can happen (if a node goes offline), yet it happening brings down the entire net right now. * Add log::error on slash * created shared volume between containers * Complete the sh scripts * Pass in the genesis time to Substrate * Correct block announcements They were announced, yet not marked best. * Correct pupulate_end_time It was used as inclusive yet didn't work inclusively. * Correct gossip channel jumping when a block is synced via Substrate * Use a looser check in import_future This triggered so it needs to be accordingly relaxed. * Correct race conditions between add_block and step Also corrects a <= to <. * Update cargo deny * rename genesis-service to genesis * Update Cargo.lock * Correct runtime Cargo.toml whitespace * Correct typo * Document recheck * Misc lints * Fix prev commit * Resolve low-hanging review comments * Mark genesis/entry-dev.sh as executable * Prevent a commit from including the same signature multiple times Yanks tendermint-machine 0.1.0 accordingly. * Update to latest nightly clippy * Improve documentation * Use clearer variable names * Add log statements * Pair more log statements * Clean TendermintAuthority::authority as possible Merges it into new. It has way too many arguments, yet there's no clear path at consolidation there, unfortunately. Additionally provides better scoping within itself. * Fix #158 Doesn't use lock_import_and_run for reasons commented (lack of async). * Rename guard to lock * Have the devnet use the current time as the genesis Possible since it's only a single node, not requiring synchronization. * Fix gossiping I really don't know what side effect this avoids and I can't say I care at this point. * Misc lints Co-authored-by: vrx00 <vrx00@proton.me> Co-authored-by: TheArchitect108 <TheArchitect108@protonmail.com>
2022-12-03 23:38:02 +00:00
type FullBackend = sc_service::TFullBackend<Block>;
pub type FullClient = TFullClient<Block, RuntimeApi, Executor>;
Initial Tendermint implementation (#145) * Machine without timeouts * Time code * Move substrate/consensus/tendermint to substrate/tendermint * Delete the old paper doc * Refactor out external parts to generics Also creates a dedicated file for the message log. * Refactor <V, B> to type V, type B * Successfully compiling * Calculate timeouts * Fix test * Finish timeouts * Misc cleanup * Define a signature scheme trait * Implement serialization via parity's scale codec Ideally, this would be generic. Unfortunately, the generic API serde doesn't natively support borsh, nor SCALE, and while there is a serde SCALE crate, it's old. While it may be complete, it's not worth working with. While we could still grab bincode, and a variety of other formats, it wasn't worth it to go custom and for Serai, we'll be using SCALE almost everywhere anyways. * Implement usage of the signature scheme * Make the infinite test non-infinite * Provide a dedicated signature in Precommit of just the block hash Greatly simplifies verifying when syncing. * Dedicated Commit object Restores sig aggregation API. * Tidy README * Document tendermint * Sign the ID directly instead of its SCALE encoding For a hash, which is fixed-size, these should be the same yet this helps move past the dependency on SCALE. It also, for any type where the two values are different, smooths integration. * Litany of bug fixes Also attempts to make the code more readable while updating/correcting documentation. * Remove async recursion Greatly increases safety as well by ensuring only one message is processed at once. * Correct timing issues 1) Commit didn't include the round, leaving the clock in question. 2) Machines started with a local time, instead of a proper start time. 3) Machines immediately started the next block instead of waiting for the block time. * Replace MultiSignature with sr25519::Signature * Minor SignatureScheme API changes * Map TM SignatureScheme to Substrate's sr25519 * Initial work on an import queue * Properly use check_block * Rename import to import_queue * Implement tendermint_machine::Block for Substrate Blocks Unfortunately, this immediately makes Tendermint machine capable of deployment as crate since it uses a git reference. In the future, a Cargo.toml patch section for serai/substrate should be investigated. This is being done regardless as it's the quickest way forward and this is for Serai. * Dummy Weights * Move documentation to the top of the file * Move logic into TendermintImport itself Multiple traits exist to verify/handle blocks. I'm unsure exactly when each will be called in the pipeline, so the easiest solution is to have every step run every check. That would be extremely computationally expensive if we ran EVERY check, yet we rely on Substrate for execution (and according checks), which are limited to just the actual import function. Since we're calling this code from many places, it makes sense for it to be consolidated under TendermintImport. * BlockImport, JustificationImport, Verifier, and import_queue function * Update consensus/lib.rs from PoW to Tendermint Not possible to be used as the previous consensus could. It will not produce blocks nor does it currenly even instantiate a machine. This is just he next step. * Update Cargo.tomls for substrate packages * Tendermint SelectChain This is incompatible with Substrate's expectations, yet should be valid for ours * Move the node over to the new SelectChain * Minor tweaks * Update SelectChain documentation * Remove substrate/node lib.rs This shouldn't be used as a library AFAIK. While runtime should be, and arguably should even be published, I have yet to see node in the same way. Helps tighten API boundaries. * Remove unused macro_use * Replace panicking todos with stubs and // TODO Enables progress. * Reduce chain_spec and use more accurate naming * Implement block proposal logic * Modularize to get_proposal * Trigger block importing Doesn't wait for the response yet, which it needs to. * Get the result of block importing * Split import_queue into a series of files * Provide a way to create the machine The BasicQueue returned obscures the TendermintImport struct. Accordingly, a Future scoped with access is returned upwards, which when awaited will create the machine. This makes creating the machine optional while maintaining scope boundaries. Is sufficient to create a 1-node net which produces and finalizes blocks. * Don't import justifications multiple times Also don't broadcast blocks which were solely proposed. * Correct justication import pipeline Removes JustificationImport as it should never be used. * Announce blocks By claiming File, they're not sent ovber the P2P network before they have a justification, as desired. Unfortunately, they never were. This works around that. * Add an assert to verify proposed children aren't best * Consolidate C and I generics into a TendermintClient trait alias * Expand sanity checks Substrate doesn't expect nor officially support children with less work than their parents. It's a trick used here. Accordingly, ensure the trick's validity. * When resetting, use the end time of the round which was committed to The machine reset to the end time of the current round. For a delayed network connection, a machine may move ahead in rounds and only later realize a prior round succeeded. Despite acknowledging that round's success, it would maintain its delay when moving to the next block, bricking it. Done by tracking the end time for each round as they occur. * Move Commit from including the round to including the round's end_time The round was usable to build the current clock in an accumulated fashion, relative to the previous round. The end time is the absolute metric of it, which can be used to calculate the round number (with all previous end times). Substrate now builds off the best block, not genesis, using the end time included in the justification to start its machine in a synchronized state. Knowing the end time of a round, or the round in which block was committed to, is necessary for nodes to sync up with Tendermint. Encoding it in the commit ensures it's long lasting and makes it readily available, without the load of an entire transaction. * Add a TODO on Tendermint * Misc bug fixes * More misc bug fixes * Clean up lock acquisition * Merge weights and signing scheme into validators, documenting needed changes * Add pallet sessions to runtime, create pallet-tendermint * Update node to use pallet sessions * Update support URL * Partial work on correcting pallet calls * Redo Tendermint folder structure * TendermintApi, compilation fixes * Fix the stub round robin At some point, the modulus was removed causing it to exceed the validators list and stop proposing. * Use the validators list from the session pallet * Basic Gossip Validator * Correct Substrate Tendermint start block The Tendermint machine uses the passed in number as the block's being worked on number. Substrate passed in the already finalized block's number. Also updates misc comments. * Clean generics in Tendermint with a monolith with associated types * Remove the Future triggering the machine for an async fn Enables passing data in, such as the network. * Move TendermintMachine from start_num, time to last_num, time Provides an explicitly clear API clearer to program around. Also adds additional time code to handle an edge case. * Connect the Tendermint machine to a GossipEngine * Connect broadcast * Remove machine from TendermintImport It's not used there at all. * Merge Verifier into block_import.rs These two files were largely the same, just hooking into sync structs with almost identical imports. As this project shapes up, removing dead weight is appreciated. * Create a dedicated file for being a Tendermint authority * Deleted comment code related to PoW * Move serai_runtime specific code from tendermint/client to node Renames serai-consensus to sc_tendermint * Consolidate file structure in sc_tendermint * Replace best_* with finalized_* We test their equivalency yet still better to use finalized_* in general. * Consolidate references to sr25519 in sc_tendermint * Add documentation to public structs/functions in sc_tendermint * Add another missing comment * Make sign asynchronous Some relation to https://github.com/serai-dex/serai/issues/95. * Move sc_tendermint to async sign * Implement proper checking of inherents * Take in a Keystore and validator ID * Remove unnecessary PhantomDatas * Update node to latest sc_tendermint * Configure node for a multi-node testnet * Fix handling of the GossipEngine * Use a rounded genesis to obtain sufficient synchrony within the Docker env * Correct Serai d-f names in Docker * Remove an attempt at caching I don't believe would ever hit * Add an already in chain check to block import While the inner should do this for us, we call verify_order on our end *before* inner to ensure sequential import. Accordingly, we need to provide our own check. Removes errors of "non-sequential import" when trying to re-import an existing block. * Update the consensus documentation It was incredibly out of date. * Add a _ to the validator arg in slash * Make the dev profile a local testnet profile Restores a dev profile which only has one validator, locally running. * Reduce Arcs in TendermintMachine, split Signer from SignatureScheme * Update sc_tendermint per previous commit * Restore cache * Remove error case which shouldn't be an error * Stop returning errors on already existing blocks entirely * Correct Dave, Eve, and Ferdie to not run as validators * Rename dev to devnet --dev still works thanks to the |. Acheieves a personal preference of mine with some historical meaning. * Add message expiry to the Tendermint gossip * Localize the LibP2P protocol to the blockchain Follows convention by doing so. Theoretically enables running multiple blockchains over a single LibP2P connection. * Add a version to sp-runtime in tendermint-machine * Add missing trait * Bump Substrate dependency Fixes #147. * Implement Schnorr half-aggregation from https://eprint.iacr.org/2021/350.pdf Relevant to https://github.com/serai-dex/serai/issues/99. * cargo update (tendermint) * Move from polling loops to a pure IO model for sc_tendermint's gossip * Correct protocol name handling * Use futures mpsc instead of tokio * Timeout futures * Move from a yielding loop to select in tendermint-machine * Update Substrate to the new TendermintHandle * Use futures pin instead of tokio * Only recheck blocks with non-fatal inherent transaction errors * Update to the latest substrate * Separate the block processing time from the latency * Add notes to the runtime * Don't spam slash Also adds a slash condition of failing to propose. * Support running TendermintMachine when not a validator This supports validators who leave the current set, without crashing their nodes, along with nodes trying to become validators (who will now seamlessly transition in). * Properly define and pass around the block size * Correct the Duration timing The proposer will build it, send it, then process it (on the first round). Accordingly, it's / 3, not / 2, as / 2 only accounted for the latter events. * Correct time-adjustment code on round skip * Have the machine respond to advances made by an external sync loop * Clean up time code in tendermint-machine * BlockData and RoundData structs * Rename Round to RoundNumber * Move BlockData to a new file * Move Round to an Option due to the pseudo-uninitialized state we create Before the addition of RoundData, we always created the round, and on .round(0), simply created it again. With RoundData, and the changes to the time code, we used round 0, time 0, the latter being incorrect yet not an issue due to lack of misuse. Now, if we do misuse it, it'll panic. * Clear the Queue instead of draining and filtering There shouldn't ever be a message which passes the filter under the current design. * BlockData::new * Move more code into block.rs Introduces type-aliases to obtain Data/Message/SignedMessage solely from a Network object. Fixes a bug regarding stepping when you're not an active validator. * Have verify_precommit_signature return if it verified the signature Also fixes a bug where invalid precommit signatures were left standing and therefore contributing to commits. * Remove the precommit signature hash It cached signatures per-block. Precommit signatures are bound to each round. This would lead to forming invalid commits when a commit should be formed. Under debug, the machine would catch that and panic. On release, it'd have everyone who wasn't a validator fail to continue syncing. * Slight doc changes Also flattens the message handling function by replacing an if containing all following code in the function with an early return for the else case. * Always produce notifications for finalized blocks via origin overrides * Correct weird formatting * Update to the latest tendermint-machine * Manually step the Tendermint machine when we synced a block over the network * Ignore finality notifications for old blocks * Remove a TODO resolved in 8c51bc011d03c8d54ded05011e7f4d1a01e9f873 * Add a TODO comment to slash Enables searching for the case-sensitive phrase and finding it. * cargo fmt * Use a tmp DB for Serai in Docker * Remove panic on slash As we move towards protonet, this can happen (if a node goes offline), yet it happening brings down the entire net right now. * Add log::error on slash * created shared volume between containers * Complete the sh scripts * Pass in the genesis time to Substrate * Correct block announcements They were announced, yet not marked best. * Correct pupulate_end_time It was used as inclusive yet didn't work inclusively. * Correct gossip channel jumping when a block is synced via Substrate * Use a looser check in import_future This triggered so it needs to be accordingly relaxed. * Correct race conditions between add_block and step Also corrects a <= to <. * Update cargo deny * rename genesis-service to genesis * Update Cargo.lock * Correct runtime Cargo.toml whitespace * Correct typo * Document recheck * Misc lints * Fix prev commit * Resolve low-hanging review comments * Mark genesis/entry-dev.sh as executable * Prevent a commit from including the same signature multiple times Yanks tendermint-machine 0.1.0 accordingly. * Update to latest nightly clippy * Improve documentation * Use clearer variable names * Add log statements * Pair more log statements * Clean TendermintAuthority::authority as possible Merges it into new. It has way too many arguments, yet there's no clear path at consolidation there, unfortunately. Additionally provides better scoping within itself. * Fix #158 Doesn't use lock_import_and_run for reasons commented (lack of async). * Rename guard to lock * Have the devnet use the current time as the genesis Possible since it's only a single node, not requiring synchronization. * Fix gossiping I really don't know what side effect this avoids and I can't say I care at this point. * Misc lints Co-authored-by: vrx00 <vrx00@proton.me> Co-authored-by: TheArchitect108 <TheArchitect108@protonmail.com>
2022-12-03 23:38:02 +00:00
type SelectChain = sc_consensus::LongestChain<FullBackend, Block>;
type GrandpaBlockImport = grandpa::GrandpaBlockImport<FullBackend, Block, FullClient, SelectChain>;
type BabeBlockImport = sc_consensus_babe::BabeBlockImport<Block, FullClient, GrandpaBlockImport>;
Initial Tendermint implementation (#145) * Machine without timeouts * Time code * Move substrate/consensus/tendermint to substrate/tendermint * Delete the old paper doc * Refactor out external parts to generics Also creates a dedicated file for the message log. * Refactor <V, B> to type V, type B * Successfully compiling * Calculate timeouts * Fix test * Finish timeouts * Misc cleanup * Define a signature scheme trait * Implement serialization via parity's scale codec Ideally, this would be generic. Unfortunately, the generic API serde doesn't natively support borsh, nor SCALE, and while there is a serde SCALE crate, it's old. While it may be complete, it's not worth working with. While we could still grab bincode, and a variety of other formats, it wasn't worth it to go custom and for Serai, we'll be using SCALE almost everywhere anyways. * Implement usage of the signature scheme * Make the infinite test non-infinite * Provide a dedicated signature in Precommit of just the block hash Greatly simplifies verifying when syncing. * Dedicated Commit object Restores sig aggregation API. * Tidy README * Document tendermint * Sign the ID directly instead of its SCALE encoding For a hash, which is fixed-size, these should be the same yet this helps move past the dependency on SCALE. It also, for any type where the two values are different, smooths integration. * Litany of bug fixes Also attempts to make the code more readable while updating/correcting documentation. * Remove async recursion Greatly increases safety as well by ensuring only one message is processed at once. * Correct timing issues 1) Commit didn't include the round, leaving the clock in question. 2) Machines started with a local time, instead of a proper start time. 3) Machines immediately started the next block instead of waiting for the block time. * Replace MultiSignature with sr25519::Signature * Minor SignatureScheme API changes * Map TM SignatureScheme to Substrate's sr25519 * Initial work on an import queue * Properly use check_block * Rename import to import_queue * Implement tendermint_machine::Block for Substrate Blocks Unfortunately, this immediately makes Tendermint machine capable of deployment as crate since it uses a git reference. In the future, a Cargo.toml patch section for serai/substrate should be investigated. This is being done regardless as it's the quickest way forward and this is for Serai. * Dummy Weights * Move documentation to the top of the file * Move logic into TendermintImport itself Multiple traits exist to verify/handle blocks. I'm unsure exactly when each will be called in the pipeline, so the easiest solution is to have every step run every check. That would be extremely computationally expensive if we ran EVERY check, yet we rely on Substrate for execution (and according checks), which are limited to just the actual import function. Since we're calling this code from many places, it makes sense for it to be consolidated under TendermintImport. * BlockImport, JustificationImport, Verifier, and import_queue function * Update consensus/lib.rs from PoW to Tendermint Not possible to be used as the previous consensus could. It will not produce blocks nor does it currenly even instantiate a machine. This is just he next step. * Update Cargo.tomls for substrate packages * Tendermint SelectChain This is incompatible with Substrate's expectations, yet should be valid for ours * Move the node over to the new SelectChain * Minor tweaks * Update SelectChain documentation * Remove substrate/node lib.rs This shouldn't be used as a library AFAIK. While runtime should be, and arguably should even be published, I have yet to see node in the same way. Helps tighten API boundaries. * Remove unused macro_use * Replace panicking todos with stubs and // TODO Enables progress. * Reduce chain_spec and use more accurate naming * Implement block proposal logic * Modularize to get_proposal * Trigger block importing Doesn't wait for the response yet, which it needs to. * Get the result of block importing * Split import_queue into a series of files * Provide a way to create the machine The BasicQueue returned obscures the TendermintImport struct. Accordingly, a Future scoped with access is returned upwards, which when awaited will create the machine. This makes creating the machine optional while maintaining scope boundaries. Is sufficient to create a 1-node net which produces and finalizes blocks. * Don't import justifications multiple times Also don't broadcast blocks which were solely proposed. * Correct justication import pipeline Removes JustificationImport as it should never be used. * Announce blocks By claiming File, they're not sent ovber the P2P network before they have a justification, as desired. Unfortunately, they never were. This works around that. * Add an assert to verify proposed children aren't best * Consolidate C and I generics into a TendermintClient trait alias * Expand sanity checks Substrate doesn't expect nor officially support children with less work than their parents. It's a trick used here. Accordingly, ensure the trick's validity. * When resetting, use the end time of the round which was committed to The machine reset to the end time of the current round. For a delayed network connection, a machine may move ahead in rounds and only later realize a prior round succeeded. Despite acknowledging that round's success, it would maintain its delay when moving to the next block, bricking it. Done by tracking the end time for each round as they occur. * Move Commit from including the round to including the round's end_time The round was usable to build the current clock in an accumulated fashion, relative to the previous round. The end time is the absolute metric of it, which can be used to calculate the round number (with all previous end times). Substrate now builds off the best block, not genesis, using the end time included in the justification to start its machine in a synchronized state. Knowing the end time of a round, or the round in which block was committed to, is necessary for nodes to sync up with Tendermint. Encoding it in the commit ensures it's long lasting and makes it readily available, without the load of an entire transaction. * Add a TODO on Tendermint * Misc bug fixes * More misc bug fixes * Clean up lock acquisition * Merge weights and signing scheme into validators, documenting needed changes * Add pallet sessions to runtime, create pallet-tendermint * Update node to use pallet sessions * Update support URL * Partial work on correcting pallet calls * Redo Tendermint folder structure * TendermintApi, compilation fixes * Fix the stub round robin At some point, the modulus was removed causing it to exceed the validators list and stop proposing. * Use the validators list from the session pallet * Basic Gossip Validator * Correct Substrate Tendermint start block The Tendermint machine uses the passed in number as the block's being worked on number. Substrate passed in the already finalized block's number. Also updates misc comments. * Clean generics in Tendermint with a monolith with associated types * Remove the Future triggering the machine for an async fn Enables passing data in, such as the network. * Move TendermintMachine from start_num, time to last_num, time Provides an explicitly clear API clearer to program around. Also adds additional time code to handle an edge case. * Connect the Tendermint machine to a GossipEngine * Connect broadcast * Remove machine from TendermintImport It's not used there at all. * Merge Verifier into block_import.rs These two files were largely the same, just hooking into sync structs with almost identical imports. As this project shapes up, removing dead weight is appreciated. * Create a dedicated file for being a Tendermint authority * Deleted comment code related to PoW * Move serai_runtime specific code from tendermint/client to node Renames serai-consensus to sc_tendermint * Consolidate file structure in sc_tendermint * Replace best_* with finalized_* We test their equivalency yet still better to use finalized_* in general. * Consolidate references to sr25519 in sc_tendermint * Add documentation to public structs/functions in sc_tendermint * Add another missing comment * Make sign asynchronous Some relation to https://github.com/serai-dex/serai/issues/95. * Move sc_tendermint to async sign * Implement proper checking of inherents * Take in a Keystore and validator ID * Remove unnecessary PhantomDatas * Update node to latest sc_tendermint * Configure node for a multi-node testnet * Fix handling of the GossipEngine * Use a rounded genesis to obtain sufficient synchrony within the Docker env * Correct Serai d-f names in Docker * Remove an attempt at caching I don't believe would ever hit * Add an already in chain check to block import While the inner should do this for us, we call verify_order on our end *before* inner to ensure sequential import. Accordingly, we need to provide our own check. Removes errors of "non-sequential import" when trying to re-import an existing block. * Update the consensus documentation It was incredibly out of date. * Add a _ to the validator arg in slash * Make the dev profile a local testnet profile Restores a dev profile which only has one validator, locally running. * Reduce Arcs in TendermintMachine, split Signer from SignatureScheme * Update sc_tendermint per previous commit * Restore cache * Remove error case which shouldn't be an error * Stop returning errors on already existing blocks entirely * Correct Dave, Eve, and Ferdie to not run as validators * Rename dev to devnet --dev still works thanks to the |. Acheieves a personal preference of mine with some historical meaning. * Add message expiry to the Tendermint gossip * Localize the LibP2P protocol to the blockchain Follows convention by doing so. Theoretically enables running multiple blockchains over a single LibP2P connection. * Add a version to sp-runtime in tendermint-machine * Add missing trait * Bump Substrate dependency Fixes #147. * Implement Schnorr half-aggregation from https://eprint.iacr.org/2021/350.pdf Relevant to https://github.com/serai-dex/serai/issues/99. * cargo update (tendermint) * Move from polling loops to a pure IO model for sc_tendermint's gossip * Correct protocol name handling * Use futures mpsc instead of tokio * Timeout futures * Move from a yielding loop to select in tendermint-machine * Update Substrate to the new TendermintHandle * Use futures pin instead of tokio * Only recheck blocks with non-fatal inherent transaction errors * Update to the latest substrate * Separate the block processing time from the latency * Add notes to the runtime * Don't spam slash Also adds a slash condition of failing to propose. * Support running TendermintMachine when not a validator This supports validators who leave the current set, without crashing their nodes, along with nodes trying to become validators (who will now seamlessly transition in). * Properly define and pass around the block size * Correct the Duration timing The proposer will build it, send it, then process it (on the first round). Accordingly, it's / 3, not / 2, as / 2 only accounted for the latter events. * Correct time-adjustment code on round skip * Have the machine respond to advances made by an external sync loop * Clean up time code in tendermint-machine * BlockData and RoundData structs * Rename Round to RoundNumber * Move BlockData to a new file * Move Round to an Option due to the pseudo-uninitialized state we create Before the addition of RoundData, we always created the round, and on .round(0), simply created it again. With RoundData, and the changes to the time code, we used round 0, time 0, the latter being incorrect yet not an issue due to lack of misuse. Now, if we do misuse it, it'll panic. * Clear the Queue instead of draining and filtering There shouldn't ever be a message which passes the filter under the current design. * BlockData::new * Move more code into block.rs Introduces type-aliases to obtain Data/Message/SignedMessage solely from a Network object. Fixes a bug regarding stepping when you're not an active validator. * Have verify_precommit_signature return if it verified the signature Also fixes a bug where invalid precommit signatures were left standing and therefore contributing to commits. * Remove the precommit signature hash It cached signatures per-block. Precommit signatures are bound to each round. This would lead to forming invalid commits when a commit should be formed. Under debug, the machine would catch that and panic. On release, it'd have everyone who wasn't a validator fail to continue syncing. * Slight doc changes Also flattens the message handling function by replacing an if containing all following code in the function with an early return for the else case. * Always produce notifications for finalized blocks via origin overrides * Correct weird formatting * Update to the latest tendermint-machine * Manually step the Tendermint machine when we synced a block over the network * Ignore finality notifications for old blocks * Remove a TODO resolved in 8c51bc011d03c8d54ded05011e7f4d1a01e9f873 * Add a TODO comment to slash Enables searching for the case-sensitive phrase and finding it. * cargo fmt * Use a tmp DB for Serai in Docker * Remove panic on slash As we move towards protonet, this can happen (if a node goes offline), yet it happening brings down the entire net right now. * Add log::error on slash * created shared volume between containers * Complete the sh scripts * Pass in the genesis time to Substrate * Correct block announcements They were announced, yet not marked best. * Correct pupulate_end_time It was used as inclusive yet didn't work inclusively. * Correct gossip channel jumping when a block is synced via Substrate * Use a looser check in import_future This triggered so it needs to be accordingly relaxed. * Correct race conditions between add_block and step Also corrects a <= to <. * Update cargo deny * rename genesis-service to genesis * Update Cargo.lock * Correct runtime Cargo.toml whitespace * Correct typo * Document recheck * Misc lints * Fix prev commit * Resolve low-hanging review comments * Mark genesis/entry-dev.sh as executable * Prevent a commit from including the same signature multiple times Yanks tendermint-machine 0.1.0 accordingly. * Update to latest nightly clippy * Improve documentation * Use clearer variable names * Add log statements * Pair more log statements * Clean TendermintAuthority::authority as possible Merges it into new. It has way too many arguments, yet there's no clear path at consolidation there, unfortunately. Additionally provides better scoping within itself. * Fix #158 Doesn't use lock_import_and_run for reasons commented (lack of async). * Rename guard to lock * Have the devnet use the current time as the genesis Possible since it's only a single node, not requiring synchronization. * Fix gossiping I really don't know what side effect this avoids and I can't say I care at this point. * Misc lints Co-authored-by: vrx00 <vrx00@proton.me> Co-authored-by: TheArchitect108 <TheArchitect108@protonmail.com>
2022-12-03 23:38:02 +00:00
type PartialComponents = sc_service::PartialComponents<
FullClient,
FullBackend,
SelectChain,
sc_consensus::DefaultImportQueue<Block, FullClient>,
sc_transaction_pool::FullPool<Block, FullClient>,
(
BabeBlockImport,
sc_consensus_babe::BabeLink<Block>,
grandpa::LinkHalf<Block, FullClient, SelectChain>,
grandpa::SharedVoterState,
Option<Telemetry>,
),
>;
Initial Tendermint implementation (#145) * Machine without timeouts * Time code * Move substrate/consensus/tendermint to substrate/tendermint * Delete the old paper doc * Refactor out external parts to generics Also creates a dedicated file for the message log. * Refactor <V, B> to type V, type B * Successfully compiling * Calculate timeouts * Fix test * Finish timeouts * Misc cleanup * Define a signature scheme trait * Implement serialization via parity's scale codec Ideally, this would be generic. Unfortunately, the generic API serde doesn't natively support borsh, nor SCALE, and while there is a serde SCALE crate, it's old. While it may be complete, it's not worth working with. While we could still grab bincode, and a variety of other formats, it wasn't worth it to go custom and for Serai, we'll be using SCALE almost everywhere anyways. * Implement usage of the signature scheme * Make the infinite test non-infinite * Provide a dedicated signature in Precommit of just the block hash Greatly simplifies verifying when syncing. * Dedicated Commit object Restores sig aggregation API. * Tidy README * Document tendermint * Sign the ID directly instead of its SCALE encoding For a hash, which is fixed-size, these should be the same yet this helps move past the dependency on SCALE. It also, for any type where the two values are different, smooths integration. * Litany of bug fixes Also attempts to make the code more readable while updating/correcting documentation. * Remove async recursion Greatly increases safety as well by ensuring only one message is processed at once. * Correct timing issues 1) Commit didn't include the round, leaving the clock in question. 2) Machines started with a local time, instead of a proper start time. 3) Machines immediately started the next block instead of waiting for the block time. * Replace MultiSignature with sr25519::Signature * Minor SignatureScheme API changes * Map TM SignatureScheme to Substrate's sr25519 * Initial work on an import queue * Properly use check_block * Rename import to import_queue * Implement tendermint_machine::Block for Substrate Blocks Unfortunately, this immediately makes Tendermint machine capable of deployment as crate since it uses a git reference. In the future, a Cargo.toml patch section for serai/substrate should be investigated. This is being done regardless as it's the quickest way forward and this is for Serai. * Dummy Weights * Move documentation to the top of the file * Move logic into TendermintImport itself Multiple traits exist to verify/handle blocks. I'm unsure exactly when each will be called in the pipeline, so the easiest solution is to have every step run every check. That would be extremely computationally expensive if we ran EVERY check, yet we rely on Substrate for execution (and according checks), which are limited to just the actual import function. Since we're calling this code from many places, it makes sense for it to be consolidated under TendermintImport. * BlockImport, JustificationImport, Verifier, and import_queue function * Update consensus/lib.rs from PoW to Tendermint Not possible to be used as the previous consensus could. It will not produce blocks nor does it currenly even instantiate a machine. This is just he next step. * Update Cargo.tomls for substrate packages * Tendermint SelectChain This is incompatible with Substrate's expectations, yet should be valid for ours * Move the node over to the new SelectChain * Minor tweaks * Update SelectChain documentation * Remove substrate/node lib.rs This shouldn't be used as a library AFAIK. While runtime should be, and arguably should even be published, I have yet to see node in the same way. Helps tighten API boundaries. * Remove unused macro_use * Replace panicking todos with stubs and // TODO Enables progress. * Reduce chain_spec and use more accurate naming * Implement block proposal logic * Modularize to get_proposal * Trigger block importing Doesn't wait for the response yet, which it needs to. * Get the result of block importing * Split import_queue into a series of files * Provide a way to create the machine The BasicQueue returned obscures the TendermintImport struct. Accordingly, a Future scoped with access is returned upwards, which when awaited will create the machine. This makes creating the machine optional while maintaining scope boundaries. Is sufficient to create a 1-node net which produces and finalizes blocks. * Don't import justifications multiple times Also don't broadcast blocks which were solely proposed. * Correct justication import pipeline Removes JustificationImport as it should never be used. * Announce blocks By claiming File, they're not sent ovber the P2P network before they have a justification, as desired. Unfortunately, they never were. This works around that. * Add an assert to verify proposed children aren't best * Consolidate C and I generics into a TendermintClient trait alias * Expand sanity checks Substrate doesn't expect nor officially support children with less work than their parents. It's a trick used here. Accordingly, ensure the trick's validity. * When resetting, use the end time of the round which was committed to The machine reset to the end time of the current round. For a delayed network connection, a machine may move ahead in rounds and only later realize a prior round succeeded. Despite acknowledging that round's success, it would maintain its delay when moving to the next block, bricking it. Done by tracking the end time for each round as they occur. * Move Commit from including the round to including the round's end_time The round was usable to build the current clock in an accumulated fashion, relative to the previous round. The end time is the absolute metric of it, which can be used to calculate the round number (with all previous end times). Substrate now builds off the best block, not genesis, using the end time included in the justification to start its machine in a synchronized state. Knowing the end time of a round, or the round in which block was committed to, is necessary for nodes to sync up with Tendermint. Encoding it in the commit ensures it's long lasting and makes it readily available, without the load of an entire transaction. * Add a TODO on Tendermint * Misc bug fixes * More misc bug fixes * Clean up lock acquisition * Merge weights and signing scheme into validators, documenting needed changes * Add pallet sessions to runtime, create pallet-tendermint * Update node to use pallet sessions * Update support URL * Partial work on correcting pallet calls * Redo Tendermint folder structure * TendermintApi, compilation fixes * Fix the stub round robin At some point, the modulus was removed causing it to exceed the validators list and stop proposing. * Use the validators list from the session pallet * Basic Gossip Validator * Correct Substrate Tendermint start block The Tendermint machine uses the passed in number as the block's being worked on number. Substrate passed in the already finalized block's number. Also updates misc comments. * Clean generics in Tendermint with a monolith with associated types * Remove the Future triggering the machine for an async fn Enables passing data in, such as the network. * Move TendermintMachine from start_num, time to last_num, time Provides an explicitly clear API clearer to program around. Also adds additional time code to handle an edge case. * Connect the Tendermint machine to a GossipEngine * Connect broadcast * Remove machine from TendermintImport It's not used there at all. * Merge Verifier into block_import.rs These two files were largely the same, just hooking into sync structs with almost identical imports. As this project shapes up, removing dead weight is appreciated. * Create a dedicated file for being a Tendermint authority * Deleted comment code related to PoW * Move serai_runtime specific code from tendermint/client to node Renames serai-consensus to sc_tendermint * Consolidate file structure in sc_tendermint * Replace best_* with finalized_* We test their equivalency yet still better to use finalized_* in general. * Consolidate references to sr25519 in sc_tendermint * Add documentation to public structs/functions in sc_tendermint * Add another missing comment * Make sign asynchronous Some relation to https://github.com/serai-dex/serai/issues/95. * Move sc_tendermint to async sign * Implement proper checking of inherents * Take in a Keystore and validator ID * Remove unnecessary PhantomDatas * Update node to latest sc_tendermint * Configure node for a multi-node testnet * Fix handling of the GossipEngine * Use a rounded genesis to obtain sufficient synchrony within the Docker env * Correct Serai d-f names in Docker * Remove an attempt at caching I don't believe would ever hit * Add an already in chain check to block import While the inner should do this for us, we call verify_order on our end *before* inner to ensure sequential import. Accordingly, we need to provide our own check. Removes errors of "non-sequential import" when trying to re-import an existing block. * Update the consensus documentation It was incredibly out of date. * Add a _ to the validator arg in slash * Make the dev profile a local testnet profile Restores a dev profile which only has one validator, locally running. * Reduce Arcs in TendermintMachine, split Signer from SignatureScheme * Update sc_tendermint per previous commit * Restore cache * Remove error case which shouldn't be an error * Stop returning errors on already existing blocks entirely * Correct Dave, Eve, and Ferdie to not run as validators * Rename dev to devnet --dev still works thanks to the |. Acheieves a personal preference of mine with some historical meaning. * Add message expiry to the Tendermint gossip * Localize the LibP2P protocol to the blockchain Follows convention by doing so. Theoretically enables running multiple blockchains over a single LibP2P connection. * Add a version to sp-runtime in tendermint-machine * Add missing trait * Bump Substrate dependency Fixes #147. * Implement Schnorr half-aggregation from https://eprint.iacr.org/2021/350.pdf Relevant to https://github.com/serai-dex/serai/issues/99. * cargo update (tendermint) * Move from polling loops to a pure IO model for sc_tendermint's gossip * Correct protocol name handling * Use futures mpsc instead of tokio * Timeout futures * Move from a yielding loop to select in tendermint-machine * Update Substrate to the new TendermintHandle * Use futures pin instead of tokio * Only recheck blocks with non-fatal inherent transaction errors * Update to the latest substrate * Separate the block processing time from the latency * Add notes to the runtime * Don't spam slash Also adds a slash condition of failing to propose. * Support running TendermintMachine when not a validator This supports validators who leave the current set, without crashing their nodes, along with nodes trying to become validators (who will now seamlessly transition in). * Properly define and pass around the block size * Correct the Duration timing The proposer will build it, send it, then process it (on the first round). Accordingly, it's / 3, not / 2, as / 2 only accounted for the latter events. * Correct time-adjustment code on round skip * Have the machine respond to advances made by an external sync loop * Clean up time code in tendermint-machine * BlockData and RoundData structs * Rename Round to RoundNumber * Move BlockData to a new file * Move Round to an Option due to the pseudo-uninitialized state we create Before the addition of RoundData, we always created the round, and on .round(0), simply created it again. With RoundData, and the changes to the time code, we used round 0, time 0, the latter being incorrect yet not an issue due to lack of misuse. Now, if we do misuse it, it'll panic. * Clear the Queue instead of draining and filtering There shouldn't ever be a message which passes the filter under the current design. * BlockData::new * Move more code into block.rs Introduces type-aliases to obtain Data/Message/SignedMessage solely from a Network object. Fixes a bug regarding stepping when you're not an active validator. * Have verify_precommit_signature return if it verified the signature Also fixes a bug where invalid precommit signatures were left standing and therefore contributing to commits. * Remove the precommit signature hash It cached signatures per-block. Precommit signatures are bound to each round. This would lead to forming invalid commits when a commit should be formed. Under debug, the machine would catch that and panic. On release, it'd have everyone who wasn't a validator fail to continue syncing. * Slight doc changes Also flattens the message handling function by replacing an if containing all following code in the function with an early return for the else case. * Always produce notifications for finalized blocks via origin overrides * Correct weird formatting * Update to the latest tendermint-machine * Manually step the Tendermint machine when we synced a block over the network * Ignore finality notifications for old blocks * Remove a TODO resolved in 8c51bc011d03c8d54ded05011e7f4d1a01e9f873 * Add a TODO comment to slash Enables searching for the case-sensitive phrase and finding it. * cargo fmt * Use a tmp DB for Serai in Docker * Remove panic on slash As we move towards protonet, this can happen (if a node goes offline), yet it happening brings down the entire net right now. * Add log::error on slash * created shared volume between containers * Complete the sh scripts * Pass in the genesis time to Substrate * Correct block announcements They were announced, yet not marked best. * Correct pupulate_end_time It was used as inclusive yet didn't work inclusively. * Correct gossip channel jumping when a block is synced via Substrate * Use a looser check in import_future This triggered so it needs to be accordingly relaxed. * Correct race conditions between add_block and step Also corrects a <= to <. * Update cargo deny * rename genesis-service to genesis * Update Cargo.lock * Correct runtime Cargo.toml whitespace * Correct typo * Document recheck * Misc lints * Fix prev commit * Resolve low-hanging review comments * Mark genesis/entry-dev.sh as executable * Prevent a commit from including the same signature multiple times Yanks tendermint-machine 0.1.0 accordingly. * Update to latest nightly clippy * Improve documentation * Use clearer variable names * Add log statements * Pair more log statements * Clean TendermintAuthority::authority as possible Merges it into new. It has way too many arguments, yet there's no clear path at consolidation there, unfortunately. Additionally provides better scoping within itself. * Fix #158 Doesn't use lock_import_and_run for reasons commented (lack of async). * Rename guard to lock * Have the devnet use the current time as the genesis Possible since it's only a single node, not requiring synchronization. * Fix gossiping I really don't know what side effect this avoids and I can't say I care at this point. * Misc lints Co-authored-by: vrx00 <vrx00@proton.me> Co-authored-by: TheArchitect108 <TheArchitect108@protonmail.com>
2022-12-03 23:38:02 +00:00
fn create_inherent_data_providers(
slot_duration: SlotDuration,
) -> (BabeInherent, TimestampInherent) {
let timestamp = TimestampInherent::from_system_time();
(BabeInherent::from_timestamp_and_slot_duration(*timestamp, slot_duration), timestamp)
Initial Tendermint implementation (#145) * Machine without timeouts * Time code * Move substrate/consensus/tendermint to substrate/tendermint * Delete the old paper doc * Refactor out external parts to generics Also creates a dedicated file for the message log. * Refactor <V, B> to type V, type B * Successfully compiling * Calculate timeouts * Fix test * Finish timeouts * Misc cleanup * Define a signature scheme trait * Implement serialization via parity's scale codec Ideally, this would be generic. Unfortunately, the generic API serde doesn't natively support borsh, nor SCALE, and while there is a serde SCALE crate, it's old. While it may be complete, it's not worth working with. While we could still grab bincode, and a variety of other formats, it wasn't worth it to go custom and for Serai, we'll be using SCALE almost everywhere anyways. * Implement usage of the signature scheme * Make the infinite test non-infinite * Provide a dedicated signature in Precommit of just the block hash Greatly simplifies verifying when syncing. * Dedicated Commit object Restores sig aggregation API. * Tidy README * Document tendermint * Sign the ID directly instead of its SCALE encoding For a hash, which is fixed-size, these should be the same yet this helps move past the dependency on SCALE. It also, for any type where the two values are different, smooths integration. * Litany of bug fixes Also attempts to make the code more readable while updating/correcting documentation. * Remove async recursion Greatly increases safety as well by ensuring only one message is processed at once. * Correct timing issues 1) Commit didn't include the round, leaving the clock in question. 2) Machines started with a local time, instead of a proper start time. 3) Machines immediately started the next block instead of waiting for the block time. * Replace MultiSignature with sr25519::Signature * Minor SignatureScheme API changes * Map TM SignatureScheme to Substrate's sr25519 * Initial work on an import queue * Properly use check_block * Rename import to import_queue * Implement tendermint_machine::Block for Substrate Blocks Unfortunately, this immediately makes Tendermint machine capable of deployment as crate since it uses a git reference. In the future, a Cargo.toml patch section for serai/substrate should be investigated. This is being done regardless as it's the quickest way forward and this is for Serai. * Dummy Weights * Move documentation to the top of the file * Move logic into TendermintImport itself Multiple traits exist to verify/handle blocks. I'm unsure exactly when each will be called in the pipeline, so the easiest solution is to have every step run every check. That would be extremely computationally expensive if we ran EVERY check, yet we rely on Substrate for execution (and according checks), which are limited to just the actual import function. Since we're calling this code from many places, it makes sense for it to be consolidated under TendermintImport. * BlockImport, JustificationImport, Verifier, and import_queue function * Update consensus/lib.rs from PoW to Tendermint Not possible to be used as the previous consensus could. It will not produce blocks nor does it currenly even instantiate a machine. This is just he next step. * Update Cargo.tomls for substrate packages * Tendermint SelectChain This is incompatible with Substrate's expectations, yet should be valid for ours * Move the node over to the new SelectChain * Minor tweaks * Update SelectChain documentation * Remove substrate/node lib.rs This shouldn't be used as a library AFAIK. While runtime should be, and arguably should even be published, I have yet to see node in the same way. Helps tighten API boundaries. * Remove unused macro_use * Replace panicking todos with stubs and // TODO Enables progress. * Reduce chain_spec and use more accurate naming * Implement block proposal logic * Modularize to get_proposal * Trigger block importing Doesn't wait for the response yet, which it needs to. * Get the result of block importing * Split import_queue into a series of files * Provide a way to create the machine The BasicQueue returned obscures the TendermintImport struct. Accordingly, a Future scoped with access is returned upwards, which when awaited will create the machine. This makes creating the machine optional while maintaining scope boundaries. Is sufficient to create a 1-node net which produces and finalizes blocks. * Don't import justifications multiple times Also don't broadcast blocks which were solely proposed. * Correct justication import pipeline Removes JustificationImport as it should never be used. * Announce blocks By claiming File, they're not sent ovber the P2P network before they have a justification, as desired. Unfortunately, they never were. This works around that. * Add an assert to verify proposed children aren't best * Consolidate C and I generics into a TendermintClient trait alias * Expand sanity checks Substrate doesn't expect nor officially support children with less work than their parents. It's a trick used here. Accordingly, ensure the trick's validity. * When resetting, use the end time of the round which was committed to The machine reset to the end time of the current round. For a delayed network connection, a machine may move ahead in rounds and only later realize a prior round succeeded. Despite acknowledging that round's success, it would maintain its delay when moving to the next block, bricking it. Done by tracking the end time for each round as they occur. * Move Commit from including the round to including the round's end_time The round was usable to build the current clock in an accumulated fashion, relative to the previous round. The end time is the absolute metric of it, which can be used to calculate the round number (with all previous end times). Substrate now builds off the best block, not genesis, using the end time included in the justification to start its machine in a synchronized state. Knowing the end time of a round, or the round in which block was committed to, is necessary for nodes to sync up with Tendermint. Encoding it in the commit ensures it's long lasting and makes it readily available, without the load of an entire transaction. * Add a TODO on Tendermint * Misc bug fixes * More misc bug fixes * Clean up lock acquisition * Merge weights and signing scheme into validators, documenting needed changes * Add pallet sessions to runtime, create pallet-tendermint * Update node to use pallet sessions * Update support URL * Partial work on correcting pallet calls * Redo Tendermint folder structure * TendermintApi, compilation fixes * Fix the stub round robin At some point, the modulus was removed causing it to exceed the validators list and stop proposing. * Use the validators list from the session pallet * Basic Gossip Validator * Correct Substrate Tendermint start block The Tendermint machine uses the passed in number as the block's being worked on number. Substrate passed in the already finalized block's number. Also updates misc comments. * Clean generics in Tendermint with a monolith with associated types * Remove the Future triggering the machine for an async fn Enables passing data in, such as the network. * Move TendermintMachine from start_num, time to last_num, time Provides an explicitly clear API clearer to program around. Also adds additional time code to handle an edge case. * Connect the Tendermint machine to a GossipEngine * Connect broadcast * Remove machine from TendermintImport It's not used there at all. * Merge Verifier into block_import.rs These two files were largely the same, just hooking into sync structs with almost identical imports. As this project shapes up, removing dead weight is appreciated. * Create a dedicated file for being a Tendermint authority * Deleted comment code related to PoW * Move serai_runtime specific code from tendermint/client to node Renames serai-consensus to sc_tendermint * Consolidate file structure in sc_tendermint * Replace best_* with finalized_* We test their equivalency yet still better to use finalized_* in general. * Consolidate references to sr25519 in sc_tendermint * Add documentation to public structs/functions in sc_tendermint * Add another missing comment * Make sign asynchronous Some relation to https://github.com/serai-dex/serai/issues/95. * Move sc_tendermint to async sign * Implement proper checking of inherents * Take in a Keystore and validator ID * Remove unnecessary PhantomDatas * Update node to latest sc_tendermint * Configure node for a multi-node testnet * Fix handling of the GossipEngine * Use a rounded genesis to obtain sufficient synchrony within the Docker env * Correct Serai d-f names in Docker * Remove an attempt at caching I don't believe would ever hit * Add an already in chain check to block import While the inner should do this for us, we call verify_order on our end *before* inner to ensure sequential import. Accordingly, we need to provide our own check. Removes errors of "non-sequential import" when trying to re-import an existing block. * Update the consensus documentation It was incredibly out of date. * Add a _ to the validator arg in slash * Make the dev profile a local testnet profile Restores a dev profile which only has one validator, locally running. * Reduce Arcs in TendermintMachine, split Signer from SignatureScheme * Update sc_tendermint per previous commit * Restore cache * Remove error case which shouldn't be an error * Stop returning errors on already existing blocks entirely * Correct Dave, Eve, and Ferdie to not run as validators * Rename dev to devnet --dev still works thanks to the |. Acheieves a personal preference of mine with some historical meaning. * Add message expiry to the Tendermint gossip * Localize the LibP2P protocol to the blockchain Follows convention by doing so. Theoretically enables running multiple blockchains over a single LibP2P connection. * Add a version to sp-runtime in tendermint-machine * Add missing trait * Bump Substrate dependency Fixes #147. * Implement Schnorr half-aggregation from https://eprint.iacr.org/2021/350.pdf Relevant to https://github.com/serai-dex/serai/issues/99. * cargo update (tendermint) * Move from polling loops to a pure IO model for sc_tendermint's gossip * Correct protocol name handling * Use futures mpsc instead of tokio * Timeout futures * Move from a yielding loop to select in tendermint-machine * Update Substrate to the new TendermintHandle * Use futures pin instead of tokio * Only recheck blocks with non-fatal inherent transaction errors * Update to the latest substrate * Separate the block processing time from the latency * Add notes to the runtime * Don't spam slash Also adds a slash condition of failing to propose. * Support running TendermintMachine when not a validator This supports validators who leave the current set, without crashing their nodes, along with nodes trying to become validators (who will now seamlessly transition in). * Properly define and pass around the block size * Correct the Duration timing The proposer will build it, send it, then process it (on the first round). Accordingly, it's / 3, not / 2, as / 2 only accounted for the latter events. * Correct time-adjustment code on round skip * Have the machine respond to advances made by an external sync loop * Clean up time code in tendermint-machine * BlockData and RoundData structs * Rename Round to RoundNumber * Move BlockData to a new file * Move Round to an Option due to the pseudo-uninitialized state we create Before the addition of RoundData, we always created the round, and on .round(0), simply created it again. With RoundData, and the changes to the time code, we used round 0, time 0, the latter being incorrect yet not an issue due to lack of misuse. Now, if we do misuse it, it'll panic. * Clear the Queue instead of draining and filtering There shouldn't ever be a message which passes the filter under the current design. * BlockData::new * Move more code into block.rs Introduces type-aliases to obtain Data/Message/SignedMessage solely from a Network object. Fixes a bug regarding stepping when you're not an active validator. * Have verify_precommit_signature return if it verified the signature Also fixes a bug where invalid precommit signatures were left standing and therefore contributing to commits. * Remove the precommit signature hash It cached signatures per-block. Precommit signatures are bound to each round. This would lead to forming invalid commits when a commit should be formed. Under debug, the machine would catch that and panic. On release, it'd have everyone who wasn't a validator fail to continue syncing. * Slight doc changes Also flattens the message handling function by replacing an if containing all following code in the function with an early return for the else case. * Always produce notifications for finalized blocks via origin overrides * Correct weird formatting * Update to the latest tendermint-machine * Manually step the Tendermint machine when we synced a block over the network * Ignore finality notifications for old blocks * Remove a TODO resolved in 8c51bc011d03c8d54ded05011e7f4d1a01e9f873 * Add a TODO comment to slash Enables searching for the case-sensitive phrase and finding it. * cargo fmt * Use a tmp DB for Serai in Docker * Remove panic on slash As we move towards protonet, this can happen (if a node goes offline), yet it happening brings down the entire net right now. * Add log::error on slash * created shared volume between containers * Complete the sh scripts * Pass in the genesis time to Substrate * Correct block announcements They were announced, yet not marked best. * Correct pupulate_end_time It was used as inclusive yet didn't work inclusively. * Correct gossip channel jumping when a block is synced via Substrate * Use a looser check in import_future This triggered so it needs to be accordingly relaxed. * Correct race conditions between add_block and step Also corrects a <= to <. * Update cargo deny * rename genesis-service to genesis * Update Cargo.lock * Correct runtime Cargo.toml whitespace * Correct typo * Document recheck * Misc lints * Fix prev commit * Resolve low-hanging review comments * Mark genesis/entry-dev.sh as executable * Prevent a commit from including the same signature multiple times Yanks tendermint-machine 0.1.0 accordingly. * Update to latest nightly clippy * Improve documentation * Use clearer variable names * Add log statements * Pair more log statements * Clean TendermintAuthority::authority as possible Merges it into new. It has way too many arguments, yet there's no clear path at consolidation there, unfortunately. Additionally provides better scoping within itself. * Fix #158 Doesn't use lock_import_and_run for reasons commented (lack of async). * Rename guard to lock * Have the devnet use the current time as the genesis Possible since it's only a single node, not requiring synchronization. * Fix gossiping I really don't know what side effect this avoids and I can't say I care at this point. * Misc lints Co-authored-by: vrx00 <vrx00@proton.me> Co-authored-by: TheArchitect108 <TheArchitect108@protonmail.com>
2022-12-03 23:38:02 +00:00
}
Redo Dockerfile generation (#530) Moves from concatted Dockerfiles to pseudo-templated Dockerfiles via a dedicated Rust program. Removes the unmaintained kubernetes, not because we shouldn't have/use it, but because it's unmaintained and needs to be reworked before it's present again. Replaces the compose with the work in the new orchestrator binary which spawns everything as expected. While this arguably re-invents the wheel, it correctly manages secrets and handles the variadic Dockerfiles. Also adds an unrelated patch for zstd and simplifies running services a bit by greater utilizing the existing infrastructure. --- * Delete all Dockerfile fragments, add new orchestator to generate Dockerfiles Enables greater templating. Also delete the unmaintained kubernetes folder *for now*. This should be restored in the future. * Use Dockerfiles from the orchestator * Ignore Dockerfiles in the git repo * Remove CI job to check Dockerfiles are as expected now that they're no longer committed * Remove old Dockerfiles from repo * Use Debian for monero-wallet-rpc * Remove replace_cmds for proper usage of entry-dev Consolidates ports a bit. Updates serai-docker-tests from "compose" to "build". * Only write a new dockerfile if it's distinct Preserves the updated time metadata. * Update serai-docker-tests * Correct the path Dockerfiles are built from * Correct inclusion of orchestration folder in Docker builds * Correct debug/release flagging in the cargo command Apparently, --debug isn't an effective NOP yet an error. * Correct path used to run the Serai node within a Dockerfile * Correct path in Monero Dockerfile * Attempt storing monerod in /usr/bin * Use sudo to move into /usr/bin in CI * Correct 18.3.0 to 18.3.1 * Escape * with quotes * Update deny.toml, ADD orchestration in runtime Dockerfile * Add --detach to the Monero GH CI * Diversify dockerfiles by network * Fixes to network-diversified orchestration * Bitcoin and Monero testnet scripts * Permissions and tweaks * Flatten scripts folders * Add missing folder specification to Monero Dockerfile * Have monero-wallet-rpc specify the monerod login * Have the Docker CMD specify env variables inserted at time of Dockerfile generation They're overrideable with the global enviornment as for tests. This enables variable generation in orchestrator and output to productionized Docker files without creating a life-long file within the Docker container. * Don't add Dockerfiles into Docker containers now that they have secrets Solely add the source code for them as needed to satisfy the workspace bounds. * Download arm64 Monero on arm64 * Ensure constant host architecture when reproducibly building the wasm Host architecture, for some reason, can effect the generated code despite the target architecture always being foreign to the host architecture. * Randomly generate infrastructure keys * Have orchestrator generate a key, be able to create/start containers * Ensure bash is used over sh * Clean dated docs * Change how quoting occurs * Standardize to sh * Have Docker test build the dev Dockerfiles * Only key_gen once * cargo update Adds a patch for zstd and reconciles the breaking nightly change which just occurred. * Use a dedicated network for Serai Also fixes SERAI_HOSTNAME passed to coordinator. * Support providing a key over the env for the Serai node * Enable and document running daemons for tests via serai-orchestrator Has running containers under the dev network port forward the RPC ports. * Use volumes for bitcoin/monero * Use bitcoin's run.sh in GH CI * Only use the volume for testnet (not dev)
2024-02-09 07:48:44 +00:00
pub fn new_partial(
config: &Configuration,
) -> Result<(PartialComponents, Arc<dyn sp_keystore::Keystore>), ServiceError> {
let telemetry = config
.telemetry_endpoints
.clone()
.filter(|x| !x.is_empty())
.map(|endpoints| -> Result<_, sc_telemetry::Error> {
let worker = TelemetryWorker::new(16)?;
let telemetry = worker.handle().new_telemetry(endpoints);
Ok((worker, telemetry))
})
.transpose()?;
2023-05-01 07:17:37 +00:00
#[allow(deprecated)]
let executor = Executor::new(
config.wasm_method,
config.default_heap_pages,
config.max_runtime_instances,
None,
2022-07-15 05:26:07 +00:00
config.runtime_cache_size,
);
2022-07-15 05:26:07 +00:00
let (client, backend, keystore_container, task_manager) =
sc_service::new_full_parts::<Block, RuntimeApi, _>(
config,
telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),
executor,
)?;
let client = Arc::new(client);
Redo Dockerfile generation (#530) Moves from concatted Dockerfiles to pseudo-templated Dockerfiles via a dedicated Rust program. Removes the unmaintained kubernetes, not because we shouldn't have/use it, but because it's unmaintained and needs to be reworked before it's present again. Replaces the compose with the work in the new orchestrator binary which spawns everything as expected. While this arguably re-invents the wheel, it correctly manages secrets and handles the variadic Dockerfiles. Also adds an unrelated patch for zstd and simplifies running services a bit by greater utilizing the existing infrastructure. --- * Delete all Dockerfile fragments, add new orchestator to generate Dockerfiles Enables greater templating. Also delete the unmaintained kubernetes folder *for now*. This should be restored in the future. * Use Dockerfiles from the orchestator * Ignore Dockerfiles in the git repo * Remove CI job to check Dockerfiles are as expected now that they're no longer committed * Remove old Dockerfiles from repo * Use Debian for monero-wallet-rpc * Remove replace_cmds for proper usage of entry-dev Consolidates ports a bit. Updates serai-docker-tests from "compose" to "build". * Only write a new dockerfile if it's distinct Preserves the updated time metadata. * Update serai-docker-tests * Correct the path Dockerfiles are built from * Correct inclusion of orchestration folder in Docker builds * Correct debug/release flagging in the cargo command Apparently, --debug isn't an effective NOP yet an error. * Correct path used to run the Serai node within a Dockerfile * Correct path in Monero Dockerfile * Attempt storing monerod in /usr/bin * Use sudo to move into /usr/bin in CI * Correct 18.3.0 to 18.3.1 * Escape * with quotes * Update deny.toml, ADD orchestration in runtime Dockerfile * Add --detach to the Monero GH CI * Diversify dockerfiles by network * Fixes to network-diversified orchestration * Bitcoin and Monero testnet scripts * Permissions and tweaks * Flatten scripts folders * Add missing folder specification to Monero Dockerfile * Have monero-wallet-rpc specify the monerod login * Have the Docker CMD specify env variables inserted at time of Dockerfile generation They're overrideable with the global enviornment as for tests. This enables variable generation in orchestrator and output to productionized Docker files without creating a life-long file within the Docker container. * Don't add Dockerfiles into Docker containers now that they have secrets Solely add the source code for them as needed to satisfy the workspace bounds. * Download arm64 Monero on arm64 * Ensure constant host architecture when reproducibly building the wasm Host architecture, for some reason, can effect the generated code despite the target architecture always being foreign to the host architecture. * Randomly generate infrastructure keys * Have orchestrator generate a key, be able to create/start containers * Ensure bash is used over sh * Clean dated docs * Change how quoting occurs * Standardize to sh * Have Docker test build the dev Dockerfiles * Only key_gen once * cargo update Adds a patch for zstd and reconciles the breaking nightly change which just occurred. * Use a dedicated network for Serai Also fixes SERAI_HOSTNAME passed to coordinator. * Support providing a key over the env for the Serai node * Enable and document running daemons for tests via serai-orchestrator Has running containers under the dev network port forward the RPC ports. * Use volumes for bitcoin/monero * Use bitcoin's run.sh in GH CI * Only use the volume for testnet (not dev)
2024-02-09 07:48:44 +00:00
let keystore: Arc<dyn sp_keystore::Keystore> =
if let Some(keystore) = crate::keystore::Keystore::from_env() {
Arc::new(keystore)
} else {
keystore_container.keystore()
};
let telemetry = telemetry.map(|(worker, telemetry)| {
task_manager.spawn_handle().spawn("telemetry", None, worker.run());
telemetry
});
let select_chain = sc_consensus::LongestChain::new(backend.clone());
let transaction_pool = sc_transaction_pool::BasicPool::new_full(
config.transaction_pool.clone(),
config.role.is_authority().into(),
config.prometheus_registry(),
task_manager.spawn_essential_handle(),
2022-07-15 05:26:07 +00:00
client.clone(),
);
let (grandpa_block_import, grandpa_link) = grandpa::block_import(
client.clone(),
&client,
select_chain.clone(),
telemetry.as_ref().map(Telemetry::handle),
)?;
let justification_import = grandpa_block_import.clone();
let (block_import, babe_link) = sc_consensus_babe::block_import(
sc_consensus_babe::configuration(&*client)?,
grandpa_block_import,
client.clone(),
)?;
let slot_duration = babe_link.config().slot_duration();
2023-07-19 02:30:55 +00:00
let (import_queue, babe_handle) =
sc_consensus_babe::import_queue(sc_consensus_babe::ImportQueueParams {
link: babe_link.clone(),
block_import: block_import.clone(),
justification_import: Some(Box::new(justification_import)),
client: client.clone(),
select_chain: select_chain.clone(),
2023-12-17 01:54:24 +00:00
create_inherent_data_providers: move |_, ()| async move {
2023-07-19 02:30:55 +00:00
Ok(create_inherent_data_providers(slot_duration))
},
spawner: &task_manager.spawn_essential_handle(),
registry: config.prometheus_registry(),
telemetry: telemetry.as_ref().map(Telemetry::handle),
offchain_tx_pool_factory: OffchainTransactionPoolFactory::new(transaction_pool.clone()),
})?;
2023-05-01 07:17:37 +00:00
// This can't be dropped, or BABE breaks
// We don't have anything to do with it though
// This won't grow in size, so forgetting this isn't a disastrous memleak
std::mem::forget(babe_handle);
Initial Tendermint implementation (#145) * Machine without timeouts * Time code * Move substrate/consensus/tendermint to substrate/tendermint * Delete the old paper doc * Refactor out external parts to generics Also creates a dedicated file for the message log. * Refactor <V, B> to type V, type B * Successfully compiling * Calculate timeouts * Fix test * Finish timeouts * Misc cleanup * Define a signature scheme trait * Implement serialization via parity's scale codec Ideally, this would be generic. Unfortunately, the generic API serde doesn't natively support borsh, nor SCALE, and while there is a serde SCALE crate, it's old. While it may be complete, it's not worth working with. While we could still grab bincode, and a variety of other formats, it wasn't worth it to go custom and for Serai, we'll be using SCALE almost everywhere anyways. * Implement usage of the signature scheme * Make the infinite test non-infinite * Provide a dedicated signature in Precommit of just the block hash Greatly simplifies verifying when syncing. * Dedicated Commit object Restores sig aggregation API. * Tidy README * Document tendermint * Sign the ID directly instead of its SCALE encoding For a hash, which is fixed-size, these should be the same yet this helps move past the dependency on SCALE. It also, for any type where the two values are different, smooths integration. * Litany of bug fixes Also attempts to make the code more readable while updating/correcting documentation. * Remove async recursion Greatly increases safety as well by ensuring only one message is processed at once. * Correct timing issues 1) Commit didn't include the round, leaving the clock in question. 2) Machines started with a local time, instead of a proper start time. 3) Machines immediately started the next block instead of waiting for the block time. * Replace MultiSignature with sr25519::Signature * Minor SignatureScheme API changes * Map TM SignatureScheme to Substrate's sr25519 * Initial work on an import queue * Properly use check_block * Rename import to import_queue * Implement tendermint_machine::Block for Substrate Blocks Unfortunately, this immediately makes Tendermint machine capable of deployment as crate since it uses a git reference. In the future, a Cargo.toml patch section for serai/substrate should be investigated. This is being done regardless as it's the quickest way forward and this is for Serai. * Dummy Weights * Move documentation to the top of the file * Move logic into TendermintImport itself Multiple traits exist to verify/handle blocks. I'm unsure exactly when each will be called in the pipeline, so the easiest solution is to have every step run every check. That would be extremely computationally expensive if we ran EVERY check, yet we rely on Substrate for execution (and according checks), which are limited to just the actual import function. Since we're calling this code from many places, it makes sense for it to be consolidated under TendermintImport. * BlockImport, JustificationImport, Verifier, and import_queue function * Update consensus/lib.rs from PoW to Tendermint Not possible to be used as the previous consensus could. It will not produce blocks nor does it currenly even instantiate a machine. This is just he next step. * Update Cargo.tomls for substrate packages * Tendermint SelectChain This is incompatible with Substrate's expectations, yet should be valid for ours * Move the node over to the new SelectChain * Minor tweaks * Update SelectChain documentation * Remove substrate/node lib.rs This shouldn't be used as a library AFAIK. While runtime should be, and arguably should even be published, I have yet to see node in the same way. Helps tighten API boundaries. * Remove unused macro_use * Replace panicking todos with stubs and // TODO Enables progress. * Reduce chain_spec and use more accurate naming * Implement block proposal logic * Modularize to get_proposal * Trigger block importing Doesn't wait for the response yet, which it needs to. * Get the result of block importing * Split import_queue into a series of files * Provide a way to create the machine The BasicQueue returned obscures the TendermintImport struct. Accordingly, a Future scoped with access is returned upwards, which when awaited will create the machine. This makes creating the machine optional while maintaining scope boundaries. Is sufficient to create a 1-node net which produces and finalizes blocks. * Don't import justifications multiple times Also don't broadcast blocks which were solely proposed. * Correct justication import pipeline Removes JustificationImport as it should never be used. * Announce blocks By claiming File, they're not sent ovber the P2P network before they have a justification, as desired. Unfortunately, they never were. This works around that. * Add an assert to verify proposed children aren't best * Consolidate C and I generics into a TendermintClient trait alias * Expand sanity checks Substrate doesn't expect nor officially support children with less work than their parents. It's a trick used here. Accordingly, ensure the trick's validity. * When resetting, use the end time of the round which was committed to The machine reset to the end time of the current round. For a delayed network connection, a machine may move ahead in rounds and only later realize a prior round succeeded. Despite acknowledging that round's success, it would maintain its delay when moving to the next block, bricking it. Done by tracking the end time for each round as they occur. * Move Commit from including the round to including the round's end_time The round was usable to build the current clock in an accumulated fashion, relative to the previous round. The end time is the absolute metric of it, which can be used to calculate the round number (with all previous end times). Substrate now builds off the best block, not genesis, using the end time included in the justification to start its machine in a synchronized state. Knowing the end time of a round, or the round in which block was committed to, is necessary for nodes to sync up with Tendermint. Encoding it in the commit ensures it's long lasting and makes it readily available, without the load of an entire transaction. * Add a TODO on Tendermint * Misc bug fixes * More misc bug fixes * Clean up lock acquisition * Merge weights and signing scheme into validators, documenting needed changes * Add pallet sessions to runtime, create pallet-tendermint * Update node to use pallet sessions * Update support URL * Partial work on correcting pallet calls * Redo Tendermint folder structure * TendermintApi, compilation fixes * Fix the stub round robin At some point, the modulus was removed causing it to exceed the validators list and stop proposing. * Use the validators list from the session pallet * Basic Gossip Validator * Correct Substrate Tendermint start block The Tendermint machine uses the passed in number as the block's being worked on number. Substrate passed in the already finalized block's number. Also updates misc comments. * Clean generics in Tendermint with a monolith with associated types * Remove the Future triggering the machine for an async fn Enables passing data in, such as the network. * Move TendermintMachine from start_num, time to last_num, time Provides an explicitly clear API clearer to program around. Also adds additional time code to handle an edge case. * Connect the Tendermint machine to a GossipEngine * Connect broadcast * Remove machine from TendermintImport It's not used there at all. * Merge Verifier into block_import.rs These two files were largely the same, just hooking into sync structs with almost identical imports. As this project shapes up, removing dead weight is appreciated. * Create a dedicated file for being a Tendermint authority * Deleted comment code related to PoW * Move serai_runtime specific code from tendermint/client to node Renames serai-consensus to sc_tendermint * Consolidate file structure in sc_tendermint * Replace best_* with finalized_* We test their equivalency yet still better to use finalized_* in general. * Consolidate references to sr25519 in sc_tendermint * Add documentation to public structs/functions in sc_tendermint * Add another missing comment * Make sign asynchronous Some relation to https://github.com/serai-dex/serai/issues/95. * Move sc_tendermint to async sign * Implement proper checking of inherents * Take in a Keystore and validator ID * Remove unnecessary PhantomDatas * Update node to latest sc_tendermint * Configure node for a multi-node testnet * Fix handling of the GossipEngine * Use a rounded genesis to obtain sufficient synchrony within the Docker env * Correct Serai d-f names in Docker * Remove an attempt at caching I don't believe would ever hit * Add an already in chain check to block import While the inner should do this for us, we call verify_order on our end *before* inner to ensure sequential import. Accordingly, we need to provide our own check. Removes errors of "non-sequential import" when trying to re-import an existing block. * Update the consensus documentation It was incredibly out of date. * Add a _ to the validator arg in slash * Make the dev profile a local testnet profile Restores a dev profile which only has one validator, locally running. * Reduce Arcs in TendermintMachine, split Signer from SignatureScheme * Update sc_tendermint per previous commit * Restore cache * Remove error case which shouldn't be an error * Stop returning errors on already existing blocks entirely * Correct Dave, Eve, and Ferdie to not run as validators * Rename dev to devnet --dev still works thanks to the |. Acheieves a personal preference of mine with some historical meaning. * Add message expiry to the Tendermint gossip * Localize the LibP2P protocol to the blockchain Follows convention by doing so. Theoretically enables running multiple blockchains over a single LibP2P connection. * Add a version to sp-runtime in tendermint-machine * Add missing trait * Bump Substrate dependency Fixes #147. * Implement Schnorr half-aggregation from https://eprint.iacr.org/2021/350.pdf Relevant to https://github.com/serai-dex/serai/issues/99. * cargo update (tendermint) * Move from polling loops to a pure IO model for sc_tendermint's gossip * Correct protocol name handling * Use futures mpsc instead of tokio * Timeout futures * Move from a yielding loop to select in tendermint-machine * Update Substrate to the new TendermintHandle * Use futures pin instead of tokio * Only recheck blocks with non-fatal inherent transaction errors * Update to the latest substrate * Separate the block processing time from the latency * Add notes to the runtime * Don't spam slash Also adds a slash condition of failing to propose. * Support running TendermintMachine when not a validator This supports validators who leave the current set, without crashing their nodes, along with nodes trying to become validators (who will now seamlessly transition in). * Properly define and pass around the block size * Correct the Duration timing The proposer will build it, send it, then process it (on the first round). Accordingly, it's / 3, not / 2, as / 2 only accounted for the latter events. * Correct time-adjustment code on round skip * Have the machine respond to advances made by an external sync loop * Clean up time code in tendermint-machine * BlockData and RoundData structs * Rename Round to RoundNumber * Move BlockData to a new file * Move Round to an Option due to the pseudo-uninitialized state we create Before the addition of RoundData, we always created the round, and on .round(0), simply created it again. With RoundData, and the changes to the time code, we used round 0, time 0, the latter being incorrect yet not an issue due to lack of misuse. Now, if we do misuse it, it'll panic. * Clear the Queue instead of draining and filtering There shouldn't ever be a message which passes the filter under the current design. * BlockData::new * Move more code into block.rs Introduces type-aliases to obtain Data/Message/SignedMessage solely from a Network object. Fixes a bug regarding stepping when you're not an active validator. * Have verify_precommit_signature return if it verified the signature Also fixes a bug where invalid precommit signatures were left standing and therefore contributing to commits. * Remove the precommit signature hash It cached signatures per-block. Precommit signatures are bound to each round. This would lead to forming invalid commits when a commit should be formed. Under debug, the machine would catch that and panic. On release, it'd have everyone who wasn't a validator fail to continue syncing. * Slight doc changes Also flattens the message handling function by replacing an if containing all following code in the function with an early return for the else case. * Always produce notifications for finalized blocks via origin overrides * Correct weird formatting * Update to the latest tendermint-machine * Manually step the Tendermint machine when we synced a block over the network * Ignore finality notifications for old blocks * Remove a TODO resolved in 8c51bc011d03c8d54ded05011e7f4d1a01e9f873 * Add a TODO comment to slash Enables searching for the case-sensitive phrase and finding it. * cargo fmt * Use a tmp DB for Serai in Docker * Remove panic on slash As we move towards protonet, this can happen (if a node goes offline), yet it happening brings down the entire net right now. * Add log::error on slash * created shared volume between containers * Complete the sh scripts * Pass in the genesis time to Substrate * Correct block announcements They were announced, yet not marked best. * Correct pupulate_end_time It was used as inclusive yet didn't work inclusively. * Correct gossip channel jumping when a block is synced via Substrate * Use a looser check in import_future This triggered so it needs to be accordingly relaxed. * Correct race conditions between add_block and step Also corrects a <= to <. * Update cargo deny * rename genesis-service to genesis * Update Cargo.lock * Correct runtime Cargo.toml whitespace * Correct typo * Document recheck * Misc lints * Fix prev commit * Resolve low-hanging review comments * Mark genesis/entry-dev.sh as executable * Prevent a commit from including the same signature multiple times Yanks tendermint-machine 0.1.0 accordingly. * Update to latest nightly clippy * Improve documentation * Use clearer variable names * Add log statements * Pair more log statements * Clean TendermintAuthority::authority as possible Merges it into new. It has way too many arguments, yet there's no clear path at consolidation there, unfortunately. Additionally provides better scoping within itself. * Fix #158 Doesn't use lock_import_and_run for reasons commented (lack of async). * Rename guard to lock * Have the devnet use the current time as the genesis Possible since it's only a single node, not requiring synchronization. * Fix gossiping I really don't know what side effect this avoids and I can't say I care at this point. * Misc lints Co-authored-by: vrx00 <vrx00@proton.me> Co-authored-by: TheArchitect108 <TheArchitect108@protonmail.com>
2022-12-03 23:38:02 +00:00
Redo Dockerfile generation (#530) Moves from concatted Dockerfiles to pseudo-templated Dockerfiles via a dedicated Rust program. Removes the unmaintained kubernetes, not because we shouldn't have/use it, but because it's unmaintained and needs to be reworked before it's present again. Replaces the compose with the work in the new orchestrator binary which spawns everything as expected. While this arguably re-invents the wheel, it correctly manages secrets and handles the variadic Dockerfiles. Also adds an unrelated patch for zstd and simplifies running services a bit by greater utilizing the existing infrastructure. --- * Delete all Dockerfile fragments, add new orchestator to generate Dockerfiles Enables greater templating. Also delete the unmaintained kubernetes folder *for now*. This should be restored in the future. * Use Dockerfiles from the orchestator * Ignore Dockerfiles in the git repo * Remove CI job to check Dockerfiles are as expected now that they're no longer committed * Remove old Dockerfiles from repo * Use Debian for monero-wallet-rpc * Remove replace_cmds for proper usage of entry-dev Consolidates ports a bit. Updates serai-docker-tests from "compose" to "build". * Only write a new dockerfile if it's distinct Preserves the updated time metadata. * Update serai-docker-tests * Correct the path Dockerfiles are built from * Correct inclusion of orchestration folder in Docker builds * Correct debug/release flagging in the cargo command Apparently, --debug isn't an effective NOP yet an error. * Correct path used to run the Serai node within a Dockerfile * Correct path in Monero Dockerfile * Attempt storing monerod in /usr/bin * Use sudo to move into /usr/bin in CI * Correct 18.3.0 to 18.3.1 * Escape * with quotes * Update deny.toml, ADD orchestration in runtime Dockerfile * Add --detach to the Monero GH CI * Diversify dockerfiles by network * Fixes to network-diversified orchestration * Bitcoin and Monero testnet scripts * Permissions and tweaks * Flatten scripts folders * Add missing folder specification to Monero Dockerfile * Have monero-wallet-rpc specify the monerod login * Have the Docker CMD specify env variables inserted at time of Dockerfile generation They're overrideable with the global enviornment as for tests. This enables variable generation in orchestrator and output to productionized Docker files without creating a life-long file within the Docker container. * Don't add Dockerfiles into Docker containers now that they have secrets Solely add the source code for them as needed to satisfy the workspace bounds. * Download arm64 Monero on arm64 * Ensure constant host architecture when reproducibly building the wasm Host architecture, for some reason, can effect the generated code despite the target architecture always being foreign to the host architecture. * Randomly generate infrastructure keys * Have orchestrator generate a key, be able to create/start containers * Ensure bash is used over sh * Clean dated docs * Change how quoting occurs * Standardize to sh * Have Docker test build the dev Dockerfiles * Only key_gen once * cargo update Adds a patch for zstd and reconciles the breaking nightly change which just occurred. * Use a dedicated network for Serai Also fixes SERAI_HOSTNAME passed to coordinator. * Support providing a key over the env for the Serai node * Enable and document running daemons for tests via serai-orchestrator Has running containers under the dev network port forward the RPC ports. * Use volumes for bitcoin/monero * Use bitcoin's run.sh in GH CI * Only use the volume for testnet (not dev)
2024-02-09 07:48:44 +00:00
Ok((
sc_service::PartialComponents {
client,
backend,
task_manager,
keystore_container,
select_chain,
import_queue,
transaction_pool,
other: (block_import, babe_link, grandpa_link, grandpa::SharedVoterState::empty(), telemetry),
},
keystore,
))
}
pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError> {
Redo Dockerfile generation (#530) Moves from concatted Dockerfiles to pseudo-templated Dockerfiles via a dedicated Rust program. Removes the unmaintained kubernetes, not because we shouldn't have/use it, but because it's unmaintained and needs to be reworked before it's present again. Replaces the compose with the work in the new orchestrator binary which spawns everything as expected. While this arguably re-invents the wheel, it correctly manages secrets and handles the variadic Dockerfiles. Also adds an unrelated patch for zstd and simplifies running services a bit by greater utilizing the existing infrastructure. --- * Delete all Dockerfile fragments, add new orchestator to generate Dockerfiles Enables greater templating. Also delete the unmaintained kubernetes folder *for now*. This should be restored in the future. * Use Dockerfiles from the orchestator * Ignore Dockerfiles in the git repo * Remove CI job to check Dockerfiles are as expected now that they're no longer committed * Remove old Dockerfiles from repo * Use Debian for monero-wallet-rpc * Remove replace_cmds for proper usage of entry-dev Consolidates ports a bit. Updates serai-docker-tests from "compose" to "build". * Only write a new dockerfile if it's distinct Preserves the updated time metadata. * Update serai-docker-tests * Correct the path Dockerfiles are built from * Correct inclusion of orchestration folder in Docker builds * Correct debug/release flagging in the cargo command Apparently, --debug isn't an effective NOP yet an error. * Correct path used to run the Serai node within a Dockerfile * Correct path in Monero Dockerfile * Attempt storing monerod in /usr/bin * Use sudo to move into /usr/bin in CI * Correct 18.3.0 to 18.3.1 * Escape * with quotes * Update deny.toml, ADD orchestration in runtime Dockerfile * Add --detach to the Monero GH CI * Diversify dockerfiles by network * Fixes to network-diversified orchestration * Bitcoin and Monero testnet scripts * Permissions and tweaks * Flatten scripts folders * Add missing folder specification to Monero Dockerfile * Have monero-wallet-rpc specify the monerod login * Have the Docker CMD specify env variables inserted at time of Dockerfile generation They're overrideable with the global enviornment as for tests. This enables variable generation in orchestrator and output to productionized Docker files without creating a life-long file within the Docker container. * Don't add Dockerfiles into Docker containers now that they have secrets Solely add the source code for them as needed to satisfy the workspace bounds. * Download arm64 Monero on arm64 * Ensure constant host architecture when reproducibly building the wasm Host architecture, for some reason, can effect the generated code despite the target architecture always being foreign to the host architecture. * Randomly generate infrastructure keys * Have orchestrator generate a key, be able to create/start containers * Ensure bash is used over sh * Clean dated docs * Change how quoting occurs * Standardize to sh * Have Docker test build the dev Dockerfiles * Only key_gen once * cargo update Adds a patch for zstd and reconciles the breaking nightly change which just occurred. * Use a dedicated network for Serai Also fixes SERAI_HOSTNAME passed to coordinator. * Support providing a key over the env for the Serai node * Enable and document running daemons for tests via serai-orchestrator Has running containers under the dev network port forward the RPC ports. * Use volumes for bitcoin/monero * Use bitcoin's run.sh in GH CI * Only use the volume for testnet (not dev)
2024-02-09 07:48:44 +00:00
let (
sc_service::PartialComponents {
client,
backend,
mut task_manager,
keystore_container: _,
import_queue,
select_chain,
transaction_pool,
other: (block_import, babe_link, grandpa_link, shared_voter_state, mut telemetry),
},
keystore_container,
Redo Dockerfile generation (#530) Moves from concatted Dockerfiles to pseudo-templated Dockerfiles via a dedicated Rust program. Removes the unmaintained kubernetes, not because we shouldn't have/use it, but because it's unmaintained and needs to be reworked before it's present again. Replaces the compose with the work in the new orchestrator binary which spawns everything as expected. While this arguably re-invents the wheel, it correctly manages secrets and handles the variadic Dockerfiles. Also adds an unrelated patch for zstd and simplifies running services a bit by greater utilizing the existing infrastructure. --- * Delete all Dockerfile fragments, add new orchestator to generate Dockerfiles Enables greater templating. Also delete the unmaintained kubernetes folder *for now*. This should be restored in the future. * Use Dockerfiles from the orchestator * Ignore Dockerfiles in the git repo * Remove CI job to check Dockerfiles are as expected now that they're no longer committed * Remove old Dockerfiles from repo * Use Debian for monero-wallet-rpc * Remove replace_cmds for proper usage of entry-dev Consolidates ports a bit. Updates serai-docker-tests from "compose" to "build". * Only write a new dockerfile if it's distinct Preserves the updated time metadata. * Update serai-docker-tests * Correct the path Dockerfiles are built from * Correct inclusion of orchestration folder in Docker builds * Correct debug/release flagging in the cargo command Apparently, --debug isn't an effective NOP yet an error. * Correct path used to run the Serai node within a Dockerfile * Correct path in Monero Dockerfile * Attempt storing monerod in /usr/bin * Use sudo to move into /usr/bin in CI * Correct 18.3.0 to 18.3.1 * Escape * with quotes * Update deny.toml, ADD orchestration in runtime Dockerfile * Add --detach to the Monero GH CI * Diversify dockerfiles by network * Fixes to network-diversified orchestration * Bitcoin and Monero testnet scripts * Permissions and tweaks * Flatten scripts folders * Add missing folder specification to Monero Dockerfile * Have monero-wallet-rpc specify the monerod login * Have the Docker CMD specify env variables inserted at time of Dockerfile generation They're overrideable with the global enviornment as for tests. This enables variable generation in orchestrator and output to productionized Docker files without creating a life-long file within the Docker container. * Don't add Dockerfiles into Docker containers now that they have secrets Solely add the source code for them as needed to satisfy the workspace bounds. * Download arm64 Monero on arm64 * Ensure constant host architecture when reproducibly building the wasm Host architecture, for some reason, can effect the generated code despite the target architecture always being foreign to the host architecture. * Randomly generate infrastructure keys * Have orchestrator generate a key, be able to create/start containers * Ensure bash is used over sh * Clean dated docs * Change how quoting occurs * Standardize to sh * Have Docker test build the dev Dockerfiles * Only key_gen once * cargo update Adds a patch for zstd and reconciles the breaking nightly change which just occurred. * Use a dedicated network for Serai Also fixes SERAI_HOSTNAME passed to coordinator. * Support providing a key over the env for the Serai node * Enable and document running daemons for tests via serai-orchestrator Has running containers under the dev network port forward the RPC ports. * Use volumes for bitcoin/monero * Use bitcoin's run.sh in GH CI * Only use the volume for testnet (not dev)
2024-02-09 07:48:44 +00:00
) = new_partial(&config)?;
config.network.node_name = "serai".to_string();
config.network.client_version = "0.1.0".to_string();
config.network.listen_addresses =
vec!["/ip4/0.0.0.0/tcp/30333".parse().unwrap(), "/ip6/::/tcp/30333".parse().unwrap()];
2023-06-28 18:57:58 +00:00
let mut net_config = sc_network::config::FullNetworkConfiguration::new(&config.network);
let grandpa_protocol_name =
grandpa::protocol_standard_name(&client.block_hash(0).unwrap().unwrap(), &config.chain_spec);
2023-06-28 18:57:58 +00:00
net_config.add_notification_protocol(sc_consensus_grandpa::grandpa_peers_set_config(
grandpa_protocol_name.clone(),
));
let publish_non_global_ips = config.network.allow_non_globals_in_dht;
let warp_sync = Arc::new(grandpa::warp_proof::NetworkProvider::new(
backend.clone(),
grandpa_link.shared_authority_set().clone(),
vec![],
));
let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) =
2022-07-15 05:26:07 +00:00
sc_service::build_network(sc_service::BuildNetworkParams {
config: &config,
2023-06-28 18:57:58 +00:00
net_config,
client: client.clone(),
transaction_pool: transaction_pool.clone(),
spawn_handle: task_manager.spawn_handle(),
import_queue,
block_announce_validator_builder: None,
warp_sync_params: Some(WarpSyncParams::WithProvider(warp_sync)),
2022-07-15 05:26:07 +00:00
})?;
task_manager.spawn_handle().spawn("bootnodes", "bootnodes", {
let network = network.clone();
let id = config.chain_spec.id().to_string();
async move {
// Transforms the above Multiaddrs into MultiaddrWithPeerIds
// While the PeerIds *should* be known in advance and hardcoded, that data wasn't collected in
// time and this fine for a testnet
let bootnodes = || async {
use libp2p::{Transport as TransportTrait, tcp::tokio::Transport, noise::Config};
let bootnode_multiaddrs = crate::chain_spec::bootnode_multiaddrs(&id);
let mut tasks = vec![];
for multiaddr in bootnode_multiaddrs {
tasks.push(tokio::time::timeout(
core::time::Duration::from_secs(10),
tokio::task::spawn(async move {
let Ok(noise) = Config::new(&sc_network::Keypair::generate_ed25519()) else { None? };
let mut transport = Transport::default()
.upgrade(libp2p::core::upgrade::Version::V1)
.authenticate(noise)
.multiplex(libp2p::yamux::Config::default());
let Ok(transport) = transport.dial(multiaddr.clone()) else { None? };
let Ok((peer_id, _)) = transport.await else { None? };
Some(sc_network::config::MultiaddrWithPeerId { multiaddr, peer_id })
}),
));
}
let mut res = vec![];
for task in tasks {
if let Ok(Ok(Some(bootnode))) = task.await {
res.push(bootnode);
}
}
res
};
use sc_network::{NetworkStatusProvider, NetworkPeers};
loop {
if let Ok(status) = network.status().await {
if status.num_connected_peers < 3 {
for bootnode in bootnodes().await {
let _ = network.add_reserved_peer(bootnode);
}
}
}
tokio::time::sleep(core::time::Duration::from_secs(60)).await;
}
}
});
if config.offchain_worker.enabled {
2023-07-19 02:30:55 +00:00
task_manager.spawn_handle().spawn(
"offchain-workers-runner",
"offchain-worker",
sc_offchain::OffchainWorkers::new(sc_offchain::OffchainWorkerOptions {
runtime_api_provider: client.clone(),
is_validator: config.role.is_authority(),
Redo Dockerfile generation (#530) Moves from concatted Dockerfiles to pseudo-templated Dockerfiles via a dedicated Rust program. Removes the unmaintained kubernetes, not because we shouldn't have/use it, but because it's unmaintained and needs to be reworked before it's present again. Replaces the compose with the work in the new orchestrator binary which spawns everything as expected. While this arguably re-invents the wheel, it correctly manages secrets and handles the variadic Dockerfiles. Also adds an unrelated patch for zstd and simplifies running services a bit by greater utilizing the existing infrastructure. --- * Delete all Dockerfile fragments, add new orchestator to generate Dockerfiles Enables greater templating. Also delete the unmaintained kubernetes folder *for now*. This should be restored in the future. * Use Dockerfiles from the orchestator * Ignore Dockerfiles in the git repo * Remove CI job to check Dockerfiles are as expected now that they're no longer committed * Remove old Dockerfiles from repo * Use Debian for monero-wallet-rpc * Remove replace_cmds for proper usage of entry-dev Consolidates ports a bit. Updates serai-docker-tests from "compose" to "build". * Only write a new dockerfile if it's distinct Preserves the updated time metadata. * Update serai-docker-tests * Correct the path Dockerfiles are built from * Correct inclusion of orchestration folder in Docker builds * Correct debug/release flagging in the cargo command Apparently, --debug isn't an effective NOP yet an error. * Correct path used to run the Serai node within a Dockerfile * Correct path in Monero Dockerfile * Attempt storing monerod in /usr/bin * Use sudo to move into /usr/bin in CI * Correct 18.3.0 to 18.3.1 * Escape * with quotes * Update deny.toml, ADD orchestration in runtime Dockerfile * Add --detach to the Monero GH CI * Diversify dockerfiles by network * Fixes to network-diversified orchestration * Bitcoin and Monero testnet scripts * Permissions and tweaks * Flatten scripts folders * Add missing folder specification to Monero Dockerfile * Have monero-wallet-rpc specify the monerod login * Have the Docker CMD specify env variables inserted at time of Dockerfile generation They're overrideable with the global enviornment as for tests. This enables variable generation in orchestrator and output to productionized Docker files without creating a life-long file within the Docker container. * Don't add Dockerfiles into Docker containers now that they have secrets Solely add the source code for them as needed to satisfy the workspace bounds. * Download arm64 Monero on arm64 * Ensure constant host architecture when reproducibly building the wasm Host architecture, for some reason, can effect the generated code despite the target architecture always being foreign to the host architecture. * Randomly generate infrastructure keys * Have orchestrator generate a key, be able to create/start containers * Ensure bash is used over sh * Clean dated docs * Change how quoting occurs * Standardize to sh * Have Docker test build the dev Dockerfiles * Only key_gen once * cargo update Adds a patch for zstd and reconciles the breaking nightly change which just occurred. * Use a dedicated network for Serai Also fixes SERAI_HOSTNAME passed to coordinator. * Support providing a key over the env for the Serai node * Enable and document running daemons for tests via serai-orchestrator Has running containers under the dev network port forward the RPC ports. * Use volumes for bitcoin/monero * Use bitcoin's run.sh in GH CI * Only use the volume for testnet (not dev)
2024-02-09 07:48:44 +00:00
keystore: Some(keystore_container.clone()),
2023-07-19 02:30:55 +00:00
offchain_db: backend.offchain_storage(),
transaction_pool: Some(OffchainTransactionPoolFactory::new(transaction_pool.clone())),
network_provider: network.clone(),
enable_http_requests: true,
custom_extensions: |_| vec![],
})
.run(client.clone(), task_manager.spawn_handle()),
);
}
let role = config.role.clone();
Redo Dockerfile generation (#530) Moves from concatted Dockerfiles to pseudo-templated Dockerfiles via a dedicated Rust program. Removes the unmaintained kubernetes, not because we shouldn't have/use it, but because it's unmaintained and needs to be reworked before it's present again. Replaces the compose with the work in the new orchestrator binary which spawns everything as expected. While this arguably re-invents the wheel, it correctly manages secrets and handles the variadic Dockerfiles. Also adds an unrelated patch for zstd and simplifies running services a bit by greater utilizing the existing infrastructure. --- * Delete all Dockerfile fragments, add new orchestator to generate Dockerfiles Enables greater templating. Also delete the unmaintained kubernetes folder *for now*. This should be restored in the future. * Use Dockerfiles from the orchestator * Ignore Dockerfiles in the git repo * Remove CI job to check Dockerfiles are as expected now that they're no longer committed * Remove old Dockerfiles from repo * Use Debian for monero-wallet-rpc * Remove replace_cmds for proper usage of entry-dev Consolidates ports a bit. Updates serai-docker-tests from "compose" to "build". * Only write a new dockerfile if it's distinct Preserves the updated time metadata. * Update serai-docker-tests * Correct the path Dockerfiles are built from * Correct inclusion of orchestration folder in Docker builds * Correct debug/release flagging in the cargo command Apparently, --debug isn't an effective NOP yet an error. * Correct path used to run the Serai node within a Dockerfile * Correct path in Monero Dockerfile * Attempt storing monerod in /usr/bin * Use sudo to move into /usr/bin in CI * Correct 18.3.0 to 18.3.1 * Escape * with quotes * Update deny.toml, ADD orchestration in runtime Dockerfile * Add --detach to the Monero GH CI * Diversify dockerfiles by network * Fixes to network-diversified orchestration * Bitcoin and Monero testnet scripts * Permissions and tweaks * Flatten scripts folders * Add missing folder specification to Monero Dockerfile * Have monero-wallet-rpc specify the monerod login * Have the Docker CMD specify env variables inserted at time of Dockerfile generation They're overrideable with the global enviornment as for tests. This enables variable generation in orchestrator and output to productionized Docker files without creating a life-long file within the Docker container. * Don't add Dockerfiles into Docker containers now that they have secrets Solely add the source code for them as needed to satisfy the workspace bounds. * Download arm64 Monero on arm64 * Ensure constant host architecture when reproducibly building the wasm Host architecture, for some reason, can effect the generated code despite the target architecture always being foreign to the host architecture. * Randomly generate infrastructure keys * Have orchestrator generate a key, be able to create/start containers * Ensure bash is used over sh * Clean dated docs * Change how quoting occurs * Standardize to sh * Have Docker test build the dev Dockerfiles * Only key_gen once * cargo update Adds a patch for zstd and reconciles the breaking nightly change which just occurred. * Use a dedicated network for Serai Also fixes SERAI_HOSTNAME passed to coordinator. * Support providing a key over the env for the Serai node * Enable and document running daemons for tests via serai-orchestrator Has running containers under the dev network port forward the RPC ports. * Use volumes for bitcoin/monero * Use bitcoin's run.sh in GH CI * Only use the volume for testnet (not dev)
2024-02-09 07:48:44 +00:00
let keystore = keystore_container;
let prometheus_registry = config.prometheus_registry().cloned();
// TODO: Ensure we're considered as an authority is a validator of an external network
let authority_discovery = if role.is_authority() {
let (worker, service) = sc_authority_discovery::new_worker_and_service_with_config(
#[allow(clippy::field_reassign_with_default)]
{
let mut worker = sc_authority_discovery::WorkerConfig::default();
worker.publish_non_global_ips = publish_non_global_ips;
worker.strict_record_validation = true;
worker
},
client.clone(),
network.clone(),
Box::pin(network.event_stream("authority-discovery").filter_map(|e| async move {
match e {
Event::Dht(e) => Some(e),
_ => None,
}
})),
sc_authority_discovery::Role::PublishAndDiscover(keystore.clone()),
prometheus_registry.clone(),
);
task_manager.spawn_handle().spawn(
"authority-discovery-worker",
Some("networking"),
worker.run(),
);
Some(service)
} else {
None
};
let rpc_builder = {
let id = config.chain_spec.id().to_string();
let client = client.clone();
let pool = transaction_pool.clone();
2022-07-15 05:26:07 +00:00
Box::new(move |deny_unsafe, _| {
crate::rpc::create_full(crate::rpc::FullDeps {
id: id.clone(),
2022-07-15 05:26:07 +00:00
client: client.clone(),
pool: pool.clone(),
deny_unsafe,
authority_discovery: authority_discovery.clone(),
2022-07-15 05:26:07 +00:00
})
.map_err(Into::into)
})
};
let enable_grandpa = !config.disable_grandpa;
let force_authoring = config.force_authoring;
let name = config.network.node_name.clone();
Initial Tendermint implementation (#145) * Machine without timeouts * Time code * Move substrate/consensus/tendermint to substrate/tendermint * Delete the old paper doc * Refactor out external parts to generics Also creates a dedicated file for the message log. * Refactor <V, B> to type V, type B * Successfully compiling * Calculate timeouts * Fix test * Finish timeouts * Misc cleanup * Define a signature scheme trait * Implement serialization via parity's scale codec Ideally, this would be generic. Unfortunately, the generic API serde doesn't natively support borsh, nor SCALE, and while there is a serde SCALE crate, it's old. While it may be complete, it's not worth working with. While we could still grab bincode, and a variety of other formats, it wasn't worth it to go custom and for Serai, we'll be using SCALE almost everywhere anyways. * Implement usage of the signature scheme * Make the infinite test non-infinite * Provide a dedicated signature in Precommit of just the block hash Greatly simplifies verifying when syncing. * Dedicated Commit object Restores sig aggregation API. * Tidy README * Document tendermint * Sign the ID directly instead of its SCALE encoding For a hash, which is fixed-size, these should be the same yet this helps move past the dependency on SCALE. It also, for any type where the two values are different, smooths integration. * Litany of bug fixes Also attempts to make the code more readable while updating/correcting documentation. * Remove async recursion Greatly increases safety as well by ensuring only one message is processed at once. * Correct timing issues 1) Commit didn't include the round, leaving the clock in question. 2) Machines started with a local time, instead of a proper start time. 3) Machines immediately started the next block instead of waiting for the block time. * Replace MultiSignature with sr25519::Signature * Minor SignatureScheme API changes * Map TM SignatureScheme to Substrate's sr25519 * Initial work on an import queue * Properly use check_block * Rename import to import_queue * Implement tendermint_machine::Block for Substrate Blocks Unfortunately, this immediately makes Tendermint machine capable of deployment as crate since it uses a git reference. In the future, a Cargo.toml patch section for serai/substrate should be investigated. This is being done regardless as it's the quickest way forward and this is for Serai. * Dummy Weights * Move documentation to the top of the file * Move logic into TendermintImport itself Multiple traits exist to verify/handle blocks. I'm unsure exactly when each will be called in the pipeline, so the easiest solution is to have every step run every check. That would be extremely computationally expensive if we ran EVERY check, yet we rely on Substrate for execution (and according checks), which are limited to just the actual import function. Since we're calling this code from many places, it makes sense for it to be consolidated under TendermintImport. * BlockImport, JustificationImport, Verifier, and import_queue function * Update consensus/lib.rs from PoW to Tendermint Not possible to be used as the previous consensus could. It will not produce blocks nor does it currenly even instantiate a machine. This is just he next step. * Update Cargo.tomls for substrate packages * Tendermint SelectChain This is incompatible with Substrate's expectations, yet should be valid for ours * Move the node over to the new SelectChain * Minor tweaks * Update SelectChain documentation * Remove substrate/node lib.rs This shouldn't be used as a library AFAIK. While runtime should be, and arguably should even be published, I have yet to see node in the same way. Helps tighten API boundaries. * Remove unused macro_use * Replace panicking todos with stubs and // TODO Enables progress. * Reduce chain_spec and use more accurate naming * Implement block proposal logic * Modularize to get_proposal * Trigger block importing Doesn't wait for the response yet, which it needs to. * Get the result of block importing * Split import_queue into a series of files * Provide a way to create the machine The BasicQueue returned obscures the TendermintImport struct. Accordingly, a Future scoped with access is returned upwards, which when awaited will create the machine. This makes creating the machine optional while maintaining scope boundaries. Is sufficient to create a 1-node net which produces and finalizes blocks. * Don't import justifications multiple times Also don't broadcast blocks which were solely proposed. * Correct justication import pipeline Removes JustificationImport as it should never be used. * Announce blocks By claiming File, they're not sent ovber the P2P network before they have a justification, as desired. Unfortunately, they never were. This works around that. * Add an assert to verify proposed children aren't best * Consolidate C and I generics into a TendermintClient trait alias * Expand sanity checks Substrate doesn't expect nor officially support children with less work than their parents. It's a trick used here. Accordingly, ensure the trick's validity. * When resetting, use the end time of the round which was committed to The machine reset to the end time of the current round. For a delayed network connection, a machine may move ahead in rounds and only later realize a prior round succeeded. Despite acknowledging that round's success, it would maintain its delay when moving to the next block, bricking it. Done by tracking the end time for each round as they occur. * Move Commit from including the round to including the round's end_time The round was usable to build the current clock in an accumulated fashion, relative to the previous round. The end time is the absolute metric of it, which can be used to calculate the round number (with all previous end times). Substrate now builds off the best block, not genesis, using the end time included in the justification to start its machine in a synchronized state. Knowing the end time of a round, or the round in which block was committed to, is necessary for nodes to sync up with Tendermint. Encoding it in the commit ensures it's long lasting and makes it readily available, without the load of an entire transaction. * Add a TODO on Tendermint * Misc bug fixes * More misc bug fixes * Clean up lock acquisition * Merge weights and signing scheme into validators, documenting needed changes * Add pallet sessions to runtime, create pallet-tendermint * Update node to use pallet sessions * Update support URL * Partial work on correcting pallet calls * Redo Tendermint folder structure * TendermintApi, compilation fixes * Fix the stub round robin At some point, the modulus was removed causing it to exceed the validators list and stop proposing. * Use the validators list from the session pallet * Basic Gossip Validator * Correct Substrate Tendermint start block The Tendermint machine uses the passed in number as the block's being worked on number. Substrate passed in the already finalized block's number. Also updates misc comments. * Clean generics in Tendermint with a monolith with associated types * Remove the Future triggering the machine for an async fn Enables passing data in, such as the network. * Move TendermintMachine from start_num, time to last_num, time Provides an explicitly clear API clearer to program around. Also adds additional time code to handle an edge case. * Connect the Tendermint machine to a GossipEngine * Connect broadcast * Remove machine from TendermintImport It's not used there at all. * Merge Verifier into block_import.rs These two files were largely the same, just hooking into sync structs with almost identical imports. As this project shapes up, removing dead weight is appreciated. * Create a dedicated file for being a Tendermint authority * Deleted comment code related to PoW * Move serai_runtime specific code from tendermint/client to node Renames serai-consensus to sc_tendermint * Consolidate file structure in sc_tendermint * Replace best_* with finalized_* We test their equivalency yet still better to use finalized_* in general. * Consolidate references to sr25519 in sc_tendermint * Add documentation to public structs/functions in sc_tendermint * Add another missing comment * Make sign asynchronous Some relation to https://github.com/serai-dex/serai/issues/95. * Move sc_tendermint to async sign * Implement proper checking of inherents * Take in a Keystore and validator ID * Remove unnecessary PhantomDatas * Update node to latest sc_tendermint * Configure node for a multi-node testnet * Fix handling of the GossipEngine * Use a rounded genesis to obtain sufficient synchrony within the Docker env * Correct Serai d-f names in Docker * Remove an attempt at caching I don't believe would ever hit * Add an already in chain check to block import While the inner should do this for us, we call verify_order on our end *before* inner to ensure sequential import. Accordingly, we need to provide our own check. Removes errors of "non-sequential import" when trying to re-import an existing block. * Update the consensus documentation It was incredibly out of date. * Add a _ to the validator arg in slash * Make the dev profile a local testnet profile Restores a dev profile which only has one validator, locally running. * Reduce Arcs in TendermintMachine, split Signer from SignatureScheme * Update sc_tendermint per previous commit * Restore cache * Remove error case which shouldn't be an error * Stop returning errors on already existing blocks entirely * Correct Dave, Eve, and Ferdie to not run as validators * Rename dev to devnet --dev still works thanks to the |. Acheieves a personal preference of mine with some historical meaning. * Add message expiry to the Tendermint gossip * Localize the LibP2P protocol to the blockchain Follows convention by doing so. Theoretically enables running multiple blockchains over a single LibP2P connection. * Add a version to sp-runtime in tendermint-machine * Add missing trait * Bump Substrate dependency Fixes #147. * Implement Schnorr half-aggregation from https://eprint.iacr.org/2021/350.pdf Relevant to https://github.com/serai-dex/serai/issues/99. * cargo update (tendermint) * Move from polling loops to a pure IO model for sc_tendermint's gossip * Correct protocol name handling * Use futures mpsc instead of tokio * Timeout futures * Move from a yielding loop to select in tendermint-machine * Update Substrate to the new TendermintHandle * Use futures pin instead of tokio * Only recheck blocks with non-fatal inherent transaction errors * Update to the latest substrate * Separate the block processing time from the latency * Add notes to the runtime * Don't spam slash Also adds a slash condition of failing to propose. * Support running TendermintMachine when not a validator This supports validators who leave the current set, without crashing their nodes, along with nodes trying to become validators (who will now seamlessly transition in). * Properly define and pass around the block size * Correct the Duration timing The proposer will build it, send it, then process it (on the first round). Accordingly, it's / 3, not / 2, as / 2 only accounted for the latter events. * Correct time-adjustment code on round skip * Have the machine respond to advances made by an external sync loop * Clean up time code in tendermint-machine * BlockData and RoundData structs * Rename Round to RoundNumber * Move BlockData to a new file * Move Round to an Option due to the pseudo-uninitialized state we create Before the addition of RoundData, we always created the round, and on .round(0), simply created it again. With RoundData, and the changes to the time code, we used round 0, time 0, the latter being incorrect yet not an issue due to lack of misuse. Now, if we do misuse it, it'll panic. * Clear the Queue instead of draining and filtering There shouldn't ever be a message which passes the filter under the current design. * BlockData::new * Move more code into block.rs Introduces type-aliases to obtain Data/Message/SignedMessage solely from a Network object. Fixes a bug regarding stepping when you're not an active validator. * Have verify_precommit_signature return if it verified the signature Also fixes a bug where invalid precommit signatures were left standing and therefore contributing to commits. * Remove the precommit signature hash It cached signatures per-block. Precommit signatures are bound to each round. This would lead to forming invalid commits when a commit should be formed. Under debug, the machine would catch that and panic. On release, it'd have everyone who wasn't a validator fail to continue syncing. * Slight doc changes Also flattens the message handling function by replacing an if containing all following code in the function with an early return for the else case. * Always produce notifications for finalized blocks via origin overrides * Correct weird formatting * Update to the latest tendermint-machine * Manually step the Tendermint machine when we synced a block over the network * Ignore finality notifications for old blocks * Remove a TODO resolved in 8c51bc011d03c8d54ded05011e7f4d1a01e9f873 * Add a TODO comment to slash Enables searching for the case-sensitive phrase and finding it. * cargo fmt * Use a tmp DB for Serai in Docker * Remove panic on slash As we move towards protonet, this can happen (if a node goes offline), yet it happening brings down the entire net right now. * Add log::error on slash * created shared volume between containers * Complete the sh scripts * Pass in the genesis time to Substrate * Correct block announcements They were announced, yet not marked best. * Correct pupulate_end_time It was used as inclusive yet didn't work inclusively. * Correct gossip channel jumping when a block is synced via Substrate * Use a looser check in import_future This triggered so it needs to be accordingly relaxed. * Correct race conditions between add_block and step Also corrects a <= to <. * Update cargo deny * rename genesis-service to genesis * Update Cargo.lock * Correct runtime Cargo.toml whitespace * Correct typo * Document recheck * Misc lints * Fix prev commit * Resolve low-hanging review comments * Mark genesis/entry-dev.sh as executable * Prevent a commit from including the same signature multiple times Yanks tendermint-machine 0.1.0 accordingly. * Update to latest nightly clippy * Improve documentation * Use clearer variable names * Add log statements * Pair more log statements * Clean TendermintAuthority::authority as possible Merges it into new. It has way too many arguments, yet there's no clear path at consolidation there, unfortunately. Additionally provides better scoping within itself. * Fix #158 Doesn't use lock_import_and_run for reasons commented (lack of async). * Rename guard to lock * Have the devnet use the current time as the genesis Possible since it's only a single node, not requiring synchronization. * Fix gossiping I really don't know what side effect this avoids and I can't say I care at this point. * Misc lints Co-authored-by: vrx00 <vrx00@proton.me> Co-authored-by: TheArchitect108 <TheArchitect108@protonmail.com>
2022-12-03 23:38:02 +00:00
2022-07-15 05:26:07 +00:00
sc_service::spawn_tasks(sc_service::SpawnTasksParams {
config,
backend,
2022-07-15 05:26:07 +00:00
client: client.clone(),
keystore: keystore.clone(),
network: network.clone(),
rpc_builder,
2022-07-15 05:26:07 +00:00
transaction_pool: transaction_pool.clone(),
task_manager: &mut task_manager,
2022-07-15 05:26:07 +00:00
system_rpc_tx,
tx_handler_controller,
sync_service: sync_service.clone(),
2022-07-15 05:26:07 +00:00
telemetry: telemetry.as_mut(),
})?;
if let sc_service::config::Role::Authority { .. } = &role {
let slot_duration = babe_link.config().slot_duration();
let babe_config = sc_consensus_babe::BabeParams {
keystore: keystore.clone(),
client: client.clone(),
select_chain,
env: sc_basic_authorship::ProposerFactory::new(
task_manager.spawn_handle(),
client,
2023-07-19 02:30:55 +00:00
transaction_pool.clone(),
prometheus_registry.as_ref(),
telemetry.as_ref().map(Telemetry::handle),
),
block_import,
sync_oracle: sync_service.clone(),
justification_sync_link: sync_service.clone(),
2023-12-17 01:54:24 +00:00
create_inherent_data_providers: move |_, ()| async move {
Ok(create_inherent_data_providers(slot_duration))
},
force_authoring,
backoff_authoring_blocks: None::<()>,
babe_link,
block_proposal_slot_portion: SlotProportion::new(0.5),
max_block_proposal_slot_portion: None,
telemetry: telemetry.as_ref().map(Telemetry::handle),
};
task_manager.spawn_essential_handle().spawn_blocking(
"babe-proposer",
Some("block-authoring"),
sc_consensus_babe::start_babe(babe_config)?,
);
}
if enable_grandpa {
task_manager.spawn_essential_handle().spawn_blocking(
"grandpa-voter",
Initial Tendermint implementation (#145) * Machine without timeouts * Time code * Move substrate/consensus/tendermint to substrate/tendermint * Delete the old paper doc * Refactor out external parts to generics Also creates a dedicated file for the message log. * Refactor <V, B> to type V, type B * Successfully compiling * Calculate timeouts * Fix test * Finish timeouts * Misc cleanup * Define a signature scheme trait * Implement serialization via parity's scale codec Ideally, this would be generic. Unfortunately, the generic API serde doesn't natively support borsh, nor SCALE, and while there is a serde SCALE crate, it's old. While it may be complete, it's not worth working with. While we could still grab bincode, and a variety of other formats, it wasn't worth it to go custom and for Serai, we'll be using SCALE almost everywhere anyways. * Implement usage of the signature scheme * Make the infinite test non-infinite * Provide a dedicated signature in Precommit of just the block hash Greatly simplifies verifying when syncing. * Dedicated Commit object Restores sig aggregation API. * Tidy README * Document tendermint * Sign the ID directly instead of its SCALE encoding For a hash, which is fixed-size, these should be the same yet this helps move past the dependency on SCALE. It also, for any type where the two values are different, smooths integration. * Litany of bug fixes Also attempts to make the code more readable while updating/correcting documentation. * Remove async recursion Greatly increases safety as well by ensuring only one message is processed at once. * Correct timing issues 1) Commit didn't include the round, leaving the clock in question. 2) Machines started with a local time, instead of a proper start time. 3) Machines immediately started the next block instead of waiting for the block time. * Replace MultiSignature with sr25519::Signature * Minor SignatureScheme API changes * Map TM SignatureScheme to Substrate's sr25519 * Initial work on an import queue * Properly use check_block * Rename import to import_queue * Implement tendermint_machine::Block for Substrate Blocks Unfortunately, this immediately makes Tendermint machine capable of deployment as crate since it uses a git reference. In the future, a Cargo.toml patch section for serai/substrate should be investigated. This is being done regardless as it's the quickest way forward and this is for Serai. * Dummy Weights * Move documentation to the top of the file * Move logic into TendermintImport itself Multiple traits exist to verify/handle blocks. I'm unsure exactly when each will be called in the pipeline, so the easiest solution is to have every step run every check. That would be extremely computationally expensive if we ran EVERY check, yet we rely on Substrate for execution (and according checks), which are limited to just the actual import function. Since we're calling this code from many places, it makes sense for it to be consolidated under TendermintImport. * BlockImport, JustificationImport, Verifier, and import_queue function * Update consensus/lib.rs from PoW to Tendermint Not possible to be used as the previous consensus could. It will not produce blocks nor does it currenly even instantiate a machine. This is just he next step. * Update Cargo.tomls for substrate packages * Tendermint SelectChain This is incompatible with Substrate's expectations, yet should be valid for ours * Move the node over to the new SelectChain * Minor tweaks * Update SelectChain documentation * Remove substrate/node lib.rs This shouldn't be used as a library AFAIK. While runtime should be, and arguably should even be published, I have yet to see node in the same way. Helps tighten API boundaries. * Remove unused macro_use * Replace panicking todos with stubs and // TODO Enables progress. * Reduce chain_spec and use more accurate naming * Implement block proposal logic * Modularize to get_proposal * Trigger block importing Doesn't wait for the response yet, which it needs to. * Get the result of block importing * Split import_queue into a series of files * Provide a way to create the machine The BasicQueue returned obscures the TendermintImport struct. Accordingly, a Future scoped with access is returned upwards, which when awaited will create the machine. This makes creating the machine optional while maintaining scope boundaries. Is sufficient to create a 1-node net which produces and finalizes blocks. * Don't import justifications multiple times Also don't broadcast blocks which were solely proposed. * Correct justication import pipeline Removes JustificationImport as it should never be used. * Announce blocks By claiming File, they're not sent ovber the P2P network before they have a justification, as desired. Unfortunately, they never were. This works around that. * Add an assert to verify proposed children aren't best * Consolidate C and I generics into a TendermintClient trait alias * Expand sanity checks Substrate doesn't expect nor officially support children with less work than their parents. It's a trick used here. Accordingly, ensure the trick's validity. * When resetting, use the end time of the round which was committed to The machine reset to the end time of the current round. For a delayed network connection, a machine may move ahead in rounds and only later realize a prior round succeeded. Despite acknowledging that round's success, it would maintain its delay when moving to the next block, bricking it. Done by tracking the end time for each round as they occur. * Move Commit from including the round to including the round's end_time The round was usable to build the current clock in an accumulated fashion, relative to the previous round. The end time is the absolute metric of it, which can be used to calculate the round number (with all previous end times). Substrate now builds off the best block, not genesis, using the end time included in the justification to start its machine in a synchronized state. Knowing the end time of a round, or the round in which block was committed to, is necessary for nodes to sync up with Tendermint. Encoding it in the commit ensures it's long lasting and makes it readily available, without the load of an entire transaction. * Add a TODO on Tendermint * Misc bug fixes * More misc bug fixes * Clean up lock acquisition * Merge weights and signing scheme into validators, documenting needed changes * Add pallet sessions to runtime, create pallet-tendermint * Update node to use pallet sessions * Update support URL * Partial work on correcting pallet calls * Redo Tendermint folder structure * TendermintApi, compilation fixes * Fix the stub round robin At some point, the modulus was removed causing it to exceed the validators list and stop proposing. * Use the validators list from the session pallet * Basic Gossip Validator * Correct Substrate Tendermint start block The Tendermint machine uses the passed in number as the block's being worked on number. Substrate passed in the already finalized block's number. Also updates misc comments. * Clean generics in Tendermint with a monolith with associated types * Remove the Future triggering the machine for an async fn Enables passing data in, such as the network. * Move TendermintMachine from start_num, time to last_num, time Provides an explicitly clear API clearer to program around. Also adds additional time code to handle an edge case. * Connect the Tendermint machine to a GossipEngine * Connect broadcast * Remove machine from TendermintImport It's not used there at all. * Merge Verifier into block_import.rs These two files were largely the same, just hooking into sync structs with almost identical imports. As this project shapes up, removing dead weight is appreciated. * Create a dedicated file for being a Tendermint authority * Deleted comment code related to PoW * Move serai_runtime specific code from tendermint/client to node Renames serai-consensus to sc_tendermint * Consolidate file structure in sc_tendermint * Replace best_* with finalized_* We test their equivalency yet still better to use finalized_* in general. * Consolidate references to sr25519 in sc_tendermint * Add documentation to public structs/functions in sc_tendermint * Add another missing comment * Make sign asynchronous Some relation to https://github.com/serai-dex/serai/issues/95. * Move sc_tendermint to async sign * Implement proper checking of inherents * Take in a Keystore and validator ID * Remove unnecessary PhantomDatas * Update node to latest sc_tendermint * Configure node for a multi-node testnet * Fix handling of the GossipEngine * Use a rounded genesis to obtain sufficient synchrony within the Docker env * Correct Serai d-f names in Docker * Remove an attempt at caching I don't believe would ever hit * Add an already in chain check to block import While the inner should do this for us, we call verify_order on our end *before* inner to ensure sequential import. Accordingly, we need to provide our own check. Removes errors of "non-sequential import" when trying to re-import an existing block. * Update the consensus documentation It was incredibly out of date. * Add a _ to the validator arg in slash * Make the dev profile a local testnet profile Restores a dev profile which only has one validator, locally running. * Reduce Arcs in TendermintMachine, split Signer from SignatureScheme * Update sc_tendermint per previous commit * Restore cache * Remove error case which shouldn't be an error * Stop returning errors on already existing blocks entirely * Correct Dave, Eve, and Ferdie to not run as validators * Rename dev to devnet --dev still works thanks to the |. Acheieves a personal preference of mine with some historical meaning. * Add message expiry to the Tendermint gossip * Localize the LibP2P protocol to the blockchain Follows convention by doing so. Theoretically enables running multiple blockchains over a single LibP2P connection. * Add a version to sp-runtime in tendermint-machine * Add missing trait * Bump Substrate dependency Fixes #147. * Implement Schnorr half-aggregation from https://eprint.iacr.org/2021/350.pdf Relevant to https://github.com/serai-dex/serai/issues/99. * cargo update (tendermint) * Move from polling loops to a pure IO model for sc_tendermint's gossip * Correct protocol name handling * Use futures mpsc instead of tokio * Timeout futures * Move from a yielding loop to select in tendermint-machine * Update Substrate to the new TendermintHandle * Use futures pin instead of tokio * Only recheck blocks with non-fatal inherent transaction errors * Update to the latest substrate * Separate the block processing time from the latency * Add notes to the runtime * Don't spam slash Also adds a slash condition of failing to propose. * Support running TendermintMachine when not a validator This supports validators who leave the current set, without crashing their nodes, along with nodes trying to become validators (who will now seamlessly transition in). * Properly define and pass around the block size * Correct the Duration timing The proposer will build it, send it, then process it (on the first round). Accordingly, it's / 3, not / 2, as / 2 only accounted for the latter events. * Correct time-adjustment code on round skip * Have the machine respond to advances made by an external sync loop * Clean up time code in tendermint-machine * BlockData and RoundData structs * Rename Round to RoundNumber * Move BlockData to a new file * Move Round to an Option due to the pseudo-uninitialized state we create Before the addition of RoundData, we always created the round, and on .round(0), simply created it again. With RoundData, and the changes to the time code, we used round 0, time 0, the latter being incorrect yet not an issue due to lack of misuse. Now, if we do misuse it, it'll panic. * Clear the Queue instead of draining and filtering There shouldn't ever be a message which passes the filter under the current design. * BlockData::new * Move more code into block.rs Introduces type-aliases to obtain Data/Message/SignedMessage solely from a Network object. Fixes a bug regarding stepping when you're not an active validator. * Have verify_precommit_signature return if it verified the signature Also fixes a bug where invalid precommit signatures were left standing and therefore contributing to commits. * Remove the precommit signature hash It cached signatures per-block. Precommit signatures are bound to each round. This would lead to forming invalid commits when a commit should be formed. Under debug, the machine would catch that and panic. On release, it'd have everyone who wasn't a validator fail to continue syncing. * Slight doc changes Also flattens the message handling function by replacing an if containing all following code in the function with an early return for the else case. * Always produce notifications for finalized blocks via origin overrides * Correct weird formatting * Update to the latest tendermint-machine * Manually step the Tendermint machine when we synced a block over the network * Ignore finality notifications for old blocks * Remove a TODO resolved in 8c51bc011d03c8d54ded05011e7f4d1a01e9f873 * Add a TODO comment to slash Enables searching for the case-sensitive phrase and finding it. * cargo fmt * Use a tmp DB for Serai in Docker * Remove panic on slash As we move towards protonet, this can happen (if a node goes offline), yet it happening brings down the entire net right now. * Add log::error on slash * created shared volume between containers * Complete the sh scripts * Pass in the genesis time to Substrate * Correct block announcements They were announced, yet not marked best. * Correct pupulate_end_time It was used as inclusive yet didn't work inclusively. * Correct gossip channel jumping when a block is synced via Substrate * Use a looser check in import_future This triggered so it needs to be accordingly relaxed. * Correct race conditions between add_block and step Also corrects a <= to <. * Update cargo deny * rename genesis-service to genesis * Update Cargo.lock * Correct runtime Cargo.toml whitespace * Correct typo * Document recheck * Misc lints * Fix prev commit * Resolve low-hanging review comments * Mark genesis/entry-dev.sh as executable * Prevent a commit from including the same signature multiple times Yanks tendermint-machine 0.1.0 accordingly. * Update to latest nightly clippy * Improve documentation * Use clearer variable names * Add log statements * Pair more log statements * Clean TendermintAuthority::authority as possible Merges it into new. It has way too many arguments, yet there's no clear path at consolidation there, unfortunately. Additionally provides better scoping within itself. * Fix #158 Doesn't use lock_import_and_run for reasons commented (lack of async). * Rename guard to lock * Have the devnet use the current time as the genesis Possible since it's only a single node, not requiring synchronization. * Fix gossiping I really don't know what side effect this avoids and I can't say I care at this point. * Misc lints Co-authored-by: vrx00 <vrx00@proton.me> Co-authored-by: TheArchitect108 <TheArchitect108@protonmail.com>
2022-12-03 23:38:02 +00:00
None,
grandpa::run_grandpa_voter(grandpa::GrandpaParams {
config: grandpa::Config {
gossip_duration: std::time::Duration::from_millis(333),
justification_period: 512,
name: Some(name),
observer_enabled: false,
keystore: if role.is_authority() { Some(keystore) } else { None },
local_role: role,
telemetry: telemetry.as_ref().map(Telemetry::handle),
protocol_name: grandpa_protocol_name,
},
link: grandpa_link,
Initial Tendermint implementation (#145) * Machine without timeouts * Time code * Move substrate/consensus/tendermint to substrate/tendermint * Delete the old paper doc * Refactor out external parts to generics Also creates a dedicated file for the message log. * Refactor <V, B> to type V, type B * Successfully compiling * Calculate timeouts * Fix test * Finish timeouts * Misc cleanup * Define a signature scheme trait * Implement serialization via parity's scale codec Ideally, this would be generic. Unfortunately, the generic API serde doesn't natively support borsh, nor SCALE, and while there is a serde SCALE crate, it's old. While it may be complete, it's not worth working with. While we could still grab bincode, and a variety of other formats, it wasn't worth it to go custom and for Serai, we'll be using SCALE almost everywhere anyways. * Implement usage of the signature scheme * Make the infinite test non-infinite * Provide a dedicated signature in Precommit of just the block hash Greatly simplifies verifying when syncing. * Dedicated Commit object Restores sig aggregation API. * Tidy README * Document tendermint * Sign the ID directly instead of its SCALE encoding For a hash, which is fixed-size, these should be the same yet this helps move past the dependency on SCALE. It also, for any type where the two values are different, smooths integration. * Litany of bug fixes Also attempts to make the code more readable while updating/correcting documentation. * Remove async recursion Greatly increases safety as well by ensuring only one message is processed at once. * Correct timing issues 1) Commit didn't include the round, leaving the clock in question. 2) Machines started with a local time, instead of a proper start time. 3) Machines immediately started the next block instead of waiting for the block time. * Replace MultiSignature with sr25519::Signature * Minor SignatureScheme API changes * Map TM SignatureScheme to Substrate's sr25519 * Initial work on an import queue * Properly use check_block * Rename import to import_queue * Implement tendermint_machine::Block for Substrate Blocks Unfortunately, this immediately makes Tendermint machine capable of deployment as crate since it uses a git reference. In the future, a Cargo.toml patch section for serai/substrate should be investigated. This is being done regardless as it's the quickest way forward and this is for Serai. * Dummy Weights * Move documentation to the top of the file * Move logic into TendermintImport itself Multiple traits exist to verify/handle blocks. I'm unsure exactly when each will be called in the pipeline, so the easiest solution is to have every step run every check. That would be extremely computationally expensive if we ran EVERY check, yet we rely on Substrate for execution (and according checks), which are limited to just the actual import function. Since we're calling this code from many places, it makes sense for it to be consolidated under TendermintImport. * BlockImport, JustificationImport, Verifier, and import_queue function * Update consensus/lib.rs from PoW to Tendermint Not possible to be used as the previous consensus could. It will not produce blocks nor does it currenly even instantiate a machine. This is just he next step. * Update Cargo.tomls for substrate packages * Tendermint SelectChain This is incompatible with Substrate's expectations, yet should be valid for ours * Move the node over to the new SelectChain * Minor tweaks * Update SelectChain documentation * Remove substrate/node lib.rs This shouldn't be used as a library AFAIK. While runtime should be, and arguably should even be published, I have yet to see node in the same way. Helps tighten API boundaries. * Remove unused macro_use * Replace panicking todos with stubs and // TODO Enables progress. * Reduce chain_spec and use more accurate naming * Implement block proposal logic * Modularize to get_proposal * Trigger block importing Doesn't wait for the response yet, which it needs to. * Get the result of block importing * Split import_queue into a series of files * Provide a way to create the machine The BasicQueue returned obscures the TendermintImport struct. Accordingly, a Future scoped with access is returned upwards, which when awaited will create the machine. This makes creating the machine optional while maintaining scope boundaries. Is sufficient to create a 1-node net which produces and finalizes blocks. * Don't import justifications multiple times Also don't broadcast blocks which were solely proposed. * Correct justication import pipeline Removes JustificationImport as it should never be used. * Announce blocks By claiming File, they're not sent ovber the P2P network before they have a justification, as desired. Unfortunately, they never were. This works around that. * Add an assert to verify proposed children aren't best * Consolidate C and I generics into a TendermintClient trait alias * Expand sanity checks Substrate doesn't expect nor officially support children with less work than their parents. It's a trick used here. Accordingly, ensure the trick's validity. * When resetting, use the end time of the round which was committed to The machine reset to the end time of the current round. For a delayed network connection, a machine may move ahead in rounds and only later realize a prior round succeeded. Despite acknowledging that round's success, it would maintain its delay when moving to the next block, bricking it. Done by tracking the end time for each round as they occur. * Move Commit from including the round to including the round's end_time The round was usable to build the current clock in an accumulated fashion, relative to the previous round. The end time is the absolute metric of it, which can be used to calculate the round number (with all previous end times). Substrate now builds off the best block, not genesis, using the end time included in the justification to start its machine in a synchronized state. Knowing the end time of a round, or the round in which block was committed to, is necessary for nodes to sync up with Tendermint. Encoding it in the commit ensures it's long lasting and makes it readily available, without the load of an entire transaction. * Add a TODO on Tendermint * Misc bug fixes * More misc bug fixes * Clean up lock acquisition * Merge weights and signing scheme into validators, documenting needed changes * Add pallet sessions to runtime, create pallet-tendermint * Update node to use pallet sessions * Update support URL * Partial work on correcting pallet calls * Redo Tendermint folder structure * TendermintApi, compilation fixes * Fix the stub round robin At some point, the modulus was removed causing it to exceed the validators list and stop proposing. * Use the validators list from the session pallet * Basic Gossip Validator * Correct Substrate Tendermint start block The Tendermint machine uses the passed in number as the block's being worked on number. Substrate passed in the already finalized block's number. Also updates misc comments. * Clean generics in Tendermint with a monolith with associated types * Remove the Future triggering the machine for an async fn Enables passing data in, such as the network. * Move TendermintMachine from start_num, time to last_num, time Provides an explicitly clear API clearer to program around. Also adds additional time code to handle an edge case. * Connect the Tendermint machine to a GossipEngine * Connect broadcast * Remove machine from TendermintImport It's not used there at all. * Merge Verifier into block_import.rs These two files were largely the same, just hooking into sync structs with almost identical imports. As this project shapes up, removing dead weight is appreciated. * Create a dedicated file for being a Tendermint authority * Deleted comment code related to PoW * Move serai_runtime specific code from tendermint/client to node Renames serai-consensus to sc_tendermint * Consolidate file structure in sc_tendermint * Replace best_* with finalized_* We test their equivalency yet still better to use finalized_* in general. * Consolidate references to sr25519 in sc_tendermint * Add documentation to public structs/functions in sc_tendermint * Add another missing comment * Make sign asynchronous Some relation to https://github.com/serai-dex/serai/issues/95. * Move sc_tendermint to async sign * Implement proper checking of inherents * Take in a Keystore and validator ID * Remove unnecessary PhantomDatas * Update node to latest sc_tendermint * Configure node for a multi-node testnet * Fix handling of the GossipEngine * Use a rounded genesis to obtain sufficient synchrony within the Docker env * Correct Serai d-f names in Docker * Remove an attempt at caching I don't believe would ever hit * Add an already in chain check to block import While the inner should do this for us, we call verify_order on our end *before* inner to ensure sequential import. Accordingly, we need to provide our own check. Removes errors of "non-sequential import" when trying to re-import an existing block. * Update the consensus documentation It was incredibly out of date. * Add a _ to the validator arg in slash * Make the dev profile a local testnet profile Restores a dev profile which only has one validator, locally running. * Reduce Arcs in TendermintMachine, split Signer from SignatureScheme * Update sc_tendermint per previous commit * Restore cache * Remove error case which shouldn't be an error * Stop returning errors on already existing blocks entirely * Correct Dave, Eve, and Ferdie to not run as validators * Rename dev to devnet --dev still works thanks to the |. Acheieves a personal preference of mine with some historical meaning. * Add message expiry to the Tendermint gossip * Localize the LibP2P protocol to the blockchain Follows convention by doing so. Theoretically enables running multiple blockchains over a single LibP2P connection. * Add a version to sp-runtime in tendermint-machine * Add missing trait * Bump Substrate dependency Fixes #147. * Implement Schnorr half-aggregation from https://eprint.iacr.org/2021/350.pdf Relevant to https://github.com/serai-dex/serai/issues/99. * cargo update (tendermint) * Move from polling loops to a pure IO model for sc_tendermint's gossip * Correct protocol name handling * Use futures mpsc instead of tokio * Timeout futures * Move from a yielding loop to select in tendermint-machine * Update Substrate to the new TendermintHandle * Use futures pin instead of tokio * Only recheck blocks with non-fatal inherent transaction errors * Update to the latest substrate * Separate the block processing time from the latency * Add notes to the runtime * Don't spam slash Also adds a slash condition of failing to propose. * Support running TendermintMachine when not a validator This supports validators who leave the current set, without crashing their nodes, along with nodes trying to become validators (who will now seamlessly transition in). * Properly define and pass around the block size * Correct the Duration timing The proposer will build it, send it, then process it (on the first round). Accordingly, it's / 3, not / 2, as / 2 only accounted for the latter events. * Correct time-adjustment code on round skip * Have the machine respond to advances made by an external sync loop * Clean up time code in tendermint-machine * BlockData and RoundData structs * Rename Round to RoundNumber * Move BlockData to a new file * Move Round to an Option due to the pseudo-uninitialized state we create Before the addition of RoundData, we always created the round, and on .round(0), simply created it again. With RoundData, and the changes to the time code, we used round 0, time 0, the latter being incorrect yet not an issue due to lack of misuse. Now, if we do misuse it, it'll panic. * Clear the Queue instead of draining and filtering There shouldn't ever be a message which passes the filter under the current design. * BlockData::new * Move more code into block.rs Introduces type-aliases to obtain Data/Message/SignedMessage solely from a Network object. Fixes a bug regarding stepping when you're not an active validator. * Have verify_precommit_signature return if it verified the signature Also fixes a bug where invalid precommit signatures were left standing and therefore contributing to commits. * Remove the precommit signature hash It cached signatures per-block. Precommit signatures are bound to each round. This would lead to forming invalid commits when a commit should be formed. Under debug, the machine would catch that and panic. On release, it'd have everyone who wasn't a validator fail to continue syncing. * Slight doc changes Also flattens the message handling function by replacing an if containing all following code in the function with an early return for the else case. * Always produce notifications for finalized blocks via origin overrides * Correct weird formatting * Update to the latest tendermint-machine * Manually step the Tendermint machine when we synced a block over the network * Ignore finality notifications for old blocks * Remove a TODO resolved in 8c51bc011d03c8d54ded05011e7f4d1a01e9f873 * Add a TODO comment to slash Enables searching for the case-sensitive phrase and finding it. * cargo fmt * Use a tmp DB for Serai in Docker * Remove panic on slash As we move towards protonet, this can happen (if a node goes offline), yet it happening brings down the entire net right now. * Add log::error on slash * created shared volume between containers * Complete the sh scripts * Pass in the genesis time to Substrate * Correct block announcements They were announced, yet not marked best. * Correct pupulate_end_time It was used as inclusive yet didn't work inclusively. * Correct gossip channel jumping when a block is synced via Substrate * Use a looser check in import_future This triggered so it needs to be accordingly relaxed. * Correct race conditions between add_block and step Also corrects a <= to <. * Update cargo deny * rename genesis-service to genesis * Update Cargo.lock * Correct runtime Cargo.toml whitespace * Correct typo * Document recheck * Misc lints * Fix prev commit * Resolve low-hanging review comments * Mark genesis/entry-dev.sh as executable * Prevent a commit from including the same signature multiple times Yanks tendermint-machine 0.1.0 accordingly. * Update to latest nightly clippy * Improve documentation * Use clearer variable names * Add log statements * Pair more log statements * Clean TendermintAuthority::authority as possible Merges it into new. It has way too many arguments, yet there's no clear path at consolidation there, unfortunately. Additionally provides better scoping within itself. * Fix #158 Doesn't use lock_import_and_run for reasons commented (lack of async). * Rename guard to lock * Have the devnet use the current time as the genesis Possible since it's only a single node, not requiring synchronization. * Fix gossiping I really don't know what side effect this avoids and I can't say I care at this point. * Misc lints Co-authored-by: vrx00 <vrx00@proton.me> Co-authored-by: TheArchitect108 <TheArchitect108@protonmail.com>
2022-12-03 23:38:02 +00:00
network,
sync: Arc::new(sync_service),
telemetry: telemetry.as_ref().map(Telemetry::handle),
voting_rule: grandpa::VotingRulesBuilder::default().build(),
prometheus_registry,
shared_voter_state,
2023-07-19 02:30:55 +00:00
offchain_tx_pool_factory: OffchainTransactionPoolFactory::new(transaction_pool),
})?,
);
}
network_starter.start_network();
Ok(task_manager)
}