Skip to content
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

[ETCM-284] Pay no money to coinbase address when processing checkpoint blocks #767

Merged
merged 1 commit into from
Nov 3, 2020

Conversation

pslaski
Copy link
Contributor

@pslaski pslaski commented Oct 29, 2020

Description

All checkpoint blocks will currently be marked as invalid, as:

the block state root is set as the same as the parent
the resulting state root includes money provided to the coinbase address

Proposed Solution

The solution is a small optimization - block with checkpoint is skipping execution of transactions and paying the reward

Important Changes Introduced

  • block with checkpoint is not executing transactions, rewards and after execution validation
  • [bonus] added information about treasury and checkpoint to the json BlockResponse (I found it useful for testing)

Testing

unit tests + local tests with mocked miner and QA endpoints

@pslaski pslaski requested review from rtkaczyk and ntallar October 29, 2020 15:40
*
* @param block the block being processed
* @param worldStateProxy the initial state
* @return the state after paying the appropriate reward to who corresponds
*/
// scalastyle:off method.length
Copy link
Contributor

Choose a reason for hiding this comment

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

Will we ever grow the balls to remove this useless tool altogether?

val (blocks, error) = blockExecution.executeBlocks(List(blockWithCheckpoint), defaultBlockHeader.difficulty)

blocks.size shouldBe 1
blocks.head.block shouldBe blockWithCheckpoint
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we check that world state is unchanged? Can we do that here?

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 can't as all intermediate world states are created and hidden inside components.
But we know that state is unchanged because the previous failing state root validation is running and passing normally (it is not mocked, MockValidatorsAlwaysSucceed is the validator of header and body)

Copy link
Contributor

Choose a reason for hiding this comment

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

we can't as all intermediate world states are created and hidden inside components.

But blockchain is not mocked and accessible here. Could we use that?

But we know that state is unchanged because the previous failing state root validation is running and passing normally (it is not mocked, MockValidatorsAlwaysSucceed is the validator of header and body)

I'm not quite sure which part of the code you are referring to

response should haveResult(expectedBlockResponse)
}

it should "handle eth_getBlockByHash request (block with treasuryOut)" in new JsonRpcControllerFixture {
Copy link
Contributor

@rtkaczyk rtkaczyk Oct 29, 2020

Choose a reason for hiding this comment

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

I'd prefer to be consistent with our naming so treasuryOptOut (besides treasuryOut sounds weird). This relates to several val names and string occurrences.

)
worldAfterTreasuryReward
}
if (block.hasCheckpoint) worldStateProxy
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. I wonder if we should move this condition outside to the prepareBlock method, so as to avoid running persist on an unchanged world state?

  2. Since BlockExecutionSpec is possibly not the best place to test that the account is unchanged, can we add an appropriate test to BlockPreparatorSpec?

@pslaski pslaski force-pushed the etcm-284-no-coinbase-money-checkpoint-block branch from 28ed295 to 104775c Compare October 30, 2020 13:04
Copy link

@ntallar ntallar left a comment

Choose a reason for hiding this comment

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

Minor changes and LGTM!

@@ -56,6 +56,7 @@ class BlockPreparator(
* @param worldStateProxy the initial state
* @return the state after paying the appropriate reward to who corresponds
*/
// scalastyle:off method.length
Copy link

Choose a reason for hiding this comment

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

Should we remove this now this method remains unchanged?

@@ -113,6 +115,11 @@ class JsonRpcControllerFixture(implicit system: ActorSystem)
unixTimestamp = 0
)

val checkpoint = ObjectGenerators.fakeCheckpointGen(2, 5).sample.get
val blockWithCheckpoint = CheckpointingTestHelpers.createBlockWithCheckpoint(Fixtures.Blocks.Block3125369.header, checkpoint)
Copy link

Choose a reason for hiding this comment

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

I thought we had removed this as it's duplicated with CheckpointBlockGenerator

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's my bad that it wasn't removed in the end. But most of its usages have been replaced with CheckpointBlockGenerator so it should be easy to remove now

val blockExecution =
new BlockExecution(blockchain, blockchainConfig, newConsensus.blockPreparator, blockValidation)

val (blocks, error) = blockExecution.executeBlocks(List(blockWithCheckpoint), defaultBlockHeader.difficulty)
Copy link

Choose a reason for hiding this comment

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

Should we rename this method to executeAndValidateBlocks for consistency?

response should haveResult(expectedBlockResponse)
}

it should "handle eth_getBlockByHash request (block with treasuryOptOut)" in new JsonRpcControllerFixture {
Copy link

Choose a reason for hiding this comment

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

It's odd that the test from this file are integration tests, instead of the usual per service and jrc

Copy link
Contributor Author

@pslaski pslaski Nov 2, 2020

Choose a reason for hiding this comment

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

it's because we have only one huge JRC service and here we have ~EthJRC tests

@pslaski pslaski force-pushed the etcm-284-no-coinbase-money-checkpoint-block branch 3 times, most recently from 32768dc to da3b169 Compare November 2, 2020 16:32
checkpoint: Checkpoint
): Block = {
Block(createBlockHeaderWithCheckpoint(parentHeader, checkpoint), BlockBody(Nil, Nil))
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we also remove the one below?

@pslaski pslaski force-pushed the etcm-284-no-coinbase-money-checkpoint-block branch from da3b169 to 2a457a9 Compare November 3, 2020 11:13
Copy link

@ntallar ntallar left a comment

Choose a reason for hiding this comment

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

LGTM! Was able to generate checkpoint blocks without any problem

 .\\            //.
. \ \          / /.
.\  ,\     /` /,.-
 -.   \  /'/ /  .
 ` -   `-'  \  -
   '.       /.\`
      -    .-
      :`//.'
      .`.'
      .' BP 

@ntallar ntallar merged commit 3b2198e into develop Nov 3, 2020
@ntallar ntallar deleted the etcm-284-no-coinbase-money-checkpoint-block branch November 3, 2020 12:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants