Skip to content

Commit a66c59f

Browse files
author
Nicolás Tallar
authored
[ETCM-143] Redefine block header structure and encoding (#709)
1 parent d982b1f commit a66c59f

39 files changed

+432
-264
lines changed

src/ets/scala/io/iohk/ethereum/ets/blockchain/Scenario.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ case class BlockHeaderDef(
5555
) {
5656

5757
def toBlockHeader: BlockHeader =
58-
BlockHeader(parentHash, uncleHash, coinbase, stateRoot, transactionsTrie, receiptTrie, bloom, difficulty, number,
59-
gasLimit, gasUsed, timestamp, extraData, mixHash, nonce, None
58+
BlockHeader(parentHash, uncleHash, coinbase, stateRoot, transactionsTrie, receiptTrie, bloom,
59+
difficulty, number, gasLimit, gasUsed, timestamp, extraData, mixHash, nonce
6060
)
6161
}
6262

src/ets/scala/io/iohk/ethereum/ets/vm/ScenarioBuilder.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ object ScenarioBuilder {
5151
env.currentTimestamp,
5252
bEmpty,
5353
bEmpty,
54-
bEmpty,
55-
None
54+
bEmpty
5655
)
5756

5857
def prepareWorld(accounts: Map[Address, AccountState], blockNumber: BigInt, exec: Exec): MockWorldState = {

src/it/scala/io/iohk/ethereum/txExecTest/util/DumpChainActor.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import akka.actor.{Actor, ActorRef, _}
77
import akka.util.ByteString
88
import io.iohk.ethereum.crypto.kec256
99
import io.iohk.ethereum.domain.{BlockBody, BlockHeader, Receipt}
10-
import io.iohk.ethereum.domain.BlockHeader._
10+
import io.iohk.ethereum.domain.BlockHeaderImplicits._
1111
import io.iohk.ethereum.network.{Peer, PeerManagerActor}
1212
import io.iohk.ethereum.network.PeerActor.SendMessage
1313
import io.iohk.ethereum.network.PeerManagerActor.{GetPeers, Peers}

src/it/scala/io/iohk/ethereum/txExecTest/util/DumpChainApp.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import io.iohk.ethereum.db.dataSource.DataSourceBatchUpdate
2626
import org.bouncycastle.util.encoders.Hex
2727

2828
import scala.concurrent.duration._
29+
import io.iohk.ethereum.domain.BlockHeader.HeaderExtraFields.HefEmpty
2930

3031
object DumpChainApp extends App with NodeKeyBuilder with SecureRandomBuilder with AuthHandshakerBuilder {
3132
val conf = ConfigFactory.load("txExecTest/chainDump.conf")
@@ -103,7 +104,7 @@ object DumpChainApp extends App with NodeKeyBuilder with SecureRandomBuilder wit
103104
class BlockchainMock(genesisHash: ByteString) extends Blockchain {
104105

105106
class FakeHeader() extends BlockHeader(ByteString.empty, ByteString.empty, ByteString.empty, ByteString.empty,
106-
ByteString.empty, ByteString.empty, ByteString.empty, 0, 0, 0, 0, 0, ByteString.empty, ByteString.empty, ByteString.empty, None) {
107+
ByteString.empty, ByteString.empty, ByteString.empty, 0, 0, 0, 0, 0, ByteString.empty, ByteString.empty, ByteString.empty, HefEmpty) {
107108
override lazy val hash: ByteString = genesisHash
108109
}
109110

src/it/scala/io/iohk/ethereum/txExecTest/util/FixtureProvider.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import java.io.Closeable
55
import akka.util.ByteString
66
import io.iohk.ethereum.db.storage._
77
import io.iohk.ethereum.domain._
8-
import io.iohk.ethereum.domain.BlockHeader._
8+
import io.iohk.ethereum.domain.BlockHeaderImplicits._
99
import io.iohk.ethereum.domain.BlockBody._
1010
import io.iohk.ethereum.network.p2p.messages.PV63._
1111
import MptNodeEncoders._

src/main/scala/io/iohk/ethereum/blockchain/data/GenesisDataLoader.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,7 @@ class GenesisDataLoader(
134134
unixTimestamp = BigInt(genesisData.timestamp.replace("0x", ""), 16).toLong,
135135
extraData = genesisData.extraData,
136136
mixHash = genesisData.mixHash.getOrElse(zeros(hashLength)),
137-
nonce = genesisData.nonce,
138-
treasuryOptOut = None
137+
nonce = genesisData.nonce
139138
)
140139

141140
private def zeros(length: Int) =

src/main/scala/io/iohk/ethereum/consensus/blocks/BlockGeneratorSkeleton.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import io.iohk.ethereum.crypto.kec256
1111
import io.iohk.ethereum.db.dataSource.EphemDataSource
1212
import io.iohk.ethereum.db.storage.StateStorage
1313
import io.iohk.ethereum.domain._
14+
import io.iohk.ethereum.domain.BlockHeader.HeaderExtraFields._
1415
import io.iohk.ethereum.consensus.ethash.blocks.OmmersSeqEnc
1516
import io.iohk.ethereum.ledger.Ledger.{BlockPreparationResult, BlockResult}
1617
import io.iohk.ethereum.ledger.{BlockPreparator, BloomFilter}
@@ -51,7 +52,11 @@ abstract class BlockGeneratorSkeleton(
5152
blockTimestamp: Long,
5253
x: Ommers
5354
): BlockHeader = {
54-
val optOut = if(blockNumber >= blockchainConfig.ecip1098BlockNumber) Some(consensusConfig.treasuryOptOut) else None
55+
val extraFields =
56+
if(blockNumber >= blockchainConfig.ecip1098BlockNumber)
57+
HefPostEcip1098(consensusConfig.treasuryOptOut)
58+
else
59+
HefEmpty
5560

5661
BlockHeader(
5762
parentHash = parent.header.hash,
@@ -70,7 +75,7 @@ abstract class BlockGeneratorSkeleton(
7075
extraData = blockchainConfig.daoForkConfig.flatMap(daoForkConfig => daoForkConfig.getExtraData(blockNumber)).getOrElse(headerExtraData),
7176
mixHash = ByteString.empty,
7277
nonce = ByteString.empty,
73-
treasuryOptOut = optOut
78+
extraFields = extraFields
7479
)
7580
}
7681

src/main/scala/io/iohk/ethereum/consensus/ethash/blocks/package.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package io.iohk.ethereum.consensus.ethash
22

33
import io.iohk.ethereum.consensus.ethash.validators.OmmersValidator.OmmersError
44
import io.iohk.ethereum.domain.BlockHeader
5+
import io.iohk.ethereum.domain.BlockHeaderImplicits._
56
import io.iohk.ethereum.ledger.BlockPreparationError
67
import io.iohk.ethereum.rlp.{RLPEncodeable, RLPList, RLPSerializable}
78

src/main/scala/io/iohk/ethereum/consensus/validators/BlockHeaderValidator.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package validators
33

44
import io.iohk.ethereum.crypto.ECDSASignature
55
import io.iohk.ethereum.domain.BlockHeader
6+
import io.iohk.ethereum.domain.BlockHeader.HeaderExtraFields
67

78
/**
89
* Validates a [[io.iohk.ethereum.domain.BlockHeader BlockHeader]].
@@ -33,13 +34,13 @@ object BlockHeaderError {
3334
case object HeaderGasLimitError extends BlockHeaderError
3435
case object HeaderNumberError extends BlockHeaderError
3536
case object HeaderPoWError extends BlockHeaderError
36-
case class HeaderOptOutError(ecip1098Activated: Boolean, optOutDefined: Boolean) extends BlockHeaderError
37+
case class HeaderExtraFieldsError(extraFields: HeaderExtraFields, ecip1097Activated: Boolean, ecip1098Activated: Boolean) extends BlockHeaderError
3738
case class HeaderWrongNumberOfCheckpointSignatures(sigCount: Int) extends BlockHeaderError
3839
case class HeaderInvalidCheckpointSignatures(invalidSignaturesWithPublics: Seq[(ECDSASignature, Option[String])])
3940
extends BlockHeaderError
40-
case object HeaderCheckpointTooEarly extends BlockHeaderError
4141
case class HeaderFieldNotEmptyError(msg: String) extends BlockHeaderError
4242
case class HeaderNotMatchParentError(msg: String) extends BlockHeaderError
43+
case object CheckpointHeaderTreasuryOptOutError extends BlockHeaderError
4344

4445
case class HeaderUnexpectedError(msg: String) extends BlockHeaderError
4546
}

src/main/scala/io/iohk/ethereum/consensus/validators/BlockHeaderValidatorSkeleton.scala

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import io.iohk.ethereum.consensus.GetBlockHeaderByHash
44
import io.iohk.ethereum.consensus.difficulty.DifficultyCalculator
55
import io.iohk.ethereum.consensus.validators.BlockHeaderError._
66
import io.iohk.ethereum.domain.BlockHeader
7+
import io.iohk.ethereum.domain.BlockHeader.HeaderExtraFields.{HefEmpty, HefPostEcip1097, HefPostEcip1098}
78
import io.iohk.ethereum.utils.{BlockchainConfig, DaoForkConfig}
89

910
/**
@@ -77,7 +78,7 @@ abstract class BlockHeaderValidatorSkeleton(blockchainConfig: BlockchainConfig)
7778
_ <- validateGasUsed(blockHeader)
7879
_ <- validateGasLimit(blockHeader, parentHeader)
7980
_ <- validateNumber(blockHeader, parentHeader)
80-
_ <- validateOptOut(blockHeader)
81+
_ <- validateExtraFields(blockHeader)
8182
_ <- validateEvenMore(blockHeader, parentHeader)
8283
} yield BlockHeaderValid
8384
}
@@ -95,6 +96,7 @@ abstract class BlockHeaderValidatorSkeleton(blockchainConfig: BlockchainConfig)
9596
for {
9697
_ <- blockWithCheckpointHeaderValidator.validate(blockHeader, parentHeader)
9798
_ <- validateNumber(blockHeader, parentHeader)
99+
_ <- validateExtraFields(blockHeader)
98100
} yield BlockHeaderValid
99101
}
100102

@@ -197,18 +199,23 @@ abstract class BlockHeaderValidatorSkeleton(blockchainConfig: BlockchainConfig)
197199
else Left(HeaderNumberError)
198200

199201
/**
200-
* Validates [[io.iohk.ethereum.domain.BlockHeader.treasuryOptOut]] is only defined if ECIP1098 is enabled at the block's number
202+
* Validates [[io.iohk.ethereum.domain.BlockHeader.extraFields]] match the ECIP1097 and ECIP1098 enabling configuration
201203
*
202204
* @param blockHeader BlockHeader to validate.
203-
* @return BlockHeader if valid, an [[HeaderOptOutError]] otherwise
205+
* @return BlockHeader if valid, an [[HeaderExtraFieldsError]] otherwise
204206
*/
205-
private def validateOptOut(blockHeader: BlockHeader): Either[BlockHeaderError, BlockHeaderValid] = {
206-
val isEcip1098Activated = blockHeader.number >= blockchainConfig.ecip1098BlockNumber
207-
val isOptOutDefined = blockHeader.treasuryOptOut.isDefined
208-
209-
if (isEcip1098Activated && isOptOutDefined) Right(BlockHeaderValid)
210-
else if (!isEcip1098Activated && !isOptOutDefined) Right(BlockHeaderValid)
211-
else Left(HeaderOptOutError(isEcip1098Activated, isOptOutDefined))
207+
private def validateExtraFields(blockHeader: BlockHeader): Either[BlockHeaderError, BlockHeaderValid] = {
208+
val isECIP1098Activated = blockHeader.number >= blockchainConfig.ecip1098BlockNumber
209+
val isECIP1097Activated = blockHeader.number >= blockchainConfig.ecip1097BlockNumber
210+
211+
blockHeader.extraFields match {
212+
case HefPostEcip1097(_, _) if isECIP1097Activated && isECIP1098Activated => Right(BlockHeaderValid)
213+
case HefPostEcip1098(_) if !isECIP1097Activated && isECIP1098Activated => Right(BlockHeaderValid)
214+
case HefEmpty if !isECIP1097Activated && !isECIP1098Activated => Right(BlockHeaderValid)
215+
case _ =>
216+
val error = HeaderExtraFieldsError(blockHeader.extraFields, isECIP1097Activated, isECIP1098Activated)
217+
Left(error)
218+
}
212219
}
213220

214221
}

0 commit comments

Comments
 (0)