Skip to content

[ETCM-72] Checkpoint Block validation #706

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

Merged
merged 1 commit into from
Oct 1, 2020

Conversation

pslaski
Copy link
Contributor

@pslaski pslaski commented Sep 28, 2020

Description

Added block with checkpoint validation

Important Changes Introduced

  • checkpoint block header validation
  • checkpoint block validation

Testing

only unit tests (as we don't have checkpoint block generator now)

@pslaski pslaski requested review from rtkaczyk and ntallar September 28, 2020 17:12
_ <- blockWithCheckpointHeaderValidator.validate(blockHeader, parentHeader)
_ <- validateExtraData(blockHeader)
_ <- validateDifficulty(blockHeader, parentHeader)
_ <- validateGasLimit(blockHeader, parentHeader)
Copy link

Choose a reason for hiding this comment

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

This differs from the original spec:

  1. Extra data is determined to only be of size less than 32, can't anyone then change this value and still generate a valid checkpoint block? This easiness of generating valid blocks could be exploited, should we minimize that as much as possible and have this be deterministic?
  2. Gas limit is determined to be in a range, doesn't that allow the same attack as in 1.?
  3. Shouldn't it be better if checkpoint blocks had instead no impact on the block difficulty? The one second gap between this block and it's parent will increase the difficulty of this block if not

Expanding from 3. even if we do that there's likely a difference in timestamp between this block and the next (as checkpoint generation will take longer than 1 second), and that would also affect the chains difficutly. Ideally, given an average checkpoint generation time of X, shouldn't we set the timestamp of the checkpoint block to be parentHeader.unixTimestamp + X?

Copy link
Contributor

@rtkaczyk rtkaczyk Sep 29, 2020

Choose a reason for hiding this comment

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

Regarding X, that's idealistic far beyond being realistic. A more realistic approach could be: given chain B0 -> C -> B1 take (timestamp(B1) - timestamp(B0)) / 2 as the interval in the difficulty calculation.

Edit: nah, doesn't make sense, the interval between B1 and B0 will not be twice the average. I think the easiest and a sane thing to do would be to assume that the checkpoint does not affect the difficulty of the succeeding block so: difficulty(B1) == difficulty(B0).

We could later adjust it based on empirical data.

Separate task, right?

Copy link

@ntallar ntallar Sep 29, 2020

Choose a reason for hiding this comment

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

difficulty(B1) == difficulty(B0).

Doesn't this remove the adjusting possibility of ETC's block difficulty? The block B1 will take the same to mine independently on how much after C it was mined. If checkpoints will be as often as we've done so far (a checkpoint per 5 blocks) that might affect it

Separate task, right?

Yes, (here it is), but definitely with some discussions before on which exact rule we propose to have here

@@ -48,6 +56,25 @@ object ECDSASignature {
ECDSASignature(r, s, pointSign)
}

def sign2(message: Array[Byte], keyPair: AsymmetricCipherKeyPair, chainId: Option[Byte] = None): ECDSASignature = {
Copy link
Contributor

Choose a reason for hiding this comment

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

What's this? I'm not seeing it used anywhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sorry I used it to generate signature with random k, will remove it

* section 4.4.2 of http://paper.gavwood.com/):
* - BlockValidator.validateTransactionRoot
* - BlockValidator.validateOmmersHash
* This method allows validate that a BlockHeader matches a BlockBody.
*
* @param blockHeader to validate
* @param blockBody to validate
* @return The block if the header matched the body, error otherwise
*/
def validateHeaderAndBody(blockHeader: BlockHeader, blockBody: BlockBody): Either[BlockError, BlockValid] = {
Copy link
Contributor

Choose a reason for hiding this comment

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

I hate the method names in this class. This one says that it validates the header but it does not. There are several others like that. Maybe we should create a task to address it?

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 agree, I had some problems to understand what's going on there and what's a purpose because of naming. I will create a task.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@pslaski pslaski force-pushed the etcm-72-checkpoint-block-validator branch 2 times, most recently from 8603a1d to 5b500bf Compare September 29, 2020 14:03
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.

Only minor comments, will continue reviewing it tomorrow

@@ -136,6 +144,15 @@ case class ECDSASignature(r: BigInt, s: BigInt, v: Byte) {
*/
def publicKey(message: ByteString): Option[ByteString] =
ECDSASignature.recoverPubBytes(r, s, v, None, message.toArray[Byte]).map(ByteString(_))

def toBytes: ByteString = {
Copy link

Choose a reason for hiding this comment

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

Minor: as this is for testing purposes, shouldn't we re-use the rlp encoders instead of multiple serializers?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not quite sure what you mean, this is different than RLP encoding. I need/desire/can't live without this method here, even if it's not used a single time in the codebase.

Copy link

Choose a reason for hiding this comment

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

this is different than RLP encoding

This is why I'm asking, given that RLP is our default serializing way, it's easy to assume that any methods toBytes and fromBytes on our objects use RLP for serialization. If we want to keep them, shouldn't we rename them (maybe as toRawBytes and fromRawBytes?) or move them to a separate codec object?

Copy link
Contributor

@rtkaczyk rtkaczyk Oct 1, 2020

Choose a reason for hiding this comment

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

move them to a separate codec object?

No! I need this here and you will too :)
As for renaming, I'm not sure, can't recall what this signature format is called (I don't think it's DER).

@ntallar ntallar added the BREAKS PROTOCOL Affects Node2Node interactions in a way that makes them not interoperate label Sep 29, 2020
@pslaski pslaski force-pushed the etcm-72-checkpoint-block-validator branch 2 times, most recently from d0d0194 to 9bcb971 Compare September 30, 2020 12:30
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.

Only minor comments, apart from which LGTM!

@pslaski pslaski force-pushed the etcm-72-checkpoint-block-validator branch from 9bcb971 to eb1ee83 Compare September 30, 2020 13:55
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.

Only minor pending discussion is the toBytes and fromBytes from ECDSASignature, apart from which LGTM!

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

@pslaski pslaski force-pushed the etcm-72-checkpoint-block-validator branch from eb1ee83 to ba02fcc Compare October 1, 2020 12:26
@pslaski pslaski force-pushed the etcm-72-checkpoint-block-validator branch from ba02fcc to f6079a4 Compare October 1, 2020 12:57
@pslaski pslaski merged commit 8b0b08f into develop Oct 1, 2020
@pslaski pslaski deleted the etcm-72-checkpoint-block-validator branch October 1, 2020 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BREAKS PROTOCOL Affects Node2Node interactions in a way that makes them not interoperate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants