Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

[PAN-2954] Support for NoReward and NoProof seal engines #1813

Merged
merged 6 commits into from
Aug 2, 2019

Conversation

shemnon
Copy link
Contributor

@shemnon shemnon commented Aug 1, 2019

PR description

Retesteth requires support for mining without block rewards and without PoW.
No PoW simply requires exposing the nonce generator and using a special
EthHashSolver.

No Reward in the tests is interpreted to mean Zero Reward, which presents
problems pre EIP158 with regard to zero balance accounts as the tests point the
coinbase to a non-existent account. We need to add a sentinel NO_REWARD reward
value (in addition to existing support for a zero value which is a short
circuit) that will proceed with the block reward logic at zero value.
UInt256.MAX_VALUE was chosen as that sentinel as it is a value that would never
make sense otherwise, causing instant integer overflow in any real use case.

Retesteth will use Wei.ZERO or Wei.NO_REWARD based on the configured fork when
mining in no-reward mode.

Retesteth requires support for mining without block rewards and without PoW.
No PoW simply requires exposing the nonce generator an dusing a special
EthHashSolver.

No Reward in the tests is interpreted to mean Zero Reward, which presents
problems pre EIP158 with regard to zero balance accounts as the tests point the
coinbase to a non-existent account.  We need to add a sentinel NO_REWARD reward
value (in addition to existing support for a zero value which is a short
circuit) that will proceed with the block reward logic at zero value.
UInt256.MAX_VALUE was chosen as that sentinel as it is a value that would never
make sense otherwise, causing instant integer overflow in any real usecase.

Retesteth will use Wei.ZERO or Wei.NO_REWARD based on the configured fork when
mining in no-reward mode.
@@ -158,6 +158,8 @@ private boolean rewardCoinbase(
if (blockReward.isZero()) {
return true;
}
// This reference equality check is deliberate.
final Wei blockReward = this.blockReward.equals(Wei.NO_REWARD) ? Wei.ZERO : this.blockReward;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You commented that this should be a reference equality check - did you mean to check that this.blockReward == Wei.NO_REWARD??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, stray comment. Will Fix.

@@ -23,6 +23,7 @@
public final class Wei extends BaseUInt256Value<Wei> {

public static final Wei ZERO = of(0);
public static final Wei NO_REWARD = of(UInt256.MAX_VALUE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like the wrong place for this constant - maybe BlockProcessor instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can move it there. It also needs to be visible to AbstractBlockCreator and MainnetBlockProcessor, but it looks like the needed dependencies are in place.

return true;
}
final Wei blockReward = blockRewardSpec.equals(Wei.NO_REWARD) ? Wei.ZERO : blockRewardSpec;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of having this special Wei.NO_REWARD value - what about just adding a flag like forceUpdateBeneficiaryAccount(boolean shouldForceUpdate) or something like that? I think that would make the intentions behind this logic clearer. Then you can return early on line 263 iff blockRewards.isZero() && !forceUpdate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We would need to add this flag to both the block creation and the block validation. That would involve passing a flag into the ProtocolScheduleBuilder, and the question would be "is EIP 158 active?"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just pused an alternate approach where we expose EIP158 status in the ProtocolSpec, seems to get to both locations with a minimum of grief.

@@ -158,6 +158,8 @@ private boolean rewardCoinbase(
if (blockReward.isZero()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be nice if we could dedupe this method :D, but probably out of scope for this change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, out of scope I'de say. Possibly could become static methods.

Copy link
Contributor

@mbaxter mbaxter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think its a little easier to follow with the EIP158 change 👍

*
* @return if EIP158 is in effect for this spec.
*/
public boolean isEIP158() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming quibbles - maybe this could be isEIP158Enabled. Not sure if it would be a good idea name it something more "meaningful" like prohibitEmptyAccounts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll go with IsEIP158Enabled when I fix the acceptance tests. My long term vision is that we have an isEIPEnabled(int eip) option and we track all the EIPs. That way we can speculatively include EIPs in the code base and use the EIP registry as feature flags. But since we care about only one at this point I'll put the number in the name,

Copy link
Contributor Author

@shemnon shemnon Aug 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out it's a clique protocol dependency, so labeling it as EIP158 treatment is inaccurate, so I went with skipZeroBlockRewards.

@shemnon
Copy link
Contributor Author

shemnon commented Aug 1, 2019

I ran the reference tests but not the acceptance tests... fix is underway.

shemnon added 2 commits August 1, 2019 19:16
…So the flag

now goes to skipZeroBlockRewards and gets set on all the protocol schedule
overrides.
return true;
}
// This reference equality check is deliberate.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stray comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed.

@@ -136,4 +143,62 @@ public void createMainnetBlock1_fixedDifficulty1() throws IOException {
// If we weren't setting difficulty to 2^256-1 a difficulty of 1 would have caused a
// IllegalArgumentException at the previous line, as 2^256 is 33 bytes.
}

@Test
public void createMainnetBlock1_noReward() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest a name that's more specific to what you're testing:

Suggested change
public void createMainnetBlock1_noReward() {
public void rewardBeneficiary_zeroReward_skipZeroRewardsFalse() {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

.buildProcessableBlockHeader();

blockCreator.rewardBeneficiary(
mutableWorldState, header, Collections.emptyList(), Wei.ZERO, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably worth creating another version of this test where skipZeroBlockRewards is true

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@shemnon shemnon merged commit 2597496 into PegaSysEng:master Aug 2, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants