-
Notifications
You must be signed in to change notification settings - Fork 249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extract genesis config and improve adding builtin services [ECR-3750] #1541
Extract genesis config and improve adding builtin services [ECR-3750] #1541
Conversation
exonum/src/blockchain/config.rs
Outdated
self | ||
} | ||
|
||
pub fn from_spec(instance_spec: InstanceSpec, constructor: impl BinaryValue) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By this method there is no way to set deploy args, is this a correct approach?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. The main intention of this method was using in tests for converting in tests. I wanted to reflect this in the documentation, but forgot. Now I see that this method is now such useful, so probably it will be better to get rid of it.
There are some minor tasks left (like write docs, rename structs), but the PR, in general, is ready for review. |
Codecov Report
@@ Coverage Diff @@
## master #1541 +/- ##
==========================================
- Coverage 93.81% 93.79% -0.03%
==========================================
Files 204 204
Lines 30047 30302 +255
==========================================
+ Hits 28188 28421 +233
- Misses 1859 1881 +22
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments as of 53f362a. I'd suggest to remove InstanceConfig
within this PR; if possible, refactor Node::new()
as well. (Is there a task to make genesis config optional for node startup? If I understand correctly, it is not used once the network is launched.)
exonum/src/node/mod.rs
Outdated
@@ -950,8 +951,14 @@ impl Node { | |||
node_cfg.service_keypair(), | |||
ApiSender::new(channel.api_requests.0.clone()), | |||
); | |||
let blockchain = BlockchainBuilder::new(blockchain, node_cfg.consensus.clone()) | |||
.with_rust_runtime(channel.endpoints.0.clone(), services) | |||
let (rust_runtime, genesis_config) = create_rust_runtime_and_genesis_config( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest to refactor Node::new
for clarity. Ideally, it should accept GenesisConfig
directly or via a field in NodeConfig
(since the consensus config is already there). Likewise, service factories should be accepted instead of InstanceCollection
s.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we even pass service factories here? Wouldn't it be better to pass RustRuntime
populated with factories along with other runtimes instead?
exonum/src/node/mod.rs
Outdated
); | ||
|
||
let blockchain = BlockchainBuilder::new(blockchain, genesis_config) | ||
.with_runtime(rust_runtime) | ||
.with_external_runtimes(external_runtimes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method looks like an redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going to get rid of it during the Node::new()
refactoring.
) | ||
.with_additional_runtime(SampleRuntime::default()) | ||
let supervisor_service = SimpleSupervisor::new(); | ||
let genesis_config = GenesisConfigBuilder::with_consensus_config(consensus_config) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose GenesisConfigBuilder::new().with_consensus_config(consensus_config)
would be more idiomatic ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any condition when we don't want to call with_consensus_config
? I suggest to just rename this method to new
, so it'll be GensisConfigBuilder::new(consensus_config)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However maybe it can be done later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, perhaps it makes sense for this. But I'd also suggest to do this later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that since it's not a common scenario, it's better to have a separate constructor like without_consensus_config
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of comments as of 2e803d0.
test-suite/testkit/src/builder.rs
Outdated
instances: Vec<InstanceInitParams>, | ||
artifacts: HashMap<ArtifactId, Vec<u8>>, | ||
artifacts: HashSet<ArtifactSpec>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a difference between HashMap<ArtifactId, Vec<u8>>
and HashSet<ArtifactSpec>
; the first overrides different specs for the same ArtifactId
, while the second admits several ArtifactId
s with different specs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for pointing out, corrected.
test-suite/testkit/src/builder.rs
Outdated
let (id, runtime) = runtime.into(); | ||
if id == RustRuntime::ID as u32 || self.additional_runtimes.contains_key(&id) { | ||
panic!("TestkitBuilder already contains runtime with id {}", id); | ||
pub fn with_additional_runtime(mut self, runtime: impl Into<RuntimeInstance>) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not impl WellKnownRuntime
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I implemented it in analogue to the BlockchainBuilder.with_runtime()
which has to accept RuntimeInstance
as well, but for this case impl WellKnownRuntime
looks better.
test-suite/testkit/src/builder.rs
Outdated
.or_insert_with(|| deploy_spec.into_bytes()); | ||
pub fn with_artifact(mut self, artifact: impl Into<ArtifactSpec>) -> Self { | ||
let artifact = artifact.into(); | ||
if !self.artifacts.contains(&artifact) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: This check seems redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re-wrote it to be actual again.
self, | ||
runtimes: impl IntoIterator<Item = impl Into<(u32, Box<dyn Runtime>)>>, | ||
) -> TestKit { | ||
pub fn resume(self, runtimes: impl IntoIterator<Item = impl Into<RuntimeInstance>>) -> TestKit { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I'm almost sure this argument won't work with multiple runtimes of different types since the iterator items need to have the same type. Oh well, the old definition had the same problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, in fact, it is used exactly for this situation. More presize - in tests there are a few places where we pass RustRuntime
this way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've avoided all the nitpicks for this to get merged, but there is still one moment I can't agree with.
Once fixed, I'll approve.
exonum/src/runtime/types.rs
Outdated
} | ||
} | ||
|
||
impl<T: Into<ArtifactId>> From<T> for ArtifactSpec { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This conversion seems to be very error-prone, since it hides the fact of setting payload to empty value.
Service having no payload is not an invariant, but From
conversion makes it feel like it is.
I suggest it to be a method with the name explaining it unambiguously, e.g. new_without_spec
(and @slowli originally suggested it to be a method, and his suggestion still makes sense).
exonum/src/runtime/types.rs
Outdated
@@ -324,6 +371,15 @@ impl Display for InstanceSpec { | |||
} | |||
} | |||
|
|||
impl From<InstanceSpec> for InstanceInitParams { | |||
fn from(spec: InstanceSpec) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
/// Adds a new Runtime to the list of available runtimes. | ||
/// | ||
/// Note that you don't have to add a Rust Runtime, since it's included by default. | ||
pub fn with_external_runtime(mut self, runtime: impl Into<(u32, Box<dyn Runtime>)>) -> Self { | ||
pub fn with_external_runtime(mut self, runtime: impl WellKnownRuntime) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One small nit: It turns that all possible runtimes are well known. :)
I think that we should think about trait name after that this PR will be merged.
Overview
UPD: Current status (since [c7abbea]):
ServiceFactory
.InstanceConfig
.Node::new()
.WellKnownRuntime
and the rest of tasks from ECR-3744.InstanceCollection
.See: https://jira.bf.local/browse/ECR-3750, https://jira.bf.local/browse/ECR-3690.
Definition of Done