-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Add block reward contract config to ethash and allow off-chain contracts #9312
Conversation
Hi @sorpaas ! I don't understand, how will it help to avoid use of Thanks! |
@phahulin So when deploying a hard fork, you just replace
For the new one, you add if statement to check the block number:
Note that this parameter is entirely optional, and |
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.
Code LGTM, logic also (but I'm not familiar so don't take my word for it).
Added a few questions and suggestions.
result.map_err(|e| format!("{}", e)) | ||
}; | ||
|
||
let rewards = c.reward(&benefactors, &mut call)?; | ||
let rewards = c.reward(&beneficiaries, &mut call)?; |
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.
+1 at this.
I think the wiki also uses "benefactors" instead of "beneficiaries" which was very confusing to me when I read it.
let result = self.machine.execute_as_system( | ||
block, | ||
to, | ||
U256::max_value(), // unbounded gas? maybe make configurable. |
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 this comment not relevant anymore?
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 the original comment didn't make sense in this case (I copied it from some other usage of execute_code_as_system
😛). It probably makes sense to execute the block reward contract with unbounded gas. Otherwise, if we cap it and it goes out of gas what do we default to? No rewards for that block? The block reward contract is a critical part of consensus so I think the framework should assume it is correct, in this case we should assume that it will terminate, if it doesn't your chain is broken.
@@ -139,7 +163,7 @@ pub fn apply_block_rewards<M: Machine + WithBalances + WithRewards>( | |||
} | |||
|
|||
let rewards: Vec<_> = rewards.into_iter().map(|&(a, k, r)| (a, k.into(), r)).collect(); |
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 line is a little awkward. It would be nice to do this work only if tracing is enabled. I'm not sure what the reason is for having both RewardKind
and RewardType
– is it possible to unify them? That way this line could go away entirely I think?
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.
It's probably possible to unify them, although now they're a bit different since the tracing type doesn't distinguish between uncle depth. Although maybe we can change note_rewards
to take RewardKind
and handle the conversion itself (only performing it if tracing is enabled)?
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.
@@ -531,6 +586,8 @@ mod tests { | |||
eip649_reward: None, | |||
expip2_transition: u64::max_value(), | |||
expip2_duration_limit: 30, | |||
block_reward_contract: None, | |||
block_reward_contract_transition: 0, | |||
} | |||
} |
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 is a pretty big function. Perhaps it's time to split it up a little?
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.
Not sure how we can split it though. I would love some ideas. The issue is just that ethash
engine is full of configs/patches and all kinds of different hard forks.
@@ -16,8 +16,9 @@ | |||
|
|||
//! Authority params deserialization. | |||
|
|||
use ethereum_types::Address; | |||
use hash::Address; |
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 this rename?
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.
Previously it was not using the right type -- in json
, we should use the json serialization/serialization type ($crate::hash::Address
) rather than from ethereum_types
.
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.
Overall LGTM, some minor comments. We should also update the wiki on this.
let result = self.machine.execute_as_system( | ||
block, | ||
to, | ||
U256::max_value(), // unbounded gas? maybe make configurable. |
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 the original comment didn't make sense in this case (I copied it from some other usage of execute_code_as_system
😛). It probably makes sense to execute the block reward contract with unbounded gas. Otherwise, if we cap it and it goes out of gas what do we default to? No rewards for that block? The block reward contract is a critical part of consensus so I think the framework should assume it is correct, in this case we should assume that it will terminate, if it doesn't your chain is broken.
@@ -139,7 +163,7 @@ pub fn apply_block_rewards<M: Machine + WithBalances + WithRewards>( | |||
} | |||
|
|||
let rewards: Vec<_> = rewards.into_iter().map(|&(a, k, r)| (a, k.into(), r)).collect(); |
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.
It's probably possible to unify them, although now they're a bit different since the tracing type doesn't distinguish between uncle depth. Although maybe we can change note_rewards
to take RewardKind
and handle the conversion itself (only performing it if tracing is enabled)?
ethcore/src/machine.rs
Outdated
if let Err(e) = ex.call(params, &mut substate, BytesRef::Flexible(&mut output), &mut NoopTracer, &mut NoopVMTracer) { | ||
warn!("Encountered error on making system call: {}", e); | ||
} | ||
ex.call(params, &mut substate, BytesRef::Flexible(&mut output), &mut NoopTracer, &mut NoopVMTracer).map_err(|e| ::engines::EngineError::FailedSystemCall(format!("{}", e)))?; |
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 still keep the warning? Code that's executed as system is usually consensus critical so it's probably helpful to have failures logged (helps with debugging issues like borked contracts).
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.
After #9085, we can make this call error directly throw, and miner/validator would handle emitting the warnings. :)
@@ -133,6 +133,18 @@ pub enum Seal { | |||
/// A system-calling closure. Enacts calls on a block's state from the system address. | |||
pub type SystemCall<'a> = FnMut(Address, Vec<u8>) -> Result<Vec<u8>, String> + 'a; |
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.
Do you think it makes sense to remove this type? It seems like everywhere SystemCall
is supported SystemOrCodeCall
should also be? (even if it's not exposed by any parameter).
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 we are still using SystemCall
in several other cases, but I do agree that we may eventually want to clean up this.
ethcore/src/ethereum/ethash.rs
Outdated
rewards.push((author, RewardKind::Author, result_block_reward)); | ||
rewards.push((ubi_contract, RewardKind::External, ubi_reward)); | ||
rewards.push((dev_contract, RewardKind::External, dev_reward)); | ||
let mut call = |to, data| { |
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.
We can probably refactor this to share the code with AuRa's on_close_block
.
ethcore/src/engines/block_reward.rs
Outdated
External, | ||
|
||
/// Reward attributed to the block uncle(s) without any reference of block difference. This is used by all except Ethash engine's reward contract. | ||
Uncle, |
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 it's safe to remove this since the block reward contract was only supported in Aura and it doesn't produce uncles, so I don't think anyone is relying on this. Even if their contract code did handle the uncle type, it would never be reached.
After this is merged it would also be nice to be able to extract the musicoin block reward logic to a contract (which maybe can be used as an example for other people). |
@andresilva @sorpaas ACK on this. we will move our logic if there is an example for musicoin |
Hi @sorpaas, Please clarify the next thing: will it work fine if we use |
@varasev Yes it will work fine. In that case, you would want to keep |
@sorpaas Thank you for the clarification. What if the new contract code in |
@varasev Yes! As long as it evaluates to the same reward results for pre-fork blocks. |
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.
LGTM! Wiki https://wiki.parity.io/Block-Reward-Contract posting it here so we don't forget to update it before we release this feature.
* master: evmbin: Fix gas_used issue in state root mismatch and handle output better (#9418) Update hardcoded sync (#9421) Add block reward contract config to ethash and allow off-chain contracts (#9312) Private packets verification and queue refactoring (#8715) Update tobalaba.json (#9419) docs: add parity ethereum logo to readme (#9415) build: update rocksdb crate (#9414) Updating the CI system (#8765) Better support for eth_getLogs in light mode (#9186) Add update docs script to CI (#9219) `gasleft` extern implemented for WASM runtime (kip-6) (#9357) block view! removal in progress (#9397) Prevent sync restart if import queue full (#9381) nonroot CentOS Docker image (#9280) ethcore: kovan: delay activation of strict score validation (#9406)
This adds block reward contract config to ethash. A new config
blockRewardContractCode
is also added to both Aura and ethash. When specified, it will execute the code directly and overrides anyblockRewardContractAddress
config. Having thisblockRewardContractCode
config allows chains to deploy hard fork by simply replacing the current config value, without the need from us to support anymulti
block reward scheme.One interface issue I faced was
RewardKind::Uncle
. Most ethash uncles reward are calculated according to its depth, but we didn't have that information. So I addedRewardKind::UncleWithDepth(u8)
for this purpose. To keep backward compatibility, removingRewardKind::Uncle
might not be an option.UncleWithDepth
uses the reward kind index from100
to355
, where101
represents uncle with depth 1, and102
represents uncle with depth 2, etc. Technically, we only use101-106
right now, and all others are invalid. cc @andresilva. Not sure whether there're better ways to do this.cc @eosclassicteam (#9163) @yograterol (#9283). If you could rewrite your PR
on_close_block
using a reward contract, that would certainly speed up merging it! Examples of block reward contracts can be found here https://github.com/parity-contracts/block-reward/tree/master/contracts